写点什么

Three.js - 走进 3D 的奇妙世界(下)

  • 2020-02-06
  • 本文字数:3102 字

    阅读完需:约 10 分钟

Three.js - 走进3D的奇妙世界(下)

接上篇

五、材质

创建几何体时通过指定几何体的顶点和三角形的面确定了几何体的形状,另外还需要给几何体添加皮肤才能实现物体的效果,材质就像物体的皮肤,决定了物体的质感。常见的材质有如下几种:


1574761705093026955.png


  • 基础材质:以简单着色方式来绘制几何体的材质,不受光照影响。

  • 深度材质:按深度绘制几何体的材质。深度基于相机远近端面,离近端面越近就越白,离远端面越近就越黑。

  • 法向量材质:把法向量映射到 RGB 颜色的材质。

  • Lambert 材质:是一种需要光源的材质,非光泽表面的材质,没有镜面高光,适用于石膏等表面粗糙的物体。

  • Phong 材质:也是一种需要光源的材质,具有镜面高光的光泽表面的材质,适用于金属、漆面等反光的物体。

  • 材质捕获:使用存储了光照和反射等信息的贴图,然后利用法线方向进行采样。优点是可以用很低的消耗来实现很多特殊风格的效果;缺点是仅对于固定相机视角的情况较好。


下图是使用不同贴图实现的效果:


1574761711928053548.png

六、光源

前面提到的光敏材质(Lambert 材质和 Phong 材质)需要使用光源来渲染出 3D 效果,在使用时需要将创建的光源添加到场景中,否则无法产生光照效果。下面介绍一下常用的光源及特点。

6.1 点光源

点光源类似蜡烛放出的光,不同的是蜡烛有底座,点光源没有底座,可以把点光源想象成悬浮在空中的火苗,点光源放出的光线来自同一点,且方向辐射向四面八方,点光源在传播过程中有衰弱,如下图所示,点光源在接近地面的位置,物体底部离点光源近,物体顶部离光源远,照到物体顶部的光就弱些,所以顶部会比底部暗些。


1574761719361025496.png

6.2 平行光

平行光模拟的是太阳光,光源发出的所有光线都是相互平行的,平行光没有衰减,被平行光照亮的整个区域接受到的光强是一样的。


1574761726762024810.png

6.3 聚光灯

类似舞台上的聚光灯效果,光源的光线从一个锥体中射出,在被照射的物体上产生聚光的效果。聚光灯在传播过程也是有衰弱的。


1574761740218053917.png

6.4 环境光

环境光是经过多次反射而来的光,环境光源放出的光线被认为来自任何方向,物体无论法向量如何,都将表现为同样的明暗程度。


1574761746944010096.png


环境光通常不会单独使用,通过使用多种光源能够实现更真实的光效,下图是将环境光与点光源混合后实现的效果,物体的背光面不像点光源那样是黑色的,而是呈现出深褐色,更自然。


1574761753866085908.png

七、纹理

在生活中纯色的物体还是比较少的,更多的是有凹凸不平的纹路或图案的物体,要用 Three.JS 实现这些物体的效果,就需要使用到纹理贴图。3D 世界的纹理是由图片组成的,将纹理添加在材质上以一定的规则映射到几何体上,几何体就有了带纹理的皮肤。

7.1 普通纹理贴图

1574761761607084261.png


在这个示例中使用上图左侧的地球纹理,在球形几何体上进行贴图就能制作出一个地球。


代码如下:


/* 创建地球 */function createGeom() {    // 球体    var geom = new THREE.SphereGeometry(1, 64, 64);    // 纹理    var loader = new THREE.TextureLoader();    var texture = loader.load('./earth.jpg');    // 材质    var material = new THREE.MeshLambertMaterial({        map: texture    });    var earth = new THREE.Mesh(geom, material);    return earth;}
复制代码

7.2 反面贴图实现全景视图

1574761770285098104.png


这个例子是通过在球形几何体的反面进行纹理贴图实现的全景视图,实现原理是这样的:创建一个球体构成一个球形的空间,把相机放在球体的中心,相机就像在一个球形的房间中,在球体的里面(也就是反面)贴上图片,通过改变相机拍摄的方向,就能看到全景视图了。


材质默认是在几何体的正面进行贴图的,如果想要在反面贴图,需要在创建材质的时候设置 side 参数的值为 THREE.BackSide,代码如下:


/* 创建反面贴图的球形 */// 球体var geom = new THREE.SphereGeometry(500, 64, 64);// 纹理var loader = new THREE.TextureLoader();var texture = loader.load('./panorama.jpg');// 材质var material = new THREE.MeshBasicMaterial({    map: texture,    side: THREE.BackSide});var panorama = new THREE.Mesh(geom, material);
复制代码

7.3 凹凸纹理贴图

1574761778594091032.png


凹凸纹理利用黑色和白色值映射到与光照相关的感知深度,不会影响对象的几何形状,只影响光照,用于光敏材质(Lambert 材质和 Phong 材质)。


如果只用上图左上角的砖墙图片进行贴图的话,就像一张墙纸贴在上面,视觉效果很差,为了增强立体感,可以使用上图左下角的凹凸纹理,给物体增加凹凸不平的效果。


凹凸纹理贴图使用方式的代码如下:


// 纹理加载器var loader = new THREE.TextureLoader();// 纹理var texture = loader.load( './stone.jpg');// 凹凸纹理var bumpTexture = loader.load( './stone-bump.jpg');// 材质var material =  new THREE.MeshPhongMaterial( {    map: texture,    bumpMap: bumpTexture} );
复制代码

7.4 法线纹理贴图

1574761786800063329.png


法线纹理也是通过影响光照实现凹凸不平视觉效果的,并不会影响物体的几何形状,用于光敏材质(Lambert 材质和 Phong 材质)。上图左下角的法线纹理图片的 RGB 值会影响每个像素片段的曲面法线,从而改变物体的光照效果。


使用方式的代码如下:


// 纹理var texture = loader.load( './metal.jpg');// 法线纹理var normalTexture = loader.load( './metal-normal.jpg');var material =  new THREE.MeshPhongMaterial( {    map: texture,    normalMap: normalTexture} );
复制代码

7.5 环境贴图

1574761795393098937.png


环境贴图是将当前环境作为纹理进行贴图,能够模拟镜面的反光效果。在进行环境贴图时需要使用立方相机在当前场景中进行拍摄,从而获得当前环境的纹理。立方相机在拍摄环境纹理时,为避免反光效果的小球出现在环境纹理的画面上,需要将小球设为不可见。


环境贴图的主要代码如下:


/* 立方相机 */var cubeCamera = new THREE.CubeCamera( 1, 10000, 128 );/* 材质 */var material = new THREE.MeshBasicMaterial( {    envMap: cubeCamera.renderTarget.texture});/* 镜面反光的球体 */var geom = new THREE.SphereBufferGeometry( 10, 32, 16 );var ball = new THREE.Mesh( geom, material );// 将立方相机添加到球体ball.add( cubeCamera );scene.add( ball );
// 立方相机生成环境纹理前将反光小球隐藏ball.visible = false;// 更新立方相机,生成环境纹理cubeCamera.update( renderer, scene );balls.visible = true;
// 渲染renderer.render(scene, camera);
复制代码

八、加载外部 3D 模型

Three.JS 已经内置了很多常用的几何体,如:球体、立方体、圆柱体等等,但是在实际使用中往往需要用到一些特殊形状的几何体,这时可以使用 3D 建模软件制作出 3D 模型,导出 obj、json、gltf 等格式的文件,然后再加载到 Three.JS 渲染出效果。


1574761804228052501.png


上图的椅子是在 3D 制图软件绘制出来的,chair.mtl 是导出的材质文件,chair.obj 是导出的几何体文件,使用材质加载器加载材质文件,加载完成后得到材质对象,给几何体加载器设置材质,加载后得到几何体对象,然后再创建场景、光源、摄像机、渲染器等进行渲染,这样就等得到如图的效果。主要的代码如下:


// .mtl材质文件加载器var mtlLoader = new THREE.MTLLoader();// .obj几何体文件加载器var objLoader = new THREE.OBJLoader();
mtlLoader.load('./chair.mtl', function (materials) { objLoader.setMaterials(materials) .load('./chair.obj', function (obj) { scene.add(obj); });});
复制代码

九、说明

以上内容对 Three.JS 的基本使用进行了介绍,文中涉及到的示例源码已上传到 github,感兴趣的同学可以下载查看,下载地址:https://github.com/liulinsp/three-demo。使用时如果有不清楚的地方可以查看Three.JS的官方文档:https://threejs.org/docs/index.html。


本文转载自宜信技术学院网站。


原文链接:http://college.creditease.cn/detail/328


2020-02-06 10:341828

评论

发布
暂无评论
发现更多内容

Java开发之环境搭建基础教程

@零度

Java 开发环境搭建

Linux运维,Linux系统学习

侠盗安全

Linux linux运维 运维工程师 云计算架构师

让工具成为双手的延伸

Zilliz

数据库 书籍推荐 程序 书籍

DataPipeline与TiDB推出异构数据实时同步解决方案,共筑安全可信基础设施

DataPipeline数见科技

数据库 大数据 中间件 数据融合 数据管理

如期而至-用户购买时间预测(下)

索信达控股

模型 购买预测 购买行为 精准营销

Android C++系列:Linux网络(三)协议格式

轻口味

c++ android 28天写作 12月日更

数据库事务的三个元问题

Zilliz

数据库 数据库设计

CANN5.0黑科技解密 | 高并发图片视频处理,为出行保驾,为生活添彩!

华为云开发者联盟

高并发 图像预处理 CANN 昇腾 异构计算

进程崩溃/应用卡死,故障频频怎么办?|HDC2021技术分论坛

HarmonyOS开发者

HarmonyOS

这套神奇的个人信息管理系统,带我一步步进入互联网大厂

博文视点Broadview

Python enumerate():使用计数器简化循环

华为云开发者联盟

Python 变量 计数器 循环 enumerate

恒拓高科WorkPlus助力南兴装备移动数字化升级

BeeWorks

前端开发:npm run serve和npm run dev的区别

三掌柜

28天写作 21天挑战 12月日更

Java 程序员必须掌握的 10 款开源工具

编程江湖

java编程 java开发工具

双 11 大促会场开发提效解析:前端智能化落地实践

凹凸实验室

机器学习 大前端 智能代码

MySQL性能测试之select&update【FunTester框架】

FunTester

MySQL 性能测试 测试框架 FunTester FunTester框架

浅谈服务网关和联邦云

星环科技

联邦云 服务网关

全链路数据血缘在满帮的实践

华为云开发者联盟

sql 图数据库 图计算 全链路数据血缘 数据血缘

大厂面试算法题之数组

程序员学长

数据结构 算法 大厂面试

一文读懂 Apache Pulsar

晓双

云原生 Apache Pulsar 消息系统 数据流 Apache Pulsar 社区

Flutter 自定义 ACEFoldTextView 折叠文本

阿策小和尚

28天写作 0 基础学习 Flutter 内容合集 签约计划第二季 12月日更

为啥你写的代码老有大串的if/else?

华为云开发者联盟

代码 if for循环 else

高并发多方案秒杀架构

MetaThoughts

【干货分享】研效优化实践:AI算法助力深层BUG挖掘

WeTest

前端性能优化 24 条建议

编程江湖

大前端

10年经验总结,华为fellow教你如何成为一名优秀的架构师?

华为云开发者联盟

架构设计 架构师 华为fellow 云服务运维

Go语言学习查缺补漏ing Day7

恒生LIGHT云社区

golang Go 语言 编程语言‘

安全办公 |企业级IM即时通讯私有云解决方案

BeeWorks

从 0-15 套存储集群,YRCloudFile 助力 AI 训练效率“超线性增长”

焱融科技

人工智能 云计算 分布式 高性能 文件存储

从0到1教你如何使用 p5.js 绘制简单的动画

海拥(haiyong.site)

大前端 动画 28天写作 签约计划第二季 12月日更

科创人·StreamNative翟佳:开源模式价值为王,基础软件的未来在国内社区

科创人

Three.js - 走进3D的奇妙世界(下)_行业深度_刘琳_InfoQ精选文章