threejs优化之3D模型压缩

threejs优化之3D模型压缩

​ 项目采用vue+threejs开发,在开发过程中需要从外部加载3D模型。一般当模型大小比较大的时候,加载过程会很长,浏览器处于阻塞状态,同时渲染时间也会变长,严重影响用户体验,阻塞严重的情况下还会使浏览器卡死,因此对3D模型大小进行压缩是必然趋势。

​ 通过模型网格压缩,通过glTF配合Draco压缩的方式,可以在视觉效果近乎一致的情况下,让3D模型文件成倍缩小。

全局安装gltf-pipeline

#全局安装
npm install -g gltf-pipeline
#压缩glb文件 -b表示输出glb格式,-d表示压缩
gltf-pipeline -i model.glb -b -d
#压缩glb文件并将纹理图片分离出来
gltf-pipeline -i model.glb -b -d -t
#更多参数查阅
gltf-pipeline -h

压缩3D模型文件

采用DRACO压缩并加载gltf模型的用法,以VUE开发为例

gltf-pipeline -i .\public\model\model.gltf -o .\public\model\model.mini.gltf  -d --draco.compressionLevel 9 --draco.quantizePositionBits 14

其中-i是输入文件;–draco.compressionLevel是压缩等级,等级范围是(0—10),压缩等级越大压缩效果越好,压缩时间越长;–draco.quantizePositionBits是顶点坐标量化位数,默认为14位。

注意:当–draco.quantizePositionBits等于0时表示不进行量化,进行无损压缩。-point_cloud情况下除了浮点型数据无损压缩用SequentialAttributeEncodersController方法进行压缩,其余情况用KdTreeAttributesEncoder方法进行压缩。

DRACO压缩算法

通过 Draco 进行压缩基本上是有损的,有两点表现:

  • Draco 通过 Edge breaker 3D 压缩算法改变了模型的网格数据的索引方法,缺少了原来的网格顺序;
  • Draco 通过减少顶点坐标、顶点纹理坐标等信息的位数,以减少数据的存储量。
--input, -i                   Path to the glTF or glb file.[string] [required]
--output, -o                  Output path of the glTF or glb file. Separate   
                               resources will be saved to the same directory.  
                                                                       [string]
--binary, -b                  Convert the input glTF to glb.                                      //将输入的glTF转换为glb
                                                     [boolean] [default: false]
--json, -j                    Convert the input glb to glTF.                                      //将输入的glb转换为glTF
                                                     [boolean] [default: false]
--separate, -s                Write separate buffers, shaders, and textures                       //编写单独的缓冲区、着色器和纹理而不是把它们嵌入到glTF中
                               instead of embedding them in the glTF.          
                                                     [boolean] [default: false]
--separateTextures, -t        Write out separate textures only.                                   //只写出单独的纹理
                                                     [boolean] [default: false]
--stats                       Print statistics to console for output glTF                         //将统计信息打印到控制台以输出glTF文件
                               file.                 [boolean] [default: false]     
--keepUnusedElements          Keep unused materials, nodes and meshes.                            //保留未使用的材质、节点和网格
                                                      [boolean] [default: false]
--draco.compressMeshes, -d    Compress the meshes using Draco. Adds the                            //使用Draco压缩网格。添加KHR_draco_mesh_压缩扩展
                                KHR_draco_mesh_compression extension.
                                                      [boolean] [default: false]
--draco.compressionLevel      Draco compression level [0-10], most is 10,                           //Draco压缩级别[0-10],大多数是10,最小值为0。值为0将会连续应用 编码并保留face顺序。
                                least is 0. A value of 0 will apply sequential
                                encoding and preserve face order.
                                                           [number] [default: 7]   
--draco.quantizePositionBits  Quantization bits for position attribute when                        //位置坐标属性的量化位使用Draco压缩。
                                using Draco compression.  [number] [default: 11]

--draco.quantizeNormalBits    Quantization bits for normal attribute when                           //法线属性的量化位使用Draco压缩
                                using Draco compression.   [number] [default: 8]

--draco.quantizeTexcoordBits  Quantization bits for texture coordinate                               //纹理坐标的量化位属性。
                                attribute when using Draco compression.
                                                          [number] [default: 10]

--draco.quantizeColorBits     Quantization bits for color attribute when using                        //使用时颜色属性的量化位德拉科压缩
                                Draco compression.         [number] [default: 8]

--draco.quantizeGenericBits   Quantization bits for skinning attribute (joint                        //蒙皮属性(关节的量化位索引和关节权重)ad自定义属性使用Draco压缩时。
                                indices and joint weights) ad custom attributes
                                when using Draco compression. [number] [default: 8]

--draco.uncompressedFallback  Adds uncompressed fallback versions of the                            //添加未压缩的回退版本压缩网格
                                compressed meshes.    [boolean] [default: false]

  --draco.unifiedQuantization   Quantize positions of all primitives using the            //统一定义的量化网格所有基本体的边界框。 如果这个选项未设置,对每个应用量化原始的可能会导致差距出现在不同图元之间。
                                same quantization grid defined by the unified
                                bounding box of all primitives. If this option
                                is not set, quantization is applied on each
                                primitive separately which can result in gaps
                                appearing between different primitives.
                                                      [boolean] [default: false]

解释如下:

threejs优化之3D模型压缩_第1张图片

项目代码实现

将3D模型文件压缩好之后就可以在项目中引用了。跟常规的gltf文件引用不同的是需要先使用dracoLoader进行解压,代码实现如下:

先从node_module/three/examples/js/libs/draco目录下,将gltf文件夹拷贝到public文件目录下。

// 引入依赖
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import {CSS3DRenderer, CSS3DObject} from "three/examples/jsm/renderers/CSS3DRenderer.js";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader"
// 压缩处理
handleCompress() {
	let gltfLoader = new GLTFLoader();
    let dracoLoader = new DRACOLoader();
    dracoLoader.setDecoderPath("/gltf/"); // 设置public下的解码路径,注意最后面的/
    dracoLoader.setDecoderConfig({ type: "js" });
    dracoLoader.preload();
    gltfLoader.setDRACOLoader(dracoLoader);

	gltfLoader.load("models/model.glb", gltf => {
    	console.log(gltf);
        gltf.scene.position.set(0, 0, 0);
        this.scene.add(gltf.scene);
    });
}

​ 采用draco压缩,原gltf格式3D模型文件大小约为140M,压缩之后的文件大小为10M,效果还是很可观的。使用新的模型加载到项目中时,加载和渲染速度有明显提升,模型页面效果基本上没有太大差异。总体来说,draco压缩3D文件之后,对加载和渲染的性能提升是巨大的,有get到了新技能。觉得有用的话请给个赞吧!

你可能感兴趣的:(3d,three.js,vue.js)