外观
变换与矩阵
3D 变换是计算机图形学的核心数学基础,它通过矩阵运算实现对物体的移动、旋转、缩放等操作。在 Web 3D 开发中,理解变换矩阵的原理和应用对于创建动态、交互式的 3D 场景至关重要。
变换基础
3D 变换是通过数学运算改变物体位置、方向和大小的过程。矩阵作为线性代数的工具,为这些变换提供了统一而高效的表示方法。
特点:
- 使用 4×4 齐次坐标矩阵表示所有变换
- 支持变换的组合和逆运算
- 硬件加速优化,适合实时渲染
示意图 (基本变换类型):
平移:移动位置
O → O
/ \ / \
| |
旋转:改变方向
↑ → →
/ \ / \
| |
缩放:改变大小
O → BIG O
/ \ / \
| |齐次坐标
齐次坐标使用四个分量 (x,y,z,w) 表示三维空间中的点,其中 w 分量用于区分点和向量,并支持透视变换。
特点:
- 点表示为 (x,y,z,1),向量表示为 (x,y,z,0)
- 统一处理仿射变换和投影变换
- w 分量支持透视除法
示意图 (齐次坐标转换):
3D 点: (x, y, z) → 齐次坐标: (x, y, z, 1)
3D 向量:(x, y, z) → 齐次坐标: (x, y, z, 0)
透视除法: (x, y, z, w) → (x/w, y/w, z/w)平移变换
平移变换改变物体的位置,在三维空间中沿 X、Y、Z 轴移动。平移矩阵是一个单位矩阵加上位移分量。
特点:
- 保持物体形状和方向不变
- 可逆操作,逆矩阵为反向平移
- 与其他变换可交换顺序
平移矩阵:
[ 1 0 0 Tx ]
[ 0 1 0 Ty ]
[ 0 0 1 Tz ]
[ 0 0 0 1 ]示意图 (沿 X 轴平移):
平移前: 平移后:
Y Y
| |
| |
[] []
| |
--+-- X --+-- X旋转变换
旋转变换改变物体的方向,围绕特定轴旋转指定角度。每个坐标轴都有对应的旋转矩阵。
特点:
- 保持物体形状和大小不变
- 旋转顺序影响最终结果 (不可交换)
- 使用弧度制表示角度
X 轴旋转矩阵:
[ 1 0 0 0 ]
[ 0 cosθ -sinθ 0 ]
[ 0 sinθ cosθ 0 ]
[ 0 0 0 1 ]Y 轴旋转矩阵:
[ cosθ 0 sinθ 0 ]
[ 0 1 0 0 ]
[-sinθ 0 cosθ 0 ]
[ 0 0 0 1 ]Z 轴旋转矩阵:
[ cosθ -sinθ 0 0 ]
[ sinθ cosθ 0 0 ]
[ 0 0 1 0 ]
[ 0 0 0 1 ]示意图 (绕 Z 轴旋转):
旋转前: 旋转后:
↑ ↗
/ \ / \
| |缩放变换
缩放变换改变物体的大小,可以沿各轴均匀或非均匀缩放。缩放矩阵是对角矩阵,对角线元素为缩放因子。
特点:
- 可以统一缩放或非均匀缩放
- 缩放因子为负值时产生镜像效果
- 零缩放因子会使物体坍缩
缩放矩阵:
[ Sx 0 0 0 ]
[ 0 Sy 0 0 ]
[ 0 0 Sz 0 ]
[ 0 0 0 1 ]示意图 (Y 轴缩放):
原始大小: Y轴放大:
O O
/|\ /|\
| |
| |
| |
|组合变换
多个变换可以通过矩阵乘法组合成单个变换矩阵。变换顺序很重要,因为矩阵乘法不满足交换律。
特点:
- 从右到左应用变换:M = T × R × S
- 预计算组合矩阵提高性能
- 支持复杂的动画和层次变换
变换顺序示意图:
局部坐标 → 缩放 → 旋转 → 平移 → 世界坐标
S R T
↓ ↓ ↓
[局部到世界矩阵] = T × R × S矩阵乘法示意图:
[T] × [R] × [S] × [顶点] = [变换后的顶点]
注意:从右向左应用
S 先应用,然后是 R,最后是 T模型矩阵
模型矩阵将物体从局部坐标系变换到世界坐标系,是平移、旋转、缩放变换的组合。
特点:
- 定义物体在世界空间中的位置和方向
- 每个物体有自己独立的模型矩阵
- 支持层次化变换 (父子关系)
示意图 (模型变换流程):
局部坐标系 → 模型矩阵 → 世界坐标系
O O
/|\ /|\
| |
↑
在世界位置视图矩阵
视图矩阵 (观察矩阵) 将世界坐标系变换到视图坐标系,以相机为参考点。视图矩阵是相机变换的逆矩阵。
特点:
- 相机位于原点,看向 Z 轴负方向
- 支持相机移动和旋转
- 便于后续的投影计算
视图矩阵构造:
[ Rx Ry Rz -dot(R, position) ]
[ Ux Uy Uz -dot(U, position) ]
[ Dx Dy Dz -dot(D, position) ]
[ 0 0 0 1 ]
其中 R, U, D 为相机的右、上、前向量示意图 (视图变换):
世界坐标系: 视图坐标系:
Y Y
| |
| C | Z(观察方向)
| / | /
| / | /
+--- X +--- X
相机 C 在世界中 相机在原点投影矩阵
投影矩阵将视图坐标系变换到裁剪坐标系,主要分为透视投影和正交投影两种类型。
透视投影
透视投影模拟人眼视觉效果,产生近大远小的透视效果。
特点:
- 创建深度感和真实感
- 视锥体为平头锥体
- 适合大多数 3D 应用场景
透视投影矩阵:
[ 2n/(r-l) 0 (r+l)/(r-l) 0 ]
[ 0 2n/(t-b) (t+b)/(t-b) 0 ]
[ 0 0 -(f+n)/(f-n) -2fn/(f-n)]
[ 0 0 -1 0 ]示意图 (透视投影):
眼睛
/ \
/ \ 视锥体
/ \
/ \
--------- 近平面
\ /
\ / 远平面
\ /
\ /正交投影
正交投影保持物体大小不变,无视距离影响,常用于工程绘图和 2.5D 游戏。
特点:
- 平行投影,无透视变形
- 视锥体为长方体
- 保持测量精度
正交投影矩阵:
[ 2/(r-l) 0 0 -(r+l)/(r-l) ]
[ 0 2/(t-b) 0 -(t+b)/(t-b) ]
[ 0 0 -2/(f-n) -(f+n)/(f-n)]
[ 0 0 0 1 ]示意图 (正交投影):
视锥体:
+-------+
| |
| | → 平行投影
| |
+-------+法线变换
变换物体时,法线向量需要特殊处理。法线变换矩阵是模型矩阵的逆转置矩阵,以保持法线与表面的垂直关系。
特点:
- 保持法线与表面的垂直性
- 使用模型矩阵的逆转置矩阵
- 对于只包含旋转的变换,可直接使用模型矩阵
法线变换矩阵:
法线变换矩阵 = transpose(inverse(Model矩阵))示意图 (法线变换):
变换前: 变换后:
↑ ↗
/ \ / \
表面 → 法线 表面 → 法线
⊥ ⊥矩阵栈与层次变换
复杂场景中,物体通常以层次结构组织。矩阵栈管理父子关系的组合变换。
特点:
- 支持骨骼动画和场景图
- 通过 push/pop 操作管理变换状态
- 提高复杂场景的变换效率
示意图 (矩阵栈操作):
push() | 当前矩阵 | push() | 父矩阵 |
当前矩阵 → |----------| → 应用变换 → |--------|
| | |子矩阵 |
pop() ← ... ← ← ... ← ... ←WebGL 中的矩阵实现
在 WebGL 和 Three.js 中,矩阵操作通过 JavaScript 库实现,如 glMatrix 或 Three.js 的 Matrix4 类。
特点:
- 使用 Float32Array 优化性能
- 提供矩阵运算的实用函数
- 与 GPU 着色器紧密集成
示例代码结构:
javascript
// 创建模型矩阵
const modelMatrix = mat4.create();
mat4.translate(modelMatrix, modelMatrix, [x, y, z]);
mat4.rotateY(modelMatrix, modelMatrix, angle);
mat4.scale(modelMatrix, modelMatrix, [sx, sy, sz]);
// 传递给着色器
gl.uniformMatrix4fv(modelMatrixLocation, false, modelMatrix);