写点什么

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:342165

评论

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

软件测试 | 测试开发 | 接口测试框架实战(一) | Requests 与接口请求构造

测吧(北京)科技有限公司

测试

软件测试 | 测试开发 | 测试人生 | 二线城市涨薪近10万 ,还能955,这样的机会你想不想要?

测吧(北京)科技有限公司

测试

多版本并发控制 MVCC

月明风清

Redis 的PSYNC命令

急需上岸的小谢

9月月更

PSYNC 部分重同步的原理

急需上岸的小谢

9月月更

软件测试 | 测试开发 | 测试人生 | 从功能到外企测开,工作1年半拿下年薪30万的测开 offer,这个95后小姐姐未来可期~

测吧(北京)科技有限公司

测试

软件测试 | 测试开发 | 测试人生 | 转行测试开发,4年4“跳”年薪涨3倍,我的目标是星辰大海(附大厂面经)!

测吧(北京)科技有限公司

测试

聚焦指标及管理,Kyligence 发布指标中台 SaaS 产品 Zen

Kyligence

数据分析 OLAP Kyligence 指标中台

羊了个羊暴力通关玩法

大熊G

MobLink iOS端快速集成文档

MobTech袤博科技

ios xcode

解析Stream foreach源码

华为云开发者联盟

Java 开发 企业号九月金秋榜

怎么合理使用索引

急需上岸的小谢

9月月更

字节跳动基于ClickHouse优化实践之“高可用”

字节跳动数据平台

数据库 大数据 Clickhouse 数据开发 数据计算

软件测试 | 测试开发 | 接口测试框架实战 | 流程封装与基于加密接口的测试用例设计

测吧(北京)科技有限公司

测试

软件测试 | 测试开发 | Jenkins 如何参数化job ?

测吧(北京)科技有限公司

测试

软件测试 | 测试开发 | 测试人生 | 毕业2年未满,0经验拿下知名互联网企业30W 年薪,他是怎么做到的?

测吧(北京)科技有限公司

软件测试 | 测试开发 | 测试人生 | 年薪超过40W,一位测试媛宝妈的 BAT 大厂逆袭之旅

测吧(北京)科技有限公司

测试

2022vivo“千镜杯”正式开赛,为守护用户安全而战!

极客天地

开源指南|如何从零开始参与 Apache 顶级开源项目?(二)

SelectDB

数据库 大数据 Doris 开源治理 企业号九月金秋榜

软件测试 | 测试开发 | 接口测试框架实战(二)| 接口请求断言

测吧(北京)科技有限公司

测试

从低代码的前世今生,看软件开发趋势

飞算JavaAI开发助手

MyBatis-Plus(一、快速入门)

MySQL Mybatis-Plus 9月月更

容器化|自建 MySQL 集群迁移到 Kubernetes

RadonDB

MySQL 数据库 RadonDB Kubernetes 集群

科技公司内部 SaaS 工具大公开|活动回顾(含视频 & PPT)

Bytebase

创业 工具 开发者工具 SaaS

软件测试 | 测试开发 | 测试人生 | 折腾 6 年踩坑无数的”笨小孩“:方向对了,路就不会遥远!

测吧(北京)科技有限公司

测试

金蝶云星空&契约锁专场直播:帮企业从小处降本,从细节增效!

IT资讯搬运工

金融

2022 DEMO CHINA创新中国峰会收官,5大专场创业者PK,投资人脱口秀别开生面

创业邦

恭喜 SelectDB 三位开发者成为 Apache Doris 新晋 Committer!

SelectDB

大数据 开源项目 Committer SelectDB 企业号九月金秋榜

EMR重磅发布智能运维诊断系统(EMR Doctor)——开源大数据平台运维利器

阿里云大数据AI技术

大数据 运维 企业号九月金秋榜 EMR

不懂 Kubernetes 实现云原生是什么体验?

北京好雨科技有限公司

云原生 #Kubernetes#

Nginx 模块开发

C++后台开发

nginx 后台开发 中间件 后端开发 Nginx模块开发

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