局部空间(Local Space)
模型自己的空间。顶点数据的原始坐标值(比如.obj文件里定义的顶点),是基于模型原点定义的。
- 目的:独立于场景定义模型本身的形状。
- 范围:无固定范围
世界空间(World Space)
所有物体共同存在的统一空间。世界坐标系定义了整个场景的原点(0,0,0)和方向。
- 变换 :可以通过 模型矩阵(Model Matrix) 将模型从局部空间转换到世界空间,这个矩阵负责模型的平移、旋转、缩放操作。将模型放置在场景的正确位置和姿态。
- 目的: 统一不同物体的空间参考系,确定物体间的位置关系。
- 变换公式 :
世界坐标 = ModelMatrix * Local坐标
观察空间(View Space)
以摄像机/眼睛为中心的坐标系!这是从摄像机的视角看到的场景。所有的物体坐标都被转换到摄像机作为坐标系原点的空间中。
- 变换 :通过观察矩阵 / 视图矩阵(View Matrix) 将场景原点移动到摄像机位置原点(平移),然后旋转场景使得摄像机视线指向目标方向。
- 这个矩阵定义了 摄像机的摆放位置
(eye)、朝向点(target)和 顶部朝向(up)。 - 等价于将摄像机从其"本地"空间移动到世界空间并朝向正确的操作取逆。
- 将世界坐标转换为观察坐标
- 这个矩阵定义了 摄像机的摆放位置
- 原点:摄像机的位置
- 坐标系
- Z轴: (负的 视线方向)! 重要 :在观察坐标系中,Z轴通常指向屏幕里(远离摄像机/眼睛) ,是
look = glm::normalize(eye - target) - X轴: (
right方向) - 顶部向量与视线方向交叉积取单位:right = glm::normalize(glm::cross(up, look)); - Y轴: (
up方向) - 取up向量的正交单位:up = glm::normalize(glm::cross(look, right));或直接使用用户定义的近似向上向量并确保与look和right构成正交系。 - OpenGL 经典坐标系中:坐标原点是摄像机位置,+X轴向右,+Y轴向上,-Z轴从屏幕指向你(视线方向指向屏幕内部)。
- Z轴: (负的 视线方向)! 重要 :在观察坐标系中,Z轴通常指向屏幕里(远离摄像机/眼睛) ,是
- 变换公式: `视口坐标 = ViewMatrix * World坐标 = (V * M) * Local坐标```
透视空间(Perspective Space)或 裁剪空间(Clip Space)
顶点经过 投影变换 后的坐标位于一个标准设备空间 中。这是一个齐次裁剪空间 (-w <= x,y,z <= w)。
- 变换 :通过投影矩阵(Projection Matrix)
- 正交投影: 平行光,无"近大远小"。适用界面GUI、CAD。
- 透视投影: 具有强烈的深度感("近大远小")。模拟真实眼睛视野。 最常用 !它用一个视锥体定义有效区域(一个金字塔截锥体)。矩阵基于近裁剪面
(near)、远裁剪面(far)、垂直视场角(fov)、纵横比(aspect ratio)计算而得。 - 将视锥体变换为立方体空间
([-1,1], [-1,1], [-1,1])。 - 重要功能 :进行视锥体裁剪
- 目的 :
- 定义可见范围:仅保留视锥体内的物体。
- 简化后面深度比较(标准化深度值)。
- 产生透视效果(如果是透视投影)。
- 变换公式 :
透视坐标 = ProjectionMatrix * View坐标 = (P * V * M) * Local坐标
标准化设备空间(NDC)
顶点坐标执行 透视除法 ,将裁剪坐标通过除以 w_c 得到 3D [−1,1] 范围内的坐标。
cpp
float x_ndc = x_c / w_c;
float y_ndc = y_c / w_c; # Y轴方向
float z_ndc = z_c / w_c; # 深度值在[-1,1]
透视除法是自动的,在顶点着色器输出后固定管线中执行。
目的 :在独立于设备的分辨率中统一表达位置和深度。
特点 :只保留在x∈[-1,1]及y∈[-1,1]区间内的点。