three.js 加载gltf格式文件入坑总结(Blender导出gltf、gltf-pipeline压缩转Draco.gltf)

总结three.js加载gltf格式文件开发过程中遇到的坑

项目介绍

此项目主要是做一个三维运维机房,笔者刚接触three一个月,属于初学者。项目起始,加载模型用的FBX格式,直接引用的3D格式文件,后期发现在性能较差的笔记本上加载模型时,耗时太长(50M大小 3~5min),体验极差。后面通过查阅资料,发现three官方是推荐gltf/glb格式文件的,后面就开始研究如何载入gltf格式文件。开发过程中遇到很多问题,最后经过不懈努力终于得到解决。此次three开发经历值得记录一下。本文适合初学者阅读,对于你比较熟悉three的同学可做交流,欢迎提出宝贵意见。
下面对开发过程入的坑做一总结:

  1. 如何使用blender导出gltf格式文件;
  2. GLTFLoader如何载入gltf格式文件;
  3. gltf格式文件如何压缩;

如何使用blender导出gltf格式文件

如何使用blender导出GLTF—参考:https://blog.csdn.net/ithanmang/article/details/82147686
提示最新版blender(version2.9.0)已经内置gltf格式导出,无需手动下载安装插件包了。

VUE项目中 GLTFLoader如何载入gltf格式文件

import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
 
const loader = new GLTFLoader(), path =  'three/model/jifang.gltf' ;
loader.load(
    path ,
    ( gltf ) => {
        // called when the resource is loaded
        scene.add( gltf.scene );
    },
    ( xhr ) => {
        // called while loading is progressing
        console.log( `${( xhr.loaded / xhr.total * 100 )}% loaded` );
    },
    ( error ) => {
        // called when loading has errors
        console.error( 'An error happened', error );
    },
);

注意:gltf文件——必须、必须、必须放在根目录public文件夹下(vue-li2构建项目对应static静态资源文件夹下面),路径为: ‘public/three/model/jifang.gltf’。gltf文件放入其他目录下 比如‘src/assets’,会导致模型load失败,至于原因后面学到会及时更新。

gltf格式文件如何压缩

项目进行到上面阶段时,模型已经能够载进dom了。但是一般的三维模型文件体积较大,动辄几十上百M,模型载入时间过长(几十秒甚至几分钟),严重影响体验。这时候就需要压缩模型文件了,一般方法有两种:减少模型细节 物理压缩体积(减少了纹理细节 不推荐)、通过gltf-pipeline插件压缩gltf文件(推荐)。

如何gltf-pipeline压缩GLTF—参考:https://blog.csdn.net/rexfow/article/details/107378041

注意:需要先cmd控制台全局安装gltf-pipeline:npm install -g gltf-pipeline,再cd进入gltf文件目录下执行:gltf-pipeline -i jifang.gltf -o jifangDraco.gltf -d,指定导出名为 XXDraco.gltf的文件。指令结束后 就可以在‘public/three/model/’目录下(根据自己的项目路径)看到XXDraco.gltf文件了。

此刻,你以为XXDraco.gltf文件就可以直接通过GLTFLoader方法载入使用了?错!

的确,想当然的以为既然压缩后同样是gltf格式文件,直接GLTFLoader载入为啥还会报错呢。通过参考官方demo找到了答案。
学习官方demo_loader_gltf_extensions—参考:http://www.yanhuangxueyuan.com/threejs/examples/?q=loader#webgl_loader_gltf_extensions

import * as THREE from 'three'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { DRACOLoader  } from 'three/examples/jsm/loaders/DRACOLoader'

const loader = new GLTFLoader(), path =  'three/model/jifangDraco.gltf' ;
var dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath( 'three/js/libs/draco/gltf/' );
loader.setDRACOLoader( dracoLoader );
loader.load(
    path ,
    ( gltf ) => {
        // called when the resource is loaded
        scene.add( gltf.scene );
    },
    ( xhr ) => {
        // called while loading is progressing
        console.log( `${( xhr.loaded / xhr.total * 100 )}% loaded` );
    },
    ( error ) => {
        // called when loading has errors
        console.error( 'An error happened', error );
    },
);

执行代码会发下以下错误:DRACOLoader实例对象下setDecoderPath方法未定义。
在这里插入图片描述
此刻 是不是有点奇怪,明明和官方demo写法一致为什么会报错,查阅了很多文档终于在一篇文章中找到了答案(参考文章:https://blog.csdn.net/yue1241630499/article/details/105322176),代码做以下改动:

import * as THREE from 'three'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { DRACOLoader  } from 'three/examples/jsm/loaders/DRACOLoader'

const loader = new GLTFLoader(), path =  'three/model/jifangDraco.gltf' ;
DRACOLoader.setDecoderPath( 'three/js/libs/draco/gltf/' );//设置解压库文件路径
var dracoLoader = new DRACOLoader();
modelLoader.setDRACOLoader( dracoLoader );
loader.load(
    path ,
    ( gltf ) => {
        // called when the resource is loaded
        scene.add( gltf.scene );
    },
    ( xhr ) => {
        // called while loading is progressing
        console.log( `${( xhr.loaded / xhr.total * 100 )}% loaded` );
    },
    ( error ) => {
        // called when loading has errors
        console.error( 'An error happened', error );
    },
);

发现区别了嘛?太奇怪了,暂时还未发现这么写的原因,有知晓者欢迎评论区指点迷津。

对于DRACOLoader.setDecoderPath( 'three/js/libs/draco/gltf/' )设置解压库文件路径的补充

是不是对这个方法的路径参数很懵?我也很懵。。。项目中没有这些文件怎么办。。。那就无奈引入吧,先实现效果再说。去官网工具资源下载官方Three.js-master包,里面有three.js所需各种插件,解压缩后将Three.js-master\R102版本\three.js-master\three.js-r102\examples\路径下js文件夹存入public/three路径下面即可。

总结:到此gltf格式文件终于可以成功导入了,模型加载速度提升不少。此篇文章对于three.js初学者大有帮助,欢迎批评指正,评论区留言。

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页