写点什么

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

评论

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

Flutter流畅度优化神器-开源组件keframe详解

贝壳大前端技术团队

flutter 性能 滑动优化

斗罗大陆真3D手游实力上线,带你感受魂兽猎杀的超燃时刻

华为云开发者联盟

数据库 华为云数据库 rds for mysql 3D手游 PITR

工业企业能耗在线监测系统开发建设

a13823115807

你怎么总是能写出两三千行的controller类?

CRMEB

Aeron 是如何实现的?—— Ipc 异常情况处理

BUG侦探

Aeron ipc

CODING x 百果园,水果零售龙头迈出 DevOps 体系建设第一步

CODING DevOps

DevOps CODING 百果园 合作

行云管家荣获第二届国际科创节“2021年度高成长性企业奖”!

行云管家

云计算 混合云 IT运维

Flutter for Web 在贝壳容灾降级中的应用

贝壳大前端技术团队

flutter 容灾 降级 flutter for web

你想知道的Kotlin version

Changing Lin

12月日更

元宇宙时代的业务、场景、技术机遇探索

融云 RongCloud

架构设计之MQ选型

无心水

RocketMQ MQ RabbitMQ Kakfa Activemq

潮玩盲盒系统开发元气部落盲盒app开发

风行无疆

前端需要的免费在线api接口

德育处主任

JavaScript ajax 前端 Postman API

重磅!中国红十字基金会固生堂中医惠民专项基金成立

E科讯

声网把七年无全网事故的实时传输网络SD-RTN全面开放了——这就是FPA!

声网

人工智能 网络 SD-RTN

CSS之选择器(六)::before和::after

Augus

CSS 12月日更

2021年12月国产数据库排行榜: openGauss节节攀升拿下榜眼,GaussDB与TDSQL你争我夺各进一位

墨天轮

数据库 opengauss TiDB 国产数据库

解决远程办公安全隐患,就用行云管家!

行云管家

远程办公 IT运维

【修复升级】腾讯容器安全首个发布开源 Log4j2 漏洞缓解工具

腾讯安全云鼎实验室

记录一次win10更新版本后IIS无法启动的解决办法

为自己带盐

28天写作 12月日更

融云直播 SDK 2.0 重磅上线,两步接入即可获得视频直播能力

融云 RongCloud

依赖 jar 没有传递,导致找不到类文件而启动失败了

程序员小航

Java maven

微服务架构 | 如何利用好日志链路追踪做性能分析?

李尚智

Java 链路追踪 微服务治理 性能调试 微服务调用链

人工成本上升+设备停机率高,制造企业该如何破而后立?

优秀

低代码 制造业

可视化神器背后的奥秘

百度开发者中心

大数据 百度开发者沙龙

【HZERO微服务平台6】源码分析之数据权限、sql拦截

qiaoxingxing

签约计划第二季

进程ID及进程间的关系

mazhen

Linux Shell Linux Kenel

基于融云直播 SDK,快速实现连麦布局

融云 RongCloud

【软件开发】直播带货App如何开发

青山一叶秋

iOS内卷面试题-你以为你够卷了,面试官更卷!

iOSer

ios 内卷 iOS面试

一张图看懂融云直播 SDK

融云 RongCloud

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