为啥图形管线需要映射到剪辑坐标和标准化设备坐标?

Posted

技术标签:

【中文标题】为啥图形管线需要映射到剪辑坐标和标准化设备坐标?【英文标题】:Why does graphics pipeline need mapping to clip coordinates and normalized device coordinates?为什么图形管线需要映射到剪辑坐标和标准化设备坐标? 【发布时间】:2016-01-09 13:03:23 【问题描述】:

关于透视投影,如果我使用简单的投影矩阵,例如:

1 0 0 0

0 1 0 0

0 0 1 0

0 0 1/接近 0

,它只是投影到图像平面上。我认为可以通过丢弃和规范化轻松获取视图空间坐标。

如果在正交投影上,它甚至不需要投影矩阵。

但是,OpenGL图形管线有上述过程,虽然透视投影会导致深度精度误差。

为什么需要映射到剪辑坐标和标准化设备坐标?

已添加

如果我使用上面的投影矩阵,

      1 0 0   0
p = ( 0 1 0   0 )
      0 0 1   0
      0 0 1/n 0

v_eye = (x y z 1)

v_clip = p * v_eye = (x y z z/n)

v_ndc = v_clip / v_clip.w = (nx/z ny/z n 1)

然后,可以通过丢弃顶部、底部、左侧、右侧的值来裁剪 v_ndc。 far 的值也可以在乘以投影矩阵之前以相同的方式进行裁剪。

嗯,虽然看起来很傻,但我认为这比以前容易了。

ps。我注意到不能以这种方式写入深度缓冲区。那么,不能在投影之前写吗? 对不起,愚蠢的问题和胡言乱语......

【问题讨论】:

我还是不明白。在乘以投影矩阵之前,您想如何裁剪 v_ndc?它在乘法之前不存在。您只能剪裁 v_eye,但在眼睛空间中,视锥体不是立方体,而是截断的金字塔,因此很难剪裁。 我的猜测是设备归一化坐标引入的原因是:1.它们简化并加速了填充多边形的硬件插值器。 2. 更好地利用硬件支持的插值器变量的位深度来提高精度(减少像素化插值) @Spektre 您的解释似乎是说 NDC 是作为优化引入的。但是,将生活在不同 4D 空间中的点带入单个 3D 空间(NDC 空间)是必要的空间。这是通过透视划分来完成的。 @Spektre:实际上,光栅化和插值发生在 窗口空间,而不是 NDC。 【参考方案1】:

在正交投影的情况下,您是对的:不需要透视除法,但不会引入任何错误,因为它是除以 1。(正交投影矩阵始终包含 [0, 0, 0, 1] 在最后一行)。

对于透视投影,这有点复杂: 我们来看最简单的透视投影:

      1  0  0  0
P = ( 0  1  0  0 )
      0  0  1  0
      0  0  1  0

然后一个向量v=[x,y,z,1](在视图空间中)被投影到

v_p = P * v = [x, y, z, z],

在投影空间中。

现在需要透视分割来获得透视效果(靠近观察者的物体看起来更大):

v_ndc = v / v.w = [x'/z y'/z, z'/z, 1]

如果没有透视划分,我不明白如何实现这一点。

【讨论】:

对不起,我问错了……我想说,好像没必要用这个perspective matrix。我认为裁剪和规范化 v_ndc [x'/z y'/z, z'/z, 1] 比让透视矩阵更容易。 裁剪和标准化是什么意思?你能在问题中添加一个例子吗?【参考方案2】:

为什么需要映射到剪辑坐标和标准化设备坐标?

程序员将顶点留给 GL 处理的空间是剪辑空间。它是顶点存在于标准化/透视分割之前的 4D 同质空间。这种划分对于执行透视投影很有用,是将顶点从剪辑空间转换为 NDC (3D) 所需的映射。为什么?相似的三角形。

View Space                               Point
                                           *
                                         / |
                            Proj       /-  |
              Y  ^          Plane   /--    |
                 |               /--       |
                 |            *--          |y
                 |        /-- |            |
                 |     /--    |y'          |
                 | /---       |            |
           <-----+------------+------------+-------
         Z     O | 
                 |-----d------|            |
                 |------------z------------|

透视投影是来自眼睛/原点的光线穿过投影平面撞击空间中存在的点的地方。射线与平面相交的点就是命中点的投影。假设我们要将点P 投影到投影平面上,其中所有点都有z = d。需要找到P 的预计位置,即P'。我们知道z' 将是d(因为投影平面在那里)。要找到y',我们知道

y ⁄ z = y' ⁄ z' (similar triangles)
y ⁄ z = y' ⁄ d  (z' = d by defn. of proj. plane)

y' = (d * y) ⁄ z

z 的这种划分称为透视划分。这表明在透视投影中,物体越远,z 越大,看起来越小;物体越近,z 越小,看起来越大。

在剪辑空间中方便执行的另一件事显然是剪辑。在 4D 中,裁剪只是检查点是否在一个范围内,而不是更昂贵的分割。

在正交投影的情况下,投影不是平截头体而是长方体——平行光线来自无穷远而不是原点。因此,对于点P = (x, y, z),Z 值被丢弃,得到P' = (x, y)。因此,在这种情况下,透视除法什么都不做(除以 1)。

【讨论】:

以上是关于为啥图形管线需要映射到剪辑坐标和标准化设备坐标?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我们需要透视分割?

管线流程详解

UE5 Shader基础学习笔记——01-12 图形管线/创建shader/数学节点/贴图压缩/LerpDotUV/常用向量/坐标空间/MinMaxClampSaturate/法线贴图混合

UE5 Shader基础学习笔记——01-12 图形管线/创建shader/数学节点/贴图压缩/LerpDotUV/常用向量/坐标空间/MinMaxClampSaturate/法线贴图混合

opengl翻转后为啥出现两个图像

OpenGL工作流程