# THREE.Clock

时间对象用于跟踪时间,用于计算每一帧的渲染时间或者是从开始渲染到现在的时间。

# 构造函数

var clock = new THREE.Clock();

实例化时间对象还可以接收一个布尔类型的参数,用于设置实例化完成后启动时间对象计时,默认为开启。

# 方法

# .start()

此方法用于启动时间对象开始计时,将所有的信息重置。

# .stop()

停止时间对象的计时。

# .getElapsedTime()

此方法返回自时间对象开启以后到现在的时间。

# .getDelta()

此方法返回上次调用到这次调用此方法的间隔时间,用于计算渲染间隔。

# THREE.Color

此类为代表颜色的类,在使用到颜色的地方,都可以配置的此类的实例化对象。如:材质的颜色对象,场景的背景设置颜色。

# 构造函数

我们可以通过 new THREE.Color() 来传入一个值来初始化一个颜色对象:

// 不传参数将默认渲染成白色
var color = new THREE.Color();
// 十六进制颜色(推荐)
var color = new THREE.Color( 0xff0000 );
//RGB 字符串
var color = new THREE.Color("rgb(255, 0, 0)");
var color = new THREE.Color("rgb(100%, 0%, 0%)");
// 支持所有 140 个颜色名称
var color = new THREE.Color( 'skyblue' );
//HSL 字符串
var color = new THREE.Color("hsl(0, 100%, 50%)");
// 支持区间为从 0 到 1 的 RGB 数值
var color = new THREE.Color( 1, 0, 0 );

# 方法

# .clone()

返回一个相同颜色的颜色对象。

# .add()

将一个颜色对象的颜色值和此颜色对象的颜色相加。

# .multiply()

将一个颜色对象的颜色值和此颜色对象的颜色相乘。

# .set()

重新设置颜色对象的颜色,支持实例化时的所有方式。

# 矢量对象

矢量是 GLSL ES 语言内的标准数据类型,也就是 webgl 原生着色器的语言的数据类型。而 Three.js 为了方便和原生融合,内置了 THREE.Vector2THREE.Vector3THREE.Vector4 三种矢量,分别代表二维向量,三维向量,四维向量。

# 二维矢量

二维矢量一般表示二维平面上的点的位置和方向。
下面是生成了一个普通的二维矢量

var a = new THREE.Vector2( 0, 1 );

我们也可以通过 set() 方法,重新修改二维矢量的值:

a.set(2, 3);

# 三维矢量

三维矢量在项目当中我们会经常用到,比如模型的位置属性、缩放属性,都是一个三维矢量。它是有三个有序的数字组成的。
使用三维矢量我们可以表示:

  1. 三维空间中一个点的位置
  2. 三维空间中两点的方向和长度
  3. 任意有序的三个数字

例子:

// 创建一个普通的三维矢量
var a = new THREE.Vector3( 0, 1, 0 );
// 默认空值,将会重置为 (0, 0, 0)
var b = new THREE.Vector3( );
//d 矢量是从 a 点到 b 点的方向和长度
var d = a.distanceTo( b );

我们经常用到的修改模型的位置,修改模型的缩放,其实都是修改三维矢量的值:

// 创建一个三维矢量
var vec = new THREE.Vector3(0, 1, 0);
// 修改模型的位置
mesh.position = vec;
// 修改三维矢量的值
vec.set(1, 2, 1);
// 修改模型的缩放值
mesh.scale.set(2, 2, 2);

我们还可以修改三维向量的单个值:

vec.setComponent(0, 20); // 将三维向量的第一值修改为 20
.setComponent(index, value); 
//index 修改的单个值的下标,可选值为 0 1 2 对应 vec.x vec.y vec.z
//value 修改成的数字

# 四维矢量

四维矢量是由四个数字组成的数据类型,四个值分别代表 x,y,z,w。
思维矢量可以表示的内容:

  1. 思维空间内的一个点
  2. 思维空间里的方向和长度
  3. 任意有序的四个数字

例子:

// 创建一个普通的四维矢量
var a = new THREE.Vector4( 0, 1, 0, 0 );
// 如果不设置参数,默认值为 (0, 0, 0, 1)
var b = new THREE.Vector4( );

# 四维矩阵

矩阵是高等代数学中的常见工具,也常见于统计分析等应用数学学科中。 Three.js 给我们封装了三维矩阵(3x3)四维矩阵(4x4)。有关 WebGL 中使用的矩阵的介绍请前往 OpenGL 基础进行学习。

由于篇幅有限,这里对三维矩阵不作介绍,我们下面主要介绍四维矩阵。

在 3D 计算机图形中最常见的四维矩阵用作转换矩阵。这代表着三维空间中的点 Vector3 通过乘以转换矩阵来实现如平移,旋转,剪切,缩放,发射,正交或透视投影等变化。

在每个 3d 对象中都有三个四维矩阵:

  • Object3D.matrix:存储 3d 对象的局部变换。这是 3d 对象相对于父对象的转换。
  • Object3D.matrixWorld:3d 对象的全局或世界变换。如果 3d 对象没有父对象,则当前矩阵和其局部变换矩阵相同。
  • Object3D.modelViewMatrix:这个表示 3d 对象相对于摄像机的坐标转换。对象的 modelViewMatrix 是对象的 matrixWorld 再乘以相机的 matrixWorldInverse 获得的结果。

相机对象不但含有 3d 对象的四维矩阵,还额外拥有两个:

  • Camera.matrixWorldInverse:视图矩阵(相机的 matrixWorld 的反转后的四维矩阵)
  • Camera.projectionMatrix:表示场景内的模型如何转换到二维显示区域的变换矩阵。

如果你对矩阵的实现原理感兴趣的话,请转到这里来查看:点击这里,这里不再过多解释原理。

接下来我们查看一下 Three.js 封装的四维变换矩阵有什么方法供我们使用:

var m = new THREE.Matrix4();
// 我们可以通过手动设置每一项的数值来生成变换矩阵
m.set( 11, 12, 13, 14,
       21, 22, 23, 24,
       31, 32, 33, 34,
       41, 42, 43, 44 );
// 创建一个矢量,并应用此变换矩阵
var v = new THREE.Vector3();
v.applyMatrix4(m); // 应用变换矩阵

上面是创建了一个默认的四维矩阵,三维矢量乘以默认的四维矩阵将不会产生变化。

我们可以使用 .identity() 方法来重置变换矩阵:

var m = new THREE.Matrix4();
m.identity(); // 重置矩阵恢复默认

我们可以通过 .lookAt() 并传入一个三个矢量生成一个旋转矩阵。这三个矢量分别代表眼的位置,查看的物体的位置,向上的方向:

var m = new THREE.Matrix4();
m.lookAt(eye, center, up); // 生成旋转变换矩阵

我们也可以通过旋转的弧度来生成旋转变换矩阵:

var m = new THREE.Matrix4();
// 通过绕 x 轴旋转生成变换矩阵
m.makeRotationX(Math.PI/2); // 绕 x 轴旋转 90 度变换矩阵
m.makeRotationAxis(new THREE.Vector3(1, 0, 0), Math.PI/2); // 效果同上
// 通过绕 y 轴旋转生成变换矩阵
m.makeRotationY(Math.PI); // 绕 y 轴旋转 180 度变换矩阵
m.makeRotationAxis(new THREE.Vector3(0, 1, 0), Math.PI); // 效果同上
// 通过绕 z 轴旋转生成变换矩阵
m.makeRotationZ(Math.PI/4); // 绕 z 轴旋转 45 度变换矩阵
m.makeRotationAxis(new THREE.Vector3(0, 0, 1), Math.PI/4); // 效果同上

通过设置缩放来生成缩放变换矩阵:

var m = new THREE.Matrix4();
m.makeScale(1, 2, 5); // 生成沿 x 轴不变,y 轴放大两倍,z 轴放大五倍的缩放变换矩阵

通过设置位置平移来生成变换矩阵:

var m = new THREE.Matrix4();
m.makeTranslation(10, -20, 100); // 生成沿 x 正轴偏移 10,y 负轴偏移 20,z 正轴偏移 100 的平移变换矩阵

# 欧拉角

欧拉角通过在每个轴指定旋转的弧度和指定旋转轴的先后顺序来进行旋转变换。之前在介绍场景时候带了一下,这里再做一下介绍,每个 3d 对象的 rotation 属性都是一个欧拉角对象。

创建欧拉角:

var e = new THREE.Euler( 0, 1, 1.57, 'XYZ' );

前三个值分别代表每个轴上旋转的弧度,第四个值是应用旋转的顺序。默认为’XYZ’,这意味着对象将首先围绕其 X 轴旋转,然后围绕其 Y 轴旋转,最后围绕其 Z 轴旋转。其他可能性有:‘YZX’,‘ZXY’,‘XZY’,‘YXZ’和’ZYX’。这些必须是大写的。

修改欧拉角:

// 通过 set 方法重新设置
var e = new THREE.Euler();
e.set(Math.PI, 0, - Math.PI / 2, "YZX"); // 先沿 y 轴旋转 180 度,再沿 z 轴旋转 0 度,最后沿 x 轴逆时针旋转 90 度,第四个值可以不填,默认是 "XYZ"

我们也可以通过变换矩阵来修改当前的欧拉角:

var e = new THREE.Euler( 0, 1, 1.57, 'XYZ' );
var m = new THREE.Matrix4();
e.setFromRotationMatrix(m); // 在当前的旋转角度,再进行矩阵变换