写点什么

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

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

    阅读完需:约 10 分钟

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

本文将通过 Three.js 的介绍及示例带我们走进 3D 的奇妙世界。

文章来源:宜信技术学院 & 宜信支付结算团队技术分享第 6 期-支付结算部支付研发团队前端研发高级工程师-刘琳《three.js - 走进 3D 的奇妙世界》

分享者:宜信支付结算部支付研发团队前端研发高级工程师-刘琳


随着人们对用户体验越来越重视,Web 开发已经不满足于 2D 效果的实现,而把目标放到了更加炫酷的 3D 效果上。Three.js 是用于实现 web 端 3D 效果的 JS 库,它的出现让 3D 应用开发更简单,本文将通过 Three.js 的介绍及示例带我们走进 3D 的奇妙世界。

一、Three.js 相关概念

1.1 Three.JS

Three.JS 是基于 WebGL 的 Javascript 开源框架,简言之,就是能够实现 3D 效果的 JS 库。

1.2 WebGL

WebGL 是一种 Javascript 的 3D 图形接口,把 JavaScript 和 OpenGL ES 2.0 结合在一起。

1.3 OpenGL

OpenGL 是开放式图形标准,跨编程语言、跨平台,Javascript、Java 、C、C++ 、 python 等都能支持 OpenG ,OpenGL 的 Javascript 实现就是 WebGL,另外很多 CAD 制图软件都采用这种标准。OpenGL ES 2.0 是 OpenGL 的子集,针对手机、游戏主机等嵌入式设备而设计。

1.4 Canvas

Canvas 是 HTML5 的画布元素,在使用 Canvas 时,需要用到 Canvas 的上下文,可以用 2D 上下文绘制二维的图像,也可以使用 3D 上下文绘制三维的图像,其中 3D 上下文就是指 WebGL。


1574760602091095648.png

二、Three.js 应用场景

利用 Three.JS 可以制作出很多酷炫的 3D 动画,并且 Three.js 还可以通过鼠标、键盘、拖拽等事件形成交互,在页面上增加一些 3D 动画和 3D 交互可以产生更好的用户体验。


通过 Three.JS 可以实现全景视图,这些全景视图应用在房产、家装行业能够带来更直观的视觉体验。在电商行业利用 Three.JS 可以实现产品的 3D 效果,这样用户就可以 360 度全方位地观察商品了,给用户带来更好的购物体验。另外,使用 Three.JS 还可以制作类似微信跳一跳那样的小游戏。随着技术的发展、基础网络的建设,web3D 技术还能得到更广泛的应用。


1574761659639065918.png

三、主要组件

在 Three.js 中,有了场景(scene)、相机(camera)和渲染器(renderer) 这 3 个组建才能将物体渲染到网页中去。


1)场景


场景是一个容器,可以看做摄影的房间,在房间中可以布置背景、摆放拍摄的物品、添加灯光设备等。


2)相机


相机是用来拍摄的工具,通过控制相机的位置和方向可以获取不同角度的图像。


3)渲染器


渲染器利用场景和相机进行渲染,渲染过程好比摄影师拍摄图像,如果只渲染一次就是静态的图像,如果连续渲染就能得到动态的画面。在 JS 中可以使用 requestAnimationFrame 实现高效的连续渲染。

3.1 常用相机

1574761667808077881.png


1)透视相机


透视相机模拟的效果与人眼看到的景象最接近,在 3D 场景中也使用得最普遍,这种相机最大的特点就是近大远小,同样大小的物体离相机近的在画面上显得大,离相机远的物体在画面上显得小。透视相机的视锥体如上图左侧所示,从近端面到远端面构成的区域内的物体才能显示在图像上。


透视相机构造器


PerspectiveCamera( fov : Number, aspect : Number, near : Number, far : Number )


  • fov — 摄像机视锥体垂直视野角度

  • aspect — 摄像机视锥体长宽比

  • near — 摄像机视锥体近端面

  • far — 摄像机视锥体远端面


2)正交相机


使用正交相机时无论物体距离相机远或者近,在最终渲染的图片中物体的大小都保持不变。正交相机的视锥体如上图右侧所示,和透视相机一样,从近端面到远端面构成的区域内的物体才能显示在图像上。


正交相机构造器


OrthographicCamera( left : Number, right : Number, top : Number, bottom : Number, near : Number, far : Number )


  • left — 摄像机视锥体左侧面

  • right — 摄像机视锥体右侧面

  • top — 摄像机视锥体上侧面

  • bottom — 摄像机视锥体下侧面

  • near — 摄像机视锥体近端面

  • far — 摄像机视锥体远端面

3.2 坐标系

在场景中,可以放物品、相机、灯光,这些东西放置到什么位置就需要使用坐标系。Three.JS 使用右手坐标系,这源于 OpenGL 默认情况下,也是右手坐标系。从初中、高中到大学的课堂上,教材中所涉及的几何基本都是右手坐标系。


1574761676237007220.png


上图右侧就是右手坐标系,五指并拢手指放平,指尖指向 x 轴的正方向,然后把四个手指垂直弯曲大拇指分开,并拢的四指指向 y 轴的正方向,大拇指指向的就是 Z 轴的正方向。


在 Three.JS 中提供了坐标轴工具(THREE.AxesHelper),在场景中添加坐标轴后,画面会出现 3 条垂直相交的直线,红色表示 x 轴,绿色表示 y 轴,蓝色表示 z 轴(如下图所示)。


1574761682608065195.png

3.3 示例代码

/* 场景 */var scene = new THREE.Scene();scene.add(new THREE.AxesHelper(10)); // 添加坐标轴辅助线
/* 几何体 */// 这是自定义的创建几何体方法,如果创建几何体后续会介绍var kleinGeom = createKleinGeom(); scene.add(kleinGeom); // 场景中添加几何体
/* 相机 */var camera = new THREE.PerspectiveCamera(45, width/height, 1, 100);camera.position.set(5,10,25); // 设置相机的位置camera.lookAt(new THREE.Vector3(0, 0, 0)); // 相机看向原点
/* 渲染器 */var renderer = new THREE.WebGLRenderer({antialias:true});renderer.setSize(width, height);// 将canvas元素添加到bodydocument.body.appendChild(renderer.domElement);// 进行渲染renderer.render(scene, camera);
复制代码

四、几何体

计算机内的 3D 世界是由点组成,两个点能够组成一条直线,三个不在一条直线上的点就能够组成一个三角形面,无数三角形面就能够组成各种形状的几何体。


1574761690685071923.png


以创建一个简单的立方体为例,创建简单的立方体需要添加 8 个顶点和 12 个三角形的面,创建顶点时需要指定顶点在坐标系中的位置,添加面的时候需要指定构成面的三个顶点的序号,第一个添加的顶点序号为 0,第二个添加的顶点序号为 1…


创建立方体的代码如下:


var geometry = new THREE.Geometry();
// 添加8个顶点geometry.vertices.push(new THREE.Vector3(1, 1, 1));geometry.vertices.push(new THREE.Vector3(1, 1, -1));geometry.vertices.push(new THREE.Vector3(1, -1, 1));geometry.vertices.push(new THREE.Vector3(1, -1, -1));geometry.vertices.push(new THREE.Vector3(-1, 1, -1));geometry.vertices.push(new THREE.Vector3(-1, 1, 1));geometry.vertices.push(new THREE.Vector3(-1, -1, -1));geometry.vertices.push(new THREE.Vector3(-1, -1, 1));
// 添加12个三角形的面geometry.faces.push(new THREE.Face3(0, 2, 1));geometry.faces.push(new THREE.Face3(2, 3, 1));geometry.faces.push(new THREE.Face3(4, 6, 5));geometry.faces.push(new THREE.Face3(6, 7, 5));geometry.faces.push(new THREE.Face3(4, 5, 1));geometry.faces.push(new THREE.Face3(5, 0, 1));geometry.faces.push(new THREE.Face3(7, 6, 2));geometry.faces.push(new THREE.Face3(6, 3, 2));geometry.faces.push(new THREE.Face3(5, 7, 0));geometry.faces.push(new THREE.Face3(7, 2, 0));geometry.faces.push(new THREE.Face3(1, 3, 4));geometry.faces.push(new THREE.Face3(3, 6, 4));
复制代码

4.1 正面和反面

创建几何体的三角形面时,指定了构成面的三个顶点,如: new THREE.Face3(0, 2, 1),如果把顶点的顺序改成 0,1,2 会有区别吗?


通过下图可以看到,按照 0,2,1 添加顶点是顺时针方向的,而按 0,1,2 添加顶点则是逆时针方向的,通过添加顶点的方向就可以判断当前看到的面是正面还是反面,如果顶点是逆时针方向添加,当前看到的面是正面,如果顶点是顺时针方向添加,则当前面为反面。


下图所看到的面就是反面。如果不好记,可以使用右手沿顶点添加的方向握住,大拇指所在的面就是正面,很像我们上学时学的电磁感应定律。


1574761698095080964.png


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


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


2020-02-06 10:342857

评论

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

人工智能是下一个“新生代农民工”吗?

澳鹏Appen

人工智能 大数据 AI 数据标注 训练数据

平头哥剑池CDK 更新重磅来袭!三大亮点速看!

Roy夹馍

物联网 risc-v 嵌入式开发 软件模拟

ipfs最新官网通知?ipfs是一场技术革命?

区块链 分布式存储 IPFS Filecoin ipfs挖矿

2020年五面蚂蚁,分布式架构+RPC+kafka+多线程

欢喜学安卓

Java 程序员 后端

2021 Java开发 最全笔记 建议收藏!,搞定kafka看这一篇就够了

欢喜学安卓

Java 程序员 后端

30G上亿数据的超大文件,如何快速导入生产环境,全网疯传

Geek_f90455

Java 程序员 后端

6年拉力工作经验,学了阿里P8级架构师的7,Java笔试题库及答案

Geek_f90455

Java 程序员 后端

天津赛誉食品有限公司与小王庄黄金梨携手 助推文旅产业化联盟销售

InfoQ 天津

RVB2601开发板快速上手教程

Roy夹馍

MCU risc-v 嵌入式开发

数字人民币与智能合约

CECBC

百度智能云天工物联网支持多种类数据传输,MQTT助力数据、语音、视觉应用智能化

百度大脑

人工智能

35岁+程序员就该被辞退,kafka入门与实践百度云网盘

Geek_f90455

Java 程序员 后端

澳鹏Appen收购Quadrant:移动定位数据业务进一步增强

澳鹏Appen

人工智能 大数据 企业 收购

解析金融服务如何在区块链中建立信任?

CECBC

30岁程序员裸辞,真香定律

Geek_f90455

Java 程序员 后端

北鲲云超算平台在AlphaFold2对蛋白质研究中有何作用?

北鲲云

从芯片到云全链路高效设计 一文了解YoC基础软件平台

Roy夹馍

物联网 risc-v 嵌入式开发

Vector向量计算技术与SIMD技术的对比

Roy夹馍

cpu IoT 芯片 risc-v

有道词典 Flutter 架构与应用

有道技术团队

大前端 客户端 网易有道

服务网格在百度核心业务大规模落地实践

百度开发者中心

最佳实践 方法论 Service Mesh 服务网格

filecoin全网有效算力突破10EiB?Filecoin挖矿现在还有机会入场吗?

区块链 分布式存储 IPFS filecoin挖矿 filecoin矿机

财经大课:看懂价格信号

石云升

财经思维 9月日更

Paxos理论介绍(3): Master选举

OpenIM

springboot elementui vue商城微信小程序源码(毕设)

清风

小程序 Vue 毕业设计 毕设

低代码和无代码的区别

低代码小观

低代码 开发工具 无代码 低代码与无代码区别

1-7中HashMap死循环分析,透彻解析

欢喜学安卓

Java 程序员 后端

2021年1月8号,这些新技术你们都知道吗

欢喜学安卓

Java 程序员 后端

EMQ X VS RabbitMQ:两大消息服务器 MQTT 性能对比全解(上)

EMQ映云科技

RabbitMQ 物联网 IoT mqtt emq

RVB2601开发板用户指南

Roy夹馍

IoT risc-v 嵌入式开发

一款神器自助帮你换背景,超强实时人像扣图算法开源啦!

百度开发者中心

最佳实践 图像处理 开源技术

2020全网最新SQL优化面试专题及答案,一步搞定你疑惑的数据结构与算法系列

欢喜学安卓

Java 程序员 后端

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