three.js 学习笔记

最近看到 Blender 发布了 3.0,又重新燃起了对 3D 的兴趣,再一次开始学习 three.js,发现 three.js 的官方文档也有了很大的改进,对各种概念有了一种豁然开朗的感觉。

基础概念

three.js 是一个渲染引擎,它负责把输入的数据渲染成 2D 的画面,最终显示出来。我们用得最多的应该是 WebGLRenderer,它通过 WebGL 把数据渲染到 WebGL Canvas 上。

输入数据包括以下几类:

  • 相机
  • 物体
  • 灯光

这些数据结合到一起组成一个树状结构,也就是 three.js 中的 scene,他们决定了最终投影到屏幕上的画面是什么样子。其中相机比较特殊,它也可以独立于 scene 而存在,这里不做深究。

接下来我们一个个地看这些数据有什么作用,以及是如何相互影响的。

相机

3D 的世界我觉得就是对真实世界的一个模拟,相机模拟的就是我们的眼睛。不管其他数据是怎么样,只有相机覆盖的范围内的数据才是真实有效的,才会被我们看到。为了有真实世界中的透视效果,我们用得最多的是 PerspectiveCamera,它规定了视角、长宽比、方向等因素,使得我们能得到一个金字塔区域的长方形投影。

物体

物体是可以有层级关系的,比如一个茶杯放到了一个桌子上,那么桌子移动的时候,茶杯自然也会跟着移动,我们只需要关心茶杯相对于桌子的位置,而不用再去关心这个茶杯在世界中的绝对位置。

每一个物体本身又关联两种数据:形状和材质。

形状决定了一个物体占据的空间。在 3D 的世界里就是一系列的点组成线条,然后组成面,最后封闭起来,就成为了一个物体的轮廓,或者说形状。在 three.js 中,形状对应了 Geometry,存储了一系列的节点坐标。

材质决定了一个物体看起来是什么样子,比如颜色、是否反光,在什么颜色的光照下会显示出什么颜色。

由于形状和材质都只是对物体的属性的描述,所以他们可以被不同的物体共用,也就是说,多个物体可以享有相同的形状和材质。

灯光

灯光实际上是一种特殊的物体,它也存在于 scene 的树状结构中,只不过它可以发出光线,照射到其他物体上,并让其他物体根据其材质显示出不同的颜色。有了灯光,才能有明暗、有阴影,让各个物体显示出现实中的立体效果。当然我们也可以不用灯光,让物体显示出他们本来的色彩,但是这种效果更适合卡通的场景,与现实还是会有明显的差别。常见的一种模拟现实的灯光是 DirectionalLight,就是沿指定方向的平行光。

使用

由于强大的 three.js 已经对各种概念进行了封装,我们只需要把各种数据分别创建好,然后塞给 Renderer,一次 3D 渲染就完成了。比如下面就是参照官方文档画的一个立方体:


© 2022