near/far 正交光栅化中的平面和 z

near/far planes and z in orthographic rasterization

我编写了大量的着色器代码,但我偶然发现了一些我以前从未意识到的东西。

我需要一个带有简单正交投影的顶点 + 片段着色器,没有深度测试。

相机与原点 Z 轴对齐。

我禁用了 GL_DEPTH_TEST,并屏蔽了深度写入。事实上它是如此简单,以至于我决定我什至不需要投影矩阵。在我完全的无知和独创性中,我认为对于任何三角形顶点,顶点着色器只会将 x,y(,z = <whatever>,w = 1) 传递给片段着色器。

我实际上认为片段着色器只需要 x,y 坐标,因为我们讨论的是正交投影,w = 1(没有透视划分),并且深度缓冲区无用,并且深度写入被禁用, z 可以是任何东西,没关系。

我当然错了。我很快发现光栅化器使用了 z 分量,事实上,我有大量的三角形根本没有被光栅化。

我还发现调整 z 分量会显着改变渲染的三角形。所以我实现了一个正交投影矩阵,这当然解决了这个问题,现在一切都被正确地光栅化了。

现在,出于纯粹的好奇心,我开始玩正交投影矩阵,看看对于不同的输入向量,近距和远距裁剪平面的值不同,我真的无法理解。好的,x、y 和 w 都符合预期,但是根据我的 near/far 剪辑平面,我得到了完全不同的 z 值。

问题是:片段着色器对裁剪平面和投影矩阵一无所知,它只是得到一堆x,y,z,w...光栅化过程中z分量的作用是什么?它怎么知道视锥体内是否有东西?

我的意思是,对于正交投影矩阵中的任何给定 near/far 平面,我得到的 z 值对给定投影矩阵有效,而对其他投影矩阵无效。由于片段着色器无法知道矩阵中使用了哪些平面,它如何丢弃片段?同一个图元的每个顶点之间是否有关系?

PS:我知道甚至没有调用片段着色器,因为我设置了一个 SSBO + 原子计数器并检查了两者都没有改变。

顶点着色器将顶点从模型局部坐标系转换到剪辑 space。如果您的坐标在透视除法后超过单位立方体(每个维度具有 [-1;1] 大小的立方体,或在除法之前为 [-W;W]),则此片段将被剪裁。

如果您不关心 Z 并且真的不想设置正确的正射投影(例如,您不知道 Z 值范围因此无法设置适当的裁剪平面),您可以在顶点着色器中更正 Z通过将其限制在 (-W; W) 范围内(或将其设置为 0)。