在 OpenGL 的渲染管线中,模型视图矩阵 和 投影矩阵 是把 3D 物体画到屏幕上的两次关键坐标变换。下面用"相机拍照"的类比来理解,再配合现代 OpenGL + GLM 的代码。
一、模型视图矩阵(Model‑View Matrix)
它其实是两步变换的合并:
| 阶段 | 作用 | 类比 |
|---|---|---|
| 模型矩阵 (Model) | 把物体从自身坐标系 变换到世界坐标系(摆放位置、旋转、缩放) | 把桌上的苹果放到房间的正确位置 |
| 视图矩阵 (View) | 把世界坐标变换到摄像机(观察)坐标系(相当于把整个场景反向移动,让相机位于原点看向 -Z) | 你举起相机,对准那个苹果 |
现代实践中通常分开写,在顶点着色器里做 projection * view * model 乘法,但 view * model 的结果就是模型视图矩阵,表示从模型局部空间一步到视图空间。
二、投影矩阵(Projection Matrix)
投影矩阵将视图空间 的坐标变换到裁剪空间,并定义"什么形状的范围能被看到"。
| 类型 | 效果 | 生成函数(GLM) |
|---|---|---|
| 透视投影 | 近大远小,有消失点,符合真实视觉 | glm::perspective(fov, aspect, near, far) |
| 正交投影 | 没有近大远小,常用于 2D、UI 或 CAD | glm::ortho(left, right, bottom, top, near, far) |
投影矩阵输出的坐标是齐次坐标 (x, y, z, w),之后 GPU 会自动做 透视除法 (x/w, y/w, z/w) 得到标准化设备坐标。
三、完整变换流程(MVP 管线)
一个顶点从模型到屏幕的完整变换链为:
局部坐标 →(乘以 模型矩阵 M)→ 世界坐标
世界坐标 →(乘以 视图矩阵 V)→ 观察坐标
观察坐标 →(乘以 投影矩阵 P)→ 裁剪坐标
裁剪坐标 →(透视除法)→ 标准化设备坐标(NDC)
NDC →(视口变换)→ 屏幕像素坐标
整体公式:MVP = P × V × M,最终顶点变换为:gl_Position = MVP × vertex