# 历史

之前的三维程序都是运行在 OpenGL 和微软公司的 DirectX 上的,PC 端大型游戏都是在此基础上开发的。随着移动技术的发展,手机上有了许多使用三维程序的场景,所以 OpenGL 标准委员会就在之前的 OpenGL 基础上开发了一个缩减版的 OpenGL 叫做 OpenGL ES,目前智能手机操作系统都是基于 OpenGL ES 来开发三维程序的。

同时为了能在浏览器上运行三维程序,就在 OpenGL ES 2.0 的基础上开发出了 WebGL 标准,把 JavaScript 和 OpenGL ES 2.0 绑定起来。WebGL 可以为 HTML5-Canvas 提供硬件 3D 加速渲染,这样 Web 开发人员就可以借助系统显卡来在浏览器里更流畅的展示 3D 场景和模型了。

WebGL 的功能很强大,但是还是偏底层,开发时非常复杂且容易出错,Three.js 就是把 WebGL 包装了一层,可以让我们方便快速的实现常见功能。

Three.js 常见功能:

  • 创建简单和复杂的三维几何图像
  • 在三维场景下创建和移动物体
  • 为物体添加纹理和材质
  • 使用各种光源来装饰场景
  • 加载三维软件所创建的模型
  • 使用自定义的着色器
  • 创建虚拟现实 (VR) 和增强现实 (AR) 场景
  • 为三维场景添加高级的后期处理效果
  • 创建点云(粒子系统)

Three.js 优缺点:

  • Three.js 擅长 WebGL 场景渲染,作为 JS 类库特别原生、灵活、自由度高。
  • Three.js 不擅长物理碰撞,因此不适合开发 3D 游戏。

# Canvas 元素

todo

https://stackoverflow.com/questions/15558418/how-do-you-save-an-image-from-a-three-js-canvas

# 核心知识分类

使用 Three.js 开发 3D 程序需要两方面的核心知识:

  • 3D 美术知识:相机、光源、mesh、geomerty、material 等等,这些知识不止在 3D 程序中会用到,建模等场景也会使用,基础美术能力决定了你对 3D 的了解。计算机图形学也是用的这一套,可能会加入一些数学方面的知识。
  • JS 编程能力:知道如何使用 JS 进行面向对象编程,构建程序的时候,如何做到清晰的模块化,代码该如何组织,数据和视图如何绑定等等。

# 技术关键词

# 场景 (Scene)

场景能够让你在什么地方、摆放什么东西来交给 three.js 来渲染,这是你放置物体、灯光和摄像机的地方。

# 相机 (Camera)

场景中的相机,代替人眼去观察,场景中只能添加一个。

three.js 中常用的相机有两种,透视相机和正交相机:

透视相机 (PerspectiveCamera)

模拟人眼,近大远小,更适合 3D 渲染;

我们在创建透视相机的时候,需要定义一个视锥 (Frustum),随后在渲染的时候,计算机会将视锥中的所有三维物体投影到我们的二维屏幕上。

正交相机 (OrthographicCamera)

物体尺寸与镜头远近无关,主要被应用在 CAD 等这种需要精确测量物体尺寸的应用场景中;

正交相机的视锥是一个长方体:

# 物体对象

包括二维物体(点、线、面)、三维物体,模型等等。

在计算机的世界里,一条弧线是由有限个点构成的有限条线段连接得到的。当线段数量越多,长度就越短,当达到你无法察觉这是线段时,一条平滑的弧线就出现了。 计算机的三维模型也是类似的。只不过线段变成了平面,空间中确定一个平面最少需要三个点,所以普遍用三角形组成的网格来描述。我们把这种模型称之为网格 (Mesh) 模型

计算机图形学中著名的斯坦福兔子

网格 (Mesh)

在 three.js 中,Mesh = 几何体 (Geometry) + 材质 (Material) 。

网格包含的内容为:几何体、几何体的材质、几何体的自身网格坐标体系。

同一个材质和几何体可以被多个网格对象使用。

一个场景可以同时添加多个网格。

几何体 (Geometry)

顾名思义,几何体用来表现物体的形状。例如 球体、立方体、平面、以及自定义的几何体(汽车、动物、房子、数目等)。

在 Three.js 中,一个几何体的来源有 3 个:

  • Three.js 中内置的一些基本几何体
  • 自己创建自定义的几何体
  • 通过文件加载进来的几何体

three.js 中内置了许多基本的几何图元 (Primitives),命名全部以Geometry结尾,我们可以使用这些图元快速创建常见的 Geometry:

名称 类型
BoxGeometry 立方体
CircleGeometry 圆形
ConeGeometry 圆锥体
CylinderGeometry 圆柱体
SphereGeometry 球体
TetrahedronGeometry 四面体
TorusGeometry 圆环体

材质 (Material)

Material 代表三维物体的材质,材质表示的是物体对光照的反应,表示除了形状以外所有可视属性的集合,例如色彩、纹理、光滑度、透明度、反射率、折射率、发光度等。

同样的,three.js 中内置了一些常用的材质函数:

名称 类型
PointsMaterial
LineBasicMaterial 实线
LineDashedMaterial 虚线
MeshBasicMaterial 基础网格(不反射光,显示材质本身的颜色)
MeshPhongMaterial Phong 网格(镜面高光)
MeshLambertMaterial Lambert 网格(非镜面高光)
MeshStandardMaterial 标准物理网格(逼真,耗性能)
MeshPhysicalMaterial 物理网格(逼真,耗性能)
MeshToonMaterial 卡通效果

纹理 (Texture)

纹理可以简单理解为一种图像或一张图片,用来包裹到几何体表面上。

纹理来源可以是:

  • 通过文件加载进来
  • 在画布上生成
  • 由另外一个场景渲染出

# 光源 (Light)

场景中的光照,如果不添加光照场景将会是一片漆黑。

名称 类型
AmbientLight 环境光
PointLight 点光源
SpotLight 聚光灯
DirectionalLight 平行光
HemisphereLight 自然光/半球光
RectAreaLight 平面光

# 渲染器 (Renderer)

场景的渲染方式,如 webGL\canvas2D\Css3D,webGL 最常用。

# 控制器 (Control)

可通过键盘、鼠标控制相机的移动。

# Three.js 中的其他功能

# 加载外部模型

除了自建立方体之外,我们还可以加载外部模型,比如 C4D、3DMax 等创建好的复杂模型。

加载外部模型,是通过 Three.js 加载器 (Loader) 实现的,每个加载器对应某种特定的文件格式。加载器把文本/二进制的模型文件转化为 Three.js 对象结构。

# 动画

todo

# 粒子

todo

# 参考

上次更新: 8/12/2022, 6:10:27 PM