课程表

three.js课程

工具箱
速查手册

Three 模型文件加载

当前位置:免费教程 » JS/JS库/框架 » three.js

实际开发中,大多数项目,通常是3D美术设计师或建筑、机械等行业工程师提供的由3dmx、blender、substence、Solidworks等软件创建好的三维模型文件。

本章节第一小节以Threejs引擎自身为例,讲解Threejs模型导入导出,该小节对Threejs模型文件本身进行了讲解,让你明白你加载的三维模型文件里面都是包含什么内容。其它章节展示了一些加载外部不同格式模型的案例,除了讲解实现代码外,还对模型的数据结构进行了简单讲解,尽管加载一个模型不一定需要知道它的内容结构,但是如果你理解模型本质上就是顶点、材质等数据,那么随意给你一种格式模型,你至少会有了解该模型能够包含哪些数据的意识。

1.jpg

如果您的服务器不能加载这些3D文件,请配置相关的MIME信息:

.obj文件的MIME类型:application/octet-stream

.fbx文件的MIME类型:model/vnd.collada

.glb文件的MIME类型:model/gltf-binary


数据结构、导入导出

通过Three.js模型数据导入导出过程的学习,可以让你对Threejs解析加载外部模型的过程更为了解。

Threejs导出模型信息

你可以通过下面代码导出模型的各类信息,然后在浏览器控制台打印出来模型数据,然后复制浏览器控制台模型数据粘贴到json文件中,最后可以尝试加载解析这些Threejs导出的json文件。之所以这么做,是为了让你理解其它三维软件,比如3dmax、blender软件导出的三维模型文件本质上是什么。

查看Threejs文档Geometry、Material、Light、Object3D等类,你可以发现这些类都提供了一个方法.toJSON()通过这个方法可以导出Threejs三维模型的各类数据,该方法的功能就是把Threejs的几何体、材质、光源等对象转化为JSON格式导出。

导出几何体信息:

  1. var geometry = new THREE.BoxGeometry(100, 100, 100);
  2. // 控制台查看立方体数据
  3. console.log(geometry);
  4. // 控制台查看geometry.toJSON()结果
  5. console.log(geometry.toJSON());
  6. // JSON对象转化为字符串
  7. console.log(JSON.stringify(geometry.toJSON()));
  8. // JSON.stringify()方法内部会自动调用参数的toJSON()方法
  9. console.log(JSON.stringify(geometry));

导出材质信息:

  1. var material = new THREE.MeshLambertMaterial({
  2.   color: 0x0000ff,
  3. }); //材质对象Material
  4. console.log(material);
  5. console.log(material.toJSON());
  6. console.log(JSON.stringify(material));

导出场景scene信息:

  1. var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
  2. scene.add(mesh); //网格模型添加到场景中
  3. console.log(scene);
  4. console.log(scene.toJSON());

在线运行案例

自定义模型加载器文件

实际开发中,加载一种特定格式的模型文件,Threejs在three.js-master\examples\js\loaders目录下会提供一系列的加载器,这些加载器本质上都是解析模型文件的字符串,通过正则表达式提取相关的顶点、材质等信息转化为Threejs自身的类表示的对象。为了让大家更理解这些常见的加载器,课件中提供了一个源码案例,编写了一个非常非常简易的自定义加载器,然后使用自定义的加载器去加载一个文件,让大家明白这些加载器怎么来的。

  1. // 如果编写通用的材质加载器需要枚举所有的材质,这里没有列举完
  2. var typeAPI = {
  3.   MeshLambertMaterial: THREE.MeshLambertMaterial,
  4.   MeshBasicMaterial: THREE.MeshBasicMaterial,
  5.   MeshPhongMaterial: THREE.MeshPhongMaterial,
  6.   PointsMaterial: THREE.PointsMaterial,
  7. }
  8. // 创建一个文件加载器,该加载器是对异步加载的封装
  9. var loader = new THREE.FileLoader();
  10. loader.load('material.json', function(elem) {
  11.   console.log(elem);// 查看加载返回的内容
  12.   var obj = JSON.parse(elem);// 字符串转JSON对象
  13.   console.log(obj);// 查看转化结果
  14.   var geometry = new THREE.BoxGeometry(100, 100, 100);
  15.   /**
  16.    * 解析材质数据
  17.    */
  18.   // 根据type的值判断调用threejs的哪一个API
  19.   var material = new typeAPI[obj.type]();
  20.   // 从obj.color中提取颜色
  21.   // 16711935对应颜色0xFF00FF  255对应颜色0x0000FF
  22.   material.color.= (obj.color >> 16 & 255) / 255; //获取颜色值R部分
  23.   material.color.= (obj.color >> 8 & 255) / 255; //获取颜色值G部分
  24.   material.color.= (obj.color & 255) / 255; //获取颜色值B部分
  25.  
  26.   var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
  27.   scene.add(mesh); //网格模型添加到场景中
  28. })

在线运行案例

加载Three.js导出的模型数据

缓冲几何体数据加载器:

  1. /**
  2.  *
  3.  */
  4. var loader = new THREE.BufferGeometryLoader();
  5. loader.load('bufferGeometry.json',function (geometry) {
  6.   // 控制台查看加载放回的threejs对象结构
  7.   console.log(geometry);
  8.   var material = new THREE.MeshLambertMaterial({
  9.     color: 0x0000ff,
  10.   }); //材质对象Material
  11.   var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
  12.   scene.add(mesh); //网格模型添加到场景中
  13. })

在线运行案例

网格模型Mesh加载,包含几何体Geometry和材质Material:

  1. var loader = new THREE.ObjectLoader();
  2. loader.load('model.json',function (obj) {
  3.   console.log(obj);
  4. console.log(obj.type);
  5.   obj.scale.set(100,100,100)
  6.   scene.add(obj)
  7. })

在线运行案例

加载组Group对象,模型对象构成的树结构:

  1. loader.load('group.json', function(obj) {
  2.   console.log(obj);
  3.   console.log(obj.type);
  4.   scene.add(obj)
  5. })

在线运行案例

加载场景对象,场景对象不仅包含模型,还包括光源对象:

  1. loader.load('scene.json',function (obj) {
  2.   console.log(obj);
  3.   console.log(obj.type);
  4.   obj.scale.set(100,100,100)
  5.   scene.add(obj)
  6. })

在线运行案例


.stl格式模型加载

基本所有的三维软件都支持导出.stl格式的三维模型文件,.stl格式的三维模型不包含材质Material信息,只包含几何体顶点数据的信息,你可以简单地把stl文件理解为几何体对象Geometry,本节课素材box.STL是一个立方体, 你可以用记事本或代码编辑器打开文件box.STL查看stl的数据结构。

stl文件数据结构

.stl文件格式的数据结构,对于大多数普通开发者来说,如果仅仅为了加载显示一个三维模型,也没必要掌握,这里之所以要强调,不是为了让你记住,而是为了从底层了解Threejs模型加载的原理,达到举一反三的目的。

三个位置坐标和一个三角形面的法线方向向量是一组数据,这一组数据表示一个三角形面的信息,可以回忆下之前关于三角形面Face3的讲解。

表示一个三角形面信息的一组数据:

  1. //三角面1
  2.    facet normal 0 0 -1    //三角形面法向量
  3.       outer loop
  4.          vertex 50 50 -50   //顶点位置
  5.          vertex 50 -50 -50  //顶点位置
  6.          vertex -50 50 -50  //顶点位置
  7.       endloop
  8.    endfacet

一个立方体有6个矩形平面,每个矩形平面至少需要两个三角形拼接而成。那么立方体6个矩形平面至少需要12个三角形面构成,你可以在STL文件中这样定义12个三角形信息:

  1. solid box  //文件名字
  2. //三角面1
  3.    facet normal 0 0 -1    //三角形面法向量
  4.       outer loop
  5.          vertex 50 50 -50   //顶点位置
  6.          vertex 50 -50 -50  //顶点位置
  7.          vertex -50 50 -50  //顶点位置
  8.       endloop
  9.    endfacet
  10. //三角面2
  11.    facet normal 0 0 -1    //三角形面法向量
  12.       outer loop
  13.          vertex -50 50 -50   //顶点位置
  14.          vertex 50 -50 -50   //顶点位置
  15.          vertex -50 -50 -50  //顶点位置
  16.       endloop
  17.    endfacet
  18.    facet normal 0 1 0
  19.       .....
  20.       .....
  21. //三角面12
  22.    facet normal -1 0 0
  23.       outer loop
  24.          vertex -50 -50 -50
  25.          vertex -50 50 50
  26.          vertex -50 50 -50
  27.       endloop
  28.    endfacet
  29. endsolid

通过STLLoader.js加载.stl文件

如果你想通过Threejs加载.stl格式三维模型文件,可以使用Threejs提供的一个扩展库stl加载器STLLoader.js,你可以在Three.js-master包中找到STLLoader.js文件,具体路径是three.js-master\examples\js\loaders.

.html文件中引入Threejs的扩展库STLLoader.js,引入该文件后,就可以在代码中使用构造函数THREE.STLLoader()实例化一个加载器。

  1. <!--引入STLLoader.js文件-->
  2. <script src="STLLoader.js"></script>

通过构造函数THREE.STLLoader()可以把.stl文件中几何体顶点信息提取出来转化为Three.js自身格式的几何体对象BufferGeometry。如果你有兴趣可以阅读STLLoader.js源码,尤其是你想独立开发自己公司特定格式加载器的情况下,更有必要参照学习。

  1. // THREE.STLLoader创建一个加载器
  2. var loader = new THREE.STLLoader();
  3. loader.load('立方体.stl',function (geometry) {
  4.   // 加载完成后会返回一个几何体对象BufferGeometry,你可以通过Mesh、Points等方式渲染该几何体
  5. })
  1. /**
  2.  * stl数据加载
  3.  */
  4. var loader = new THREE.STLLoader();
  5. // 立方体默认尺寸长宽高各200
  6. loader.load('立方体.stl',function (geometry) {
  7.   // 控制台查看加载放回的threejs对象结构
  8.   console.log(geometry);
  9.   // 查看顶点数,一个立方体6个矩形面,每个矩形面至少2个三角面,每个三角面3个顶点,
  10.   // 如果没有索引index复用顶点,就是说一个立方体至少36个顶点
  11.   console.log(geometry.attributes.position.count);
  12.   // 缩放几何体
  13.   // geometry.scale(0.5,0.5,0.5);
  14.   // 几何体居中
  15.   // geometry.center();
  16.   // 平移立方体
  17.   // geometry.translate(-50,-50,-50);
  18.   var material = new THREE.MeshLambertMaterial({
  19.     color: 0x0000ff,
  20.   }); //材质对象Material
  21.   var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
  22.   scene.add(mesh); //网格模型添加到场景中
  23. })

在线运行案例

使用点模型渲染STL文件

你可以使用下面代码代替上面代码,查看Three.js如果通过点模型Points渲染stl文件中的顶点数据。

  1. /**
  2.  * 点渲染模式
  3.  */
  4.  loader.load('离心叶轮.stl',function (geometry) {
  5.    var material = new THREE.PointsMaterial({
  6.      color: 0x000000,
  7.      size: 0.5//点对象像素尺寸
  8.    }); //材质对象
  9.    var points = new THREE.Points(geometry, material); //点模型对象
  10.    scene.add(points); //点对象添加到场景中
  11.  })

在线运行案例


加载.obj模型文件

使用三维软件导出.obj模型文件的时候,会同时导出一个材质文件.mtl, .obj和.stl文件包含的信息一样都是几何体顶点相关数据,材质文件.mtl包含的是模型的材质信息,比如颜色、贴图路径等。

加载.obj三维模型的时候,可以只加载.obj文件,然后借助three.js引擎自定义材质Material,也可以同时加载.obj和.mtl文件。

只加载obj文件

只加载obj文件,引入路径three.js-master/examples/js/loaders/OBJLoader.js下的OBJLoader.js文件即可:

  1. <!-- 引入obj模型加载库OBJLoader.js -->
  2. <script src="../../three.js-master/examples/js/loaders/OBJLoader.js"></script>

.obj文件加载:

  1. /**
  2.  * OBJ文件加载  只加载obj文件中的几何信息,不加载材质文件.mtl
  3.  */
  4. var loader = new THREE.OBJLoader();
  5. // 没有材质文件,系统自动设置Phong网格材质
  6. loader.load('./立方体/box.obj',function (obj) {
  7.   // 控制台查看返回结构:包含一个网格模型Mesh的组Group
  8.   console.log(obj);
  9.   // 查看加载器生成的材质对象:MeshPhongMaterial
  10.   console.log(obj.children[0].material);
  11.   scene.add(obj);
  12. })

加载文件返回的对象插入场景中后,你也可以做一些自定的设置,比如缩放、居中等操作。

  1. // 加载后的一些编辑操作
  2. obj.children[0].scale.set(20,20,20);//网格模型缩放
  3. obj.children[0].geometry.center();//网格模型的几何体居中
  4. obj.children[0].material.color.set(0xff0000);//设置材质颜色

在线运行案例

同时加载obj文件和mtl文件

mtl文件包含了模型的材质信息,比如模型颜色、透明度等信息,还有纹理贴图的路径,比如颜色贴图、法线贴图、高光贴图等等。

  1. <!-- 引入obj模型加载库OBJLoader.js -->
  2. <script src="../../three.js-master/examples/js/loaders/OBJLoader.js"></script>
  3. <!-- 引入obj模型材质加载库MTLLoader.js -->
  4. <script src="../../three.js-master/examples/js/loaders/MTLLoader.js"></script>

同时加载代码:

  1. /**
  2.  * OBJ和材质文件mtl加载
  3.  */
  4. var OBJLoader = new THREE.OBJLoader();//obj加载器
  5. var MTLLoader = new THREE.MTLLoader();//材质文件加载器
  6. MTLLoader.load('./立方体/box.mtl', function(materials) {
  7.   // 返回一个包含材质的对象MaterialCreator
  8.   console.log(materials);
  9.   //obj的模型会和MaterialCreator包含的材质对应起来
  10.   OBJLoader.setMaterials(materials);
  11.   OBJLoader.load('./立方体/box.obj', function(obj) {
  12.     console.log(obj);
  13.     obj.scale.set(10, 10, 10); //放大obj组对象
  14.     scene.add(obj);//返回的组对象插入场景中
  15.   })
  16. })

在线运行案例

obj包含多个网格模型

obj文件可以包含多个网格模型对象,不一定就是一个,这些网格模型对象全部是并列关系,无法通过父子关系构建一个树结构层级模型。

  1. // 没有材质文件,系统自动设置Phong网格材质
  2. OBJLoader.load('./多个模型/model.obj',function (obj) {
  3.   // 控制台查看返回结构:包含一个网格模型Mesh的组Group
  4.   console.log(obj);
  5.   scene.add(obj);
  6.   // 加载后的一些编辑操作
  7.   obj.scale.set(20,20,20);//网格模型缩放
  8.   // 设置其中一个网格模型的颜色
  9.   obj.children[0].material.color.set(0xff0000);
  10. })

模型纹理贴图

obj模型的mtl文件可能包含纹理贴图,也可能不包含,这主要看3D美术是否设置。

一个包含纹理贴图路径的.mtl文件,如果路径有问题,可能会无法加载,可以仿照该案例修改。

  1. // 一个包含纹理贴图路径的.mtl文件
  2. newmtl material_1
  3.     Ns 32
  4.     d 1
  5.     Tr 0
  6.     Tf 1 1 1
  7.     illum 2
  8.     Ka 0.5880 0.5880 0.5880
  9.     Kd 0.9880 0.9880 0.9880
  10.     Ks 0.1200 0.1200 0.1200
  11.     map_Kd ./贴图/Earth.png
  12.   map_ks ./贴图/EarthSpec.png
  13.     norm ./贴图/EarthNormal.png

mtl和threejs贴图对应关系:

mtl贴图Threejs贴图
map_kdmap
map_ksspecularMap
map_bump/bumpbumpMap
  1. /**
  2.  * OBJ和材质文件mtl加载
  3.  */
  4. var OBJLoader = new THREE.OBJLoader(); //obj加载器
  5. var MTLLoader = new THREE.MTLLoader(); //材质文件加载器
  6. MTLLoader.load('./贴图/material.mtl', function(materials) {
  7.   // 返回一个包含材质的对象MaterialCreator
  8.   console.log(materials);
  9.   //obj的模型会和MaterialCreator包含的材质对应起来
  10.   OBJLoader.setMaterials(materials);
  11.   OBJLoader.load('./贴图/model.obj', function(obj) {
  12.     console.log(obj);
  13.     scene.add(obj); //返回的组对象插入场景中
  14.     // 加载后操作
  15.     obj.children[0].scale.set(2, 2, 2); //缩放球体网格模型
  16.     // 通过调节参数,地球表面的凹凸感更强
  17.     obj.children[0].material.normalScale.set(3, 3);
  18.   })
  19. })

在线运行案例

导出.obj和.mtl的名称、路径问题

3dmax导出的obj和mtl模型文件有时候需要修改一下个别位置字符,比如.obj中.mtl文件的名称可能是乱码mtllib ?????.mtl,.mtl文件中贴图的路径要设置正确,比如导出的是绝对路径还是相对路径,可以打开看下。

.obj文件不包含信息

.obj文件不包含场景的相机Camera、光源Light等信息,不能导出骨骼动画、变形动画,如果希望导出光照信息、相机信息、骨骼动画信息、变形动画信息,可以选择.fbx、.gltf等格式。


加载FBX并解析骨骼动画

通过Threejs先加载一个.FBX格式的三维模型文件,然后解析该文件中的骨骼动画信息。

加载器FBXLoader.js

引入FBX加载器相关文件

  1. <!-- 引入fbx模型加载库FBXLoader -->
  2. <script src="FBXLoader.js"></script>
  3. <!-- 辅助文件 -->
  4. <script src="inflate.min.js"></script>

加载fbx模型文件

加载模型文件,加载完成后,如果模型显示位置不符合要求,可以让3D美术修改,也可以通过Threejs程序进行平移、缩放等操作。

  1. var loader = new THREE.FBXLoader();//创建一个FBX加载器
  2. loader.load("SambaDancing.fbx", function(obj) {
  3.   // console.log(obj);//查看加载后返回的模型对象
  4.   scene.add(obj)
  5.   // 适当平移fbx模型位置
  6.   obj.translateY(-80);
  7. })

查看FBX模型帧动画数据

stl、obj都是静态模型,不可以包含动画,fbx除了包含几何、材质信息,可以存储骨骼动画等数据。

解析之前可以先在浏览器控制台查看动画相关的数据是如何存储的。你可以看到obj.animations属性的数组包含两个剪辑对象AnimationClip,obj.animations[0]对应剪辑对象AnimationClip包含多组关键帧KeyframeTrack数据,obj.animations[1]对应的剪辑对象AnimationClip没有关键帧数据,也就是说没有关键帧动画。具体的开发中,可能美术提供的模型有很多包含关键帧动画的剪辑对象AnimationClip,你可以根据自己的需要解析某个剪辑对象AnimationClip对应的动画。

  1. var loader = new THREE.FBXLoader();//创建一个FBX加载器
  2. loader.load("SambaDancing.fbx", function(obj) {
  3.   ...
  4.   // 可以在控制台打印obj对象,找到animations属性
  5.   console.log(obj)
  6.   // 查看动画数据  2个剪辑对象AnimationClip,一个有关键帧动画,一个没有
  7.   console.log(obj.animations)
  8.  
  9. })

解析fbx模型骨骼动画

  1. var mixer=null;//声明一个混合器变量
  2. var loader = new THREE.FBXLoader();//创建一个FBX加载器
  3. loader.load("SambaDancing.fbx", function(obj) {
  4.   // console.log(obj)
  5.   scene.add(obj)
  6.   obj.translateY(-80);
  7.   // obj作为参数创建一个混合器,解析播放obj及其子对象包含的动画数据
  8.   mixer = new THREE.AnimationMixer(obj);
  9.   // 查看动画数据
  10.   console.log(obj.animations)
  11.   // obj.animations[0]:获得剪辑对象clip
  12.   var AnimationAction=mixer.clipAction(obj.animations[0]);
  13.   // AnimationAction.timeScale = 1; //默认1,可以调节播放速度
  14.   // AnimationAction.loop = THREE.LoopOnce; //不循环播放
  15.   // AnimationAction.clampWhenFinished=true;//暂停在最后一帧播放的状态
  16.   AnimationAction.play();//播放动画
  17. })
  1. // 创建一个时钟对象Clock
  2. var clock = new THREE.Clock();
  3. // 渲染函数
  4. function render() {
  5.   renderer.render(scene, camera); //执行渲染操作
  6.   requestAnimationFrame(render); //请求再次执行渲染函数render,渲染下一帧
  7.  
  8.   if (mixer !== null) {
  9.     //clock.getDelta()方法获得两帧的时间间隔
  10.     // 更新混合器相关的时间
  11.     mixer.update(clock.getDelta());
  12.   }
  13. }
  14. render();

在线运行案例


手镯在线预览案例

在线预览产品的时候,一个产品可能会提供不同的系列,比如颜色不同、造型款式不同。本节课的玉镯案例模型提供了三种颜色款式,不同的颜色款式本质上就是网格模型的颜色贴图.map不同。

设置纹理贴图

model.obj文件中已经包含纹理映射的UV坐标数据,直接给模型颜色贴图属性.map赋值即可。

  1. /**
  2.  * OBJ文件加载  只加载obj文件中的几何信息,不加载材质文件.mtl
  3.  */
  4. var loader = new THREE.OBJLoader();
  5. loader.load('./model.obj',function (obj) {
  6.   // 控制台查看返回结构:包含一个网格模型Mesh的组Group
  7.   // console.log(obj);
  8.   //加载纹理贴图texture1.png
  9.   var texture = new THREE.TextureLoader().load('texture1.png');
  10.   // 颜色贴图中已经包含了光照信息,所以直接使用不受光照影响的基础网格材质MeshBasicMaterial
  11.   obj.children[0].material= new THREE.MeshBasicMaterial({
  12.     map:texture,//设置颜色纹理贴图
  13.   })
  14.   scene.add(obj);
  15.   obj.children[0].scale.set(5,5,5);//网格模型缩放
  16. })

在线运行案例

切换颜色

模型提供了texture1.png、texture2.png和texture3.png三张贴图,上面代码加载了texture1.png作为颜色贴图。

你可以在上面代码.load()回调函数中插入下面语句,给玉镯设置其它的颜色款式。

  1. // 更换纹理贴图
  2. var texture = new THREE.TextureLoader().load('texture2.png');
  3. obj.children[0].material.map=texture

实际开发的时候,可能会通过前端UI进行颜色交互(颜色交互体验),其实实现也比较简单,比如一个按钮表示绿色,前端代码只要给该按钮绑定一个函数,函数中执行代码mesh.material.map=Texture改变颜色贴图属性.map的值即可。不过本节课主要是讲解Threejs,关于前端交互内容就不做过多描述,你可以自己创建一个按钮测试这个思路。


心脏在线预览(法线、高光贴图)

本节课加载一个心脏的次时代模型,模型包含颜色贴图.map、法线贴图.normalMap、高光贴图.specularMap、环境贴图.envMap,关于这些贴图的相关属性可以查看高光网格模型材质的文档MeshPhongMaterial。

1.jpg

心脏次时代模型加载设置

  1. /**
  2.  * OBJ文件加载  只加载obj文件中的几何信息,不加载材质文件.mtl
  3.  */
  4. var loader = new THREE.OBJLoader();
  5. // 没有材质文件,系统自动设置Phong网格材质
  6. var mesh = null; //声明一个网格模型变量
  7. loader.load('./heart/model.obj', function(obj) {
  8.   // 控制台查看返回结构:包含一个网格模型Mesh的组Group
  9.   console.log(obj);
  10.   scene.add(obj);
  11.   mesh = obj.children[0]; //获得心脏网格模型
  12.   mesh.scale.set(10, 10, 10); //网格模型缩放
  13.   // 创建一个纹理加载器
  14.   var textureLoader = new THREE.TextureLoader();
  15. ...
  16. })

设置模型的颜色贴图.map。

  1.   //加载颜色纹理
  2.   var texture = textureLoader.load('./heart/color.png');
  3.   mesh.material.map = texture;

设置模型的法线贴图.normalMap,表面细节更丰富,为了压缩模型顶点数量,也就是降低文件大小,3D美术通常会给程序员提供法线贴图。

  1. var textureNormal = textureLoader.load('./heart/normal.png');
  2. mesh.material.normalMap = textureNormal
  3. // 设置深浅程度
  4. mesh.material.normalScale.set(1.5, 1.5)

对于心脏模型而言,模型外表面不同区域的粗糙度不同,对光线的镜面反射程度不同,所以可以把这些不同区域的不同光反射信息记录在一个贴图上,即高光贴图.specularMap,设置高光贴图需要高光网格模型材质MeshPhongMaterial。

  1. // 设置高光贴图,一个网格模型不同的区域反射光线的能力不同
  2. var textureSpecular = textureLoader.load('./heart/Specular.png');
  3. mesh.material.specularMap = textureSpecular;
  4. mesh.material.specular.set(0xffffff);// 高光反射颜色
  5. mesh.material.shininess = 100;// 高光高亮程度,默认30

通过类CubeTextureLoader来加载六张纹理贴图'px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg'。

设置环境贴图.envMap,反射周围环境效果,渲染更逼真。

  1. var textureCube = new THREE.CubeTextureLoader()
  2.   .setPath('环境贴图/')
  3.   .load(['px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg']);
  4. mesh.material.envMap = textureCube;

渲染模型的时候,合理的设置光源是很必要的,比如光源强度太低,模型就会比较灰暗,光源强度太高,模型会过于明亮。

  1. /**
  2.  * 光源设置
  3.  */
  4. //点光源
  5. var point = new THREE.PointLight(0xffffff, 0.3);
  6. point.position.set(400, 200, 300); //点光源位置
  7. scene.add(point); //点光源添加到场景中
  8. // 环境光
  9. var ambient = new THREE.AmbientLight(0xffffff, 0.8);
  10. scene.add(ambient);
  11. // 方向光1
  12. var directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
  13. directionalLight.position.set(400, 200, 300);
  14. scene.add(directionalLight);
  15. // 方向光2
  16. var directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
  17. directionalLight.position.set(-400, -200, -300);
  18. scene.add(directionalLight);

在线运行案例


加载.glb文件

GLB文件是以图形语言传输格式(glTF)保存的3D模型,它以二进制格式存储有关3D模型的信息,包括节点层级、摄像机、材质、动画和网格。GLB文件是.GLTF文件的二进制版本。

glTF是一种高效、可扩展、可互操作的格式,用于传输和加载3D场景和模型。glTF格式的目标包括最大限度地减少文件大小、快速加载、完整的3D场景表示、运行时独立性以及伴随进一步开发的可扩展性。glTF的提出是源自于3D工业和媒体发展的过程中,对3D格式统一化的急迫需求。

GLB是glTF模型的二进制文件格式表示,它存储了glTF的组件,如JSON、BIN文件和图片。GLB避免了使用glTF格式文件变大的问题,通过压缩,GLB能更快地加载,提供完整的三维场景,且能在未来的开发中扩展。

GLB作为一个容器,用二进制格式实现glTF的内容,并规避了glTF的一些缺陷。GLB格式的规格说明有提到所有的读写的实现,供应用程序开发。

请确保您的服务器配置了.glb文件的MIME类型:

  1. model/gltf-binary

加载.glb文件的方法和加载.obj文件大同小异。首先需要加载GLTFLoader.js:

  1. <script src="GLTFLoader.js"></script>

其格式如下:

  1. //加载外部glb文件
  2. var loader = new THREE.GLTFLoader();
  3. loader.load( '/js/threejs/apple.glb', function ( glb ) {
  4. console.log(glb.scene);
  5. glb.scene.position.set(0,0,25)
  6. glb.scene.scale.set(10,10,10); //放大倍数
  7. scene.add(glb.scene);
  8. }, undefined, function ( error ) {
  9. console.error( error );
  10. } );

在线运行案例

转载本站内容时,请务必注明来自W3xue,违者必究。
 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号