1.Threejs WebGL相关模型加载性能对比及模型压缩优化详解干货链接

2.webgl的模型格式选择:

列举3个最常用的模型格式

1. fbx
FBX最大的用途是用在诸如在 Max、Maya、Softimage 等软件间进行模型、材质、动作和摄影机信息的互导,这样就可以发挥 Max 和 Maya 等软件的优势。可以说,FBX 方案是非常好的互导方案。
. fbx 格式,Autodesk 家族格式 - 支持动画!这是一个商业的格式,兼容最好的当属 Autodesk 家族的软件了。fbx 也开放给了第三方软件,但总是感觉除了他自己的软件之外或多或少的都有解决不完的问题。 毋庸置疑,FBX 现在是最受欢迎的格式。
2. glTF
glTF 称为“ 3D 界的 JPEG”,使用了更优的数据结构,为应用程序实时渲染而生。glTF 有以下几大特点:
- 由现有 OpenGL 的维护组织 Khronos 推出,目的就是为了统一用于应用程序渲染的 3D 格式,更适用于基于 OpenGL 的引擎;
- 减少了 3D 格式中除了与渲染无关的冗余信息,最小化 3D 文件资源;
- 优化了应用程序读取效率和和减少渲染模型的运行时间;
- 支持 3D 模型几何体、材质、动画及场景、摄影机等信息。
glF 导出格式有两种后缀格式可供选择:.gltf 和 .glb:
- .gltf 文件导出时一般会输出两种文件类型,一是 .bin 文件,以二进制流的方式存储顶点坐标、顶点法线坐标和贴图纹理坐标、贴图信息等模型基本数据信息;二是 .gltf 文件,本质是 json 文件,记录对bin文件中模型顶点基本数据的索引、材质索引等信息,方便编辑,可读性较好;
- .glb 文件格式只导出一个 .glb 文件,将所有数据都输出为二进制流,通常来说会更小一点,若不关心模型内的具体数据可直接选择此类型。
3. obj
OBJ文件很适合用于3D软件模型之间的互导。目前几乎所有知名的3D软件都支持OBJ文件的读写。OBJ文件是一种文本文件,可以直接用写字板打开进行查看和编辑修改。. obj 格式, 静态多边形模型 - 附带 UV 信息及材质路径!不包含动画、材质特性、贴图路径、动力学、粒子等信息。

最适用于webgl的模型格式: glTF/glb

3.在Threejs中对模型加载的运用

3.1 对于gltf模型的压缩:
3.2 npm 工具安装:

#fbx转gltf
fbx2gltf : npm i fbx2gltf

#obj转gltf
obj2gltf : npm i obj2gltf

#gltf Draco压缩
gltf-pipeline : npm i gltf-pipeline

#gltf MeshQuan、MeshOpt压缩
gltfpack : npm i gltfpack

gltfpack 命令行参数:

gltfpack 属性:
-c:生成压缩的gltf/glb文件(-cc以获得更高的压缩比)
材质:
-tc :使用BasisU超压缩将所有纹理转换为KTX2(使用BasisU / toktx可执行文件)
-tu:当编码纹理时使用UASTC(更高的质量和更大的尺寸)
-tq N:设置纹理编码质量(默认值:8;N应该在1到10之间
-ts R:根据比例R缩放纹理尺寸(默认为1;R应该在0和1之间)
-tp:调整纹理大小到最接近2的幂,以符合WebGL1的限制
简化:
-si R:简化网格以达到比例R(默认为1;R应该在0和1之间)
-sa:不计质量,积极简化目标比率
顶点:
-vp N:使用N位量化的位置(默认:14;N应该在1到16之间)
-vt N:使用N位量化纹理坐标(默认:12;N应该在1到16之间)
-vn N:使用N位量化法线和切线(默认:8;N应该在1到16之间)
-vc N:使用N位量化颜色(默认:8;N应该在1到16之间)
动画:
-at N:使用N位量化转换(默认值:16;N应该在1到24之间)
-ar N:使用N位量化旋转(默认:12;N应该在4到16之间)
-as N:使用N位量化的规模(默认值:16;N应该在1到24之间)@iñ tEâ1
iX
-af N:以N Hz重采样动画(默认值:30)#压缩glb
-cc 表示Opt压缩 ,
-tc 表示贴图压缩KTX格式*

3.3 npm 模型压缩命令行使用

1.fbx转gltf/gab
命令行:
fbx2gltf -i model.FBX -o model.gltf

2.obj转gltf/glb
命令行:
-s 代表纹理图片从模型中分离
obj2gltf -i model.obj -o i model.glb
obj2gltf -i model.obj -o i model.glb -s

3.gltf 压缩 Draco压缩
命令行:
#压缩glb文件 -b 表示输出glb格式 -f 表示输出gltf格式 -d表示Draco压缩, -s 表示压缩glb文件并将纹理图片分离出来 + .bin 文件
gltf-pipeline -i model.glb -b -d
gltf-pipeline -i model.glb -o model2.glb -d
gltf-pipeline -i model.glb -o model-processed.glb -s

4.gltf 压缩 MeshQuan
命令行:
gltfpack -i model.glb -o model_pack.glb

5.gltf 压缩 MeshOpt
命令行:
#压缩模型
gltfpack -i model.glb -o model_pack.glb -cc
#压缩模型+压缩贴图
gltfpack -i model.glb -o model_pack.glb -cc -tc
#压缩模型+压缩贴图+对vp进行限制,防止压缩太过使贴图与模型重面导致闪面(重要) (以下vp vt 参数根据开关室模型调整)
gltfpack -i model.glb -o model-vpvtcctc.glb -vp 16 -vt 12 -cc -tc

4.Threejs不同压缩格式简易加载代码示例:

导入Three相关加载器:
import * as THREE from 'three'
import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader";
import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader";
import { MTLLoader } from "three/examples/jsm/loaders/MTLLoader";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
import { KTX2Loader } from 'three/examples/jsm/loaders/KTX2Loader.js';
import { MeshoptDecoder } from 'three/examples/jsm/libs/meshopt_decoder.module.js';

1.obj

 	/**
    * OBJ和材质文件mtl加载
    */
    loadObj = (materialPath, objPath) => {
        var a = new Date().getTime() / 1000
        let objloader = new OBJLoader(); //obj加载器
        var mtlLoader = new MTLLoader(); //材质文件加载器
        mtlLoader.load(materialPath, function (materials) {
            // 返回一个包含材质的对象MaterialCreator
            //obj的模型会和MaterialCreator包含的材质对应起来
            objloader.setMaterials(materials);
            objloader.load(objPath, function (obj) {
                scene.add(obj); //返回的组对象插入场景中
            })
        })
    }

2.fbx

loadFBX = ( path ) => {
        // 加载fbx 摄像机model
        var loader = new FBXLoader();
        loader.load(path, function (obj) {
            obj.traverse(function (child) {
                if (child.isMesh) {
                    //child.castShadow = true;
                    //child.receiveShadow = true;
                }
            });
            scene.add(obj);
        });
    }

3.普通不压缩 gltf/glb

loadGltf = (path) => {
        var gltfloader = new GLTFLoader()
        gltfloader.load(path, function (gltf) {
            var object = gltf.scene
            scene.add(object);
        });
    }

4.gltf/glb Draco压缩

loadGlb_Draco(path) {
        var loader = new GLTFLoader();
        var dracoLoader = new DRACOLoader();
        dracoLoader.setDecoderPath('node_modules/three/examples/js/libs/draco/');
        dracoLoader.preload();
        loader.setDRACOLoader(dracoLoader);
        loader.load(
            path,
            function (gltf) {
                gltf.scene.traverse(function (child) {
                    if (child.isMesh) {
                        // child.material .wireframe =true;  
                        // child.material.shininess = 60; 
                    }
                });
                scene.add(gltf.scene);
            }
        );
    }

5.gltf/glb MeshoptDecoder压缩

	/**
     * 加载 opt压缩格式的glb模型
     * @param {*} _this 
     * @param {*} path 
     * @param {*} cb 
     */
    loadGlbMeshopt = ( path ) => {
        var loader = new GLTFLoader();
        loader.setMeshoptDecoder(MeshoptDecoder);
        loader.load(path, function (gltf) { scene.add(gltf.scene); });
    }

6.gltf/glb MeshoptDecoder压缩+贴图 KTX压缩

/**
     * gltfKTX压缩模型加载
     * @param {*} _this 
     * @param {*} path 
     * @param {*} cb 
     */
    loadGlbpackKTX = ( path ) => {
        const ktx2Loader = new KTX2Loader()
            // .setTranscoderPath('js/libs/basis/')
            .setTranscoderPath('node_modules/three/examples/js/libs/basis/')
            .detectSupport(_this.renderer);
        // const loader = new GLTFLoader().setPath('./public/three/models/gltf/cc_tc/');
        const loader = new GLTFLoader();
        loader.setKTX2Loader(ktx2Loader);
        loader.setMeshoptDecoder(MeshoptDecoder);
        loader.load(path, function (gltf) {
            // coffeemat.glb was produced from the source scene using gltfpack:
            // gltfpack -i coffeemat/scene.gltf -o coffeemat.glb -cc -tc
            // The resulting model uses EXT_meshopt_compression (for geometry) and KHR_texture_basisu (for texture compression using ETC1S/BasisLZ)
            scene.add(gltf.scene);
        });
    }
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐