加载.gltf 文件(模型加载文件)
- gltf 模型加载器 GLTFLoader.js
- 相机参数根据需要设置
- 加载.gltf 文件的时候,设置 webgl 渲染器的编码方式
引入 GLTFLoader.js
你在 three.js 官方文件的**examples/jsm/子文件 loaders/**目录下,可以找到一个文件 GLTFLoader.js,这个文件就是 three.js 的一个扩展库,专门用来加载 gltf 格式模型加载器
// 引入gltf模型加载库GLTFLoader.js
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
实例化 gltf 加载器: new GLTFLoader()
执行 new GLTFLoader()就可以实例化一个 gltf 的加载器对象
// 创建GLTF加载器对象
const loader = new GLTFLoader();
gltf 加载器方法.load()
通过 gltf 加载器方法.load()就可以加载外部的 gltf 模型
执行方法.load()会返回一个 gltf 对象,作为参数 2 函数的参数,改 gltf 对象可以包含模型、动画等信息,本文章只需要先了解 gltf 的场景属性 gltf.scene,该属性包含的是模型信息,比如几何体 BufferGometry、材质 Material、网格模型 Mesh
loader.load('gltf模型.gltf', function (gltf) {
console.log('控制台查看加载gltf文件返回的对象结构', gltf);
console.log('gltf对象场景属性', gltf.scene);
// 返回的场景对象gltf.scene插入到threejs场景中
scene.add(gltf.scene);
});
相机选择(正投影 OrthographicCamera 和透视投影 PerspectiveCamera)
如果你想预览一个三维场景,一般有正投影相机 OrthographicCamera 和透视投影相机 PerspectiveCamera 可供选择,不过大部分 3D 项目,一般都是使用透视投影相机 PerspectiveCamera,比如游戏、物联网等项目也都会选择透视投影相机 PerspectiveCamera
如果你希望渲染的结果符合人眼的远小近大的规律,毫无疑问要选择透视投影相机,如果不需要模拟人眼远小近大的投影规律,可以选择正投影相机
尺寸概念
项目开发的时候,程序员对一个模型或者说一个三维场景要有一个尺寸的概念,不用具体值,要有一个大概印象
一般通过三维建模软件可以轻松测试测量模型尺寸,比如作为程序员你可以用三维建模软件 blender 打开 gltf 模型,可以自己测量尺寸
单位问题
three.js 的世界并没有任何单位,只有数字大小的运算
obj、gltf 格式的模型信息只有尺寸,并不含单位信息
不过实际项目开发的时候,一般会定义一个单位,一方面甲方、前端、美术之间更好协调,甚至你自己写代码也要有一个尺寸标准,比如一个园区、工厂,可以 m 为单位建模,比如建筑、人、相机都用 m 为尺度去衡量,如果单位不统一,就需要你写代码,通过.scale 属性去缩放
设置合适的相机参数
通过 gltf 加载完成模型后,你还需要根据自身需要,设置合适的相机参数,就好比你拍照,你想拍摄一个石头,肯定要把相机对着石头,如果希望石头在照片上占比大,就要离石头近一些
相机位置怎么设置,你就类比你的眼睛,如果你想模拟人在 3D 场景中漫游,那么很简单,你把相机放在地面上,距离地面高度和人身高接近即可
如果你想看到工厂的全貌,你可以理解为你坐着无人机向下俯瞰,简单说,相比人漫游工厂,整体预览工厂相机距离工厂距离更远一些,否则你也看不到全貌,当然过于远了,你就看不清工厂了
相机位置.position
工厂尺寸范围大概 200 米数量级,那么如果想整体预览观察工厂所有模型,那很简单,第一步,把 camera.position 的 xyz 值统统设置为几百即可,比如(200, 200, 200)
具体 xyz 值,你可以通过 OrbitControls 可视化操作调整,然后浏览器控制台记录相机参数即可
camera.position.set(200, 200, 200);
某位置在 canvas 画布居中
你如果需要工厂的那个位置在 canavs 画布上居中,请直接把 camera.lookAt()指向哪个坐标
如果美术建模,把工厂整体居中,也就是说模型的几何中心,大概位于世界坐标原点,你设置 camera.lookAt(0,0,0),相机视线指向坐标原点
camera.lookAt(0, 0, 0);
注意相机控件 OrbitControls 会影响 lookAt 设置,注意手动设置 OrbitControls 的目标参数
camera.lookAt(100, 0, 0);
// 设置相机控件轨道控制器OrbitControls
const controls = new OrbitControls(camera, renderer.domElement);
// 相机控件.target属性在OrbitControls.js内部表示相机目标观察点,默认0,0,0
// console.log('controls.target', controls.target);
controls.target.set(100, 0, 0);
controls.update(); //update()函数内会执行camera.lookAt(controls.targe)
远裁截面 far 参数
近裁截面 near 和远裁截面 far,要能包含你想渲染的场景,否则超出视锥体模型会被剪裁掉,简单说 near 足够小,far 足够大,主要是 far
PerspectiveCamera(fov, aspect, near, far)
测量工厂尺寸大概几百的数量级,这里不用测具体尺寸,有个大概数量级即可,然后 far 设置为 3000 足够了
const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000);
纹理贴图颜色偏差解决
three.js 加载 gltf 模型的时候,可能会遇到 three.js 渲染结果颜色偏差,对于这种情况,你只需要修改 WebGL 渲染器默认的编码方式.outputEncoding 即可
//解决加载gltf格式模型纹理贴图和原图不一样问题
renderer.outputEncoding = THREE.sRGBEncoding; // 经过测试 已经被废弃了
renderer.outputEncoding = THREE.outputColorSpace;
注意! 最新版本属性名字有改变,渲染器属性名.outputEncoding 已经变更为.outputColorSpace
查 WebGL 渲染器文档,你可以看到.outputColorSpace 的默认值就是 SRGB 颜色空间 THREE.SRGBColorSpace,意味着新版本代码中,加载 gltf,没有特殊需要,不设置.outputColorSpace 也不会引起色差
//新版本,加载gltf,不需要执行下面代码解决颜色偏差
renderer.outputColorSpace = THREE.SRGBColorSpace; //设置为SRGB颜色空间