友情链接:threejs 中文文档
目录
1. GLTF格式简介 (Web3D领域JPG)
GLTF格式信息
2. 加载.gltf文件(全流程)
(1) 引入GLTFLoader.js
(2) gltf加载器new GLTFLoader()
(3) gltf加载器方法.load()
(4) 纹理贴图颜色偏差解决
3. 递归遍历层级模型
递归遍历方法.traverse()
查看gltf默认的材质
4. 纹理encoding和渲染器
纹理对象Texture颜色空间编码属性.encoding
浏览器控制台查看Texture.encoding属性值
WebGL渲染器.outputEncoding
GLTF格式是新2015发布的三维模型格式,随着物联网、WebGL、5G的进一步发展,会有越来越多的互联网项目Web端引入3D元素,你可以把GLTF格式的三维模型理解为.jpg、.png格式的图片一样,现在的网站,图片基本是标配,对于以后的网站来说如果需要展示一个场景,使用3D来替换图片表达也是很正常的事情。图片有很多格式,对于三维模型自然也是如此,Web开发的时候图片会有常用格式,对于Web3D开发也一样,肯定会根据需要选择一个常见的大家都熟悉的格式,随时时间的发展,GLTF必然称为一个极为重要的标准格式。
不仅three.js,其它的WebGL三维引擎cesium、babylonjs都对gltf格式有良好的的支持
如果你有一定的前端基础,那么你对JSON一定不陌生,GLTF文件就是通过JSON的键值对方式来表示模型信息,比如meshes表示网格模型信息,materials表示材质信息...
{
"asset": {
"version": "2.0",
},
...
// 模型材质信息
"materials": [
{
"pbrMetallicRoughness": {//PBR材质
"baseColorFactor": [1,1,0,1],
"metallicFactor": 0.5,//金属度
"roughnessFactor": 1//粗糙度
}
}
],
// 网格模型数据
"meshes": ...
// 纹理贴图
"images": [
{
// uri指向外部图像文件
"uri": "贴图名称.png"//图像数据也可以直接存储在.gltf文件中
}
],
"buffers": [
// 一个buffer对应一个二进制数据块,可能是顶点位置 、顶点索引等数据
{
"byteLength": 840,
//这里面的顶点数据,也快成单独以.bin文件的形式存在
"uri": "data:application/octet-stream;base64,AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAC/.......
}
],
}
// 引入gltf模型加载库GLTFLoader.js
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
执行new GLTFLoader()就可以实例化一个gltf的加载器对象。
// 创建GLTF加载器对象
const loader = new GLTFLoader();
通过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 );
})
three.js加载gltf模型的时候,可能会遇到three.js渲染结果颜色偏差,对于这种情况,你只需要修改WebGL渲染器默认的编码方式.outputEncoding即可
//解决加载gltf格式模型纹理贴图和原图不一样问题
renderer.outputEncoding = THREE.sRGBEncoding;
注意!!!!!!!最新版本属性名字有改变。渲染器属性名.outputEncoding已经变更为.outputColorSpace。 查WebGL渲染器文档,你可以看到.outputColorSpace的默认值就是SRGB颜色空间THREE.SRGBColorSpace,意味着新版本代码中,加载gltf,没有特殊需要,不设置.outputColorSpace也不会引起色差。
//新版本,加载gltf,不需要执行下面代码解决颜色偏差
renderer.outputColorSpace = THREE.SRGBColorSpace;//设置为SRGB颜色空间
加载一个外部模型,比如gltf模型,如果你想批量修改每个Mesh的材质,一个一个设置比较麻烦,可以通过递归遍历方法.traverse()批量操作更加方便。
gltf.scene.traverse(function(obj) {
if (obj.isMesh) {//判断是否是网格模型
console.log('模型节点',obj);
console.log('模型节点名字',obj.name);
}
});
.obj、.gltf、.fbx等不同格式的模型,threejs加载默认的材质可能不同,不过也不用刻意记忆,通过浏览器控制台log打印即可console.log(obj.material)
// 递归遍历所有模型节点批量修改材质
gltf.scene.traverse(function(obj) {
if (obj.isMesh) {
console.log('gltf默认材质',obj.material);
}
});
如果没有特殊需要,一般为了正常渲染,避免颜色偏差,threejs代码中需要颜色贴图.encoding和渲染器.outputEncoding属性值保持一致。
纹理对象Texture颜色空间 (opens new window)编码属性.encoding有多个属性值,默认值是线性颜色空间THREE.LinearEncoding。
const texture = new THREE.TextureLoader().load('./earth.jpg');
texture.encoding = THREE.LinearEncoding;//默认值
// THREE.LinearEncoding变量在threejs内部表示数字3000
console.log('texture.encoding',texture.encoding);
// 修改为THREE.sRGBEncoding,
texture.encoding = THREE.sRGBEncoding;
// THREE.sRGBEncoding变量在threejs内部表示数字3001
console.log('texture.encoding',texture.encoding);
.outputEncoding的默认值是线性空间THREE.LinearEncoding,和纹理对象.encoding默认值一样,如果颜色贴图.encoding的值是THREE.sRGBEncoding,为了避免颜色偏差,.outputEncoding的值也需要设置为THREE.sRGBEncoding。
//解决加载gltf格式模型颜色偏差问题
renderer.outputEncoding = THREE.sRGBEncoding;
注意!最新版本属性名字有改变。渲染器属性名.outputEncoding已经变更为.outputColorSpace
文章中部分素材选取自Threejs中文网:Three.js中文网