引子
在 JavaScript WebGL 矩阵之后,发现在实现三维效果之前还有一些概念需要理解,就去查了下资料,按照自己的习惯整合了一下。
齐次坐标
三维坐标理论上三个分量就够了,但在看相关程序的时候,发现会出现 4 个分量,这种表示方式称为齐次坐标,它将一个原本 n 维向量用一个 n+1 维向量表示。比如向量 (x, y, z) 的齐次坐标可表示为 (x, y, z, w)。这样表示有利于使用矩阵运算将一个点集从一个坐标系转换到另一个坐标系。齐次坐标 (x, y, z, w) 等价于三维坐标 (x/w, y/w, z/w) 。更详细介绍见这里。
空间转换
WeGL 没有现成 API 可以直接绘制出三维效果,需要进行一系列空间转换,最终在二维空间(比如电脑屏幕)显示,从视觉上看上去是三维立体效果。下面看看几个主要转换过程。
模型空间
模型空间是描述三维物体自身的空间,拥有自己的坐标系和对应原点。这里点坐标可以按照 WebGL 中可见范围 [-1, +1] 约束进行描述,也可以不按照这个约束。自定义描述规则后面需要转换一下。
世界空间
物体模型创建好后,放在具体环境当中,才会达到想要的效果,除此之外,还可能会进行位移、缩放和旋转,进行这些变化都需要一个新参考坐标系,这个所处环境就是世界空间。有了世界坐标系,相互独立的物体才会有相对位置的描述。
从模型空间转换到世界空间,需要用到模型矩阵(Model Matrix)。
三维模型矩阵跟 JavaScript WebGL 矩阵中介绍的二维变换矩阵类似,主要变化是行列增加和旋转。
点击展开代码
const m4 = {
translation: (x, y, z) => {
return [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
x, y, z, 1,
];
},
// 缩放矩阵
scaling: (x, y, z) => {
return [
x, 0, 0, 0,
0, y, 0, 0,
0, 0, z, 0,
0, 0, 0, 1,
];
},
// 旋转矩阵
xRotation: (angle) => {
const c = Math.cos(angle);
const s = Math.sin(angle);
return [
1, 0, 0, 0,
0, c, s, 0,
0, -s, c, 0,
0