六、threejs学习笔记-加载外部三维模型

友情链接: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

1. GLTF格式简介 (Web3D领域JPG)

GLTF格式是新2015发布的三维模型格式,随着物联网、WebGL、5G的进一步发展,会有越来越多的互联网项目Web端引入3D元素,你可以把GLTF格式的三维模型理解为.jpg、.png格式的图片一样,现在的网站,图片基本是标配,对于以后的网站来说如果需要展示一个场景,使用3D来替换图片表达也是很正常的事情。图片有很多格式,对于三维模型自然也是如此,Web开发的时候图片会有常用格式,对于Web3D开发也一样,肯定会根据需要选择一个常见的大家都熟悉的格式,随时时间的发展,GLTF必然称为一个极为重要的标准格式。

不仅three.js,其它的WebGL三维引擎cesium、babylonjs都对gltf格式有良好的的支持

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/.......
    }
  ],
}

2. 加载.gltf文件(全流程)

(1) 引入GLTFLoader.js

// 引入gltf模型加载库GLTFLoader.js
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

(2) gltf加载器new GLTFLoader()

执行new GLTFLoader()就可以实例化一个gltf的加载器对象。

// 创建GLTF加载器对象
const loader = new GLTFLoader();

(3) 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 );
})

(4) 纹理贴图颜色偏差解决

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颜色空间

 3. 递归遍历层级模型

加载一个外部模型,比如gltf模型,如果你想批量修改每个Mesh的材质,一个一个设置比较麻烦,可以通过递归遍历方法.traverse()批量操作更加方便。

递归遍历方法.traverse()

gltf.scene.traverse(function(obj) {
    if (obj.isMesh) {//判断是否是网格模型
        console.log('模型节点',obj);
        console.log('模型节点名字',obj.name);
    }
});

查看gltf默认的材质

.obj、.gltf、.fbx等不同格式的模型,threejs加载默认的材质可能不同,不过也不用刻意记忆,通过浏览器控制台log打印即可console.log(obj.material)

六、threejs学习笔记-加载外部三维模型_第1张图片

// 递归遍历所有模型节点批量修改材质
gltf.scene.traverse(function(obj) {
    if (obj.isMesh) {
        console.log('gltf默认材质',obj.material);
    }
});

 4. 纹理encoding和渲染器

如果没有特殊需要,一般为了正常渲染,避免颜色偏差,threejs代码中需要颜色贴图.encoding和渲染器.outputEncoding属性值保持一致。

纹理对象Texture颜色空间编码属性.encoding

纹理对象Texture颜色空间 (opens new window)编码属性.encoding有多个属性值,默认值是线性颜色空间THREE.LinearEncoding。

  • THREE.LinearEncoding:线性颜色空间
  • THREE.sRGBEncoding:sRGB颜色空间

浏览器控制台查看Texture.encoding属性值

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);

WebGL渲染器.outputEncoding

.outputEncoding的默认值是线性空间THREE.LinearEncoding,和纹理对象.encoding默认值一样,如果颜色贴图.encoding的值是THREE.sRGBEncoding,为了避免颜色偏差,.outputEncoding的值也需要设置为THREE.sRGBEncoding

//解决加载gltf格式模型颜色偏差问题
renderer.outputEncoding = THREE.sRGBEncoding;

注意!最新版本属性名字有改变。渲染器属性名.outputEncoding已经变更为.outputColorSpace

 文章中部分素材选取自Threejs中文网:Three.js中文网

你可能感兴趣的:(threejs,前端,threejs)