【发布时间】:2016-01-25 08:06:29
【问题描述】:
我编写了大量的着色器,但我偶然发现了一些我以前从未意识到的东西。
我需要一个带有简单正交投影的顶点 + 片段着色器,没有深度测试。
相机与原点 Z 轴对齐。
我禁用了 GL_DEPTH_TEST,并屏蔽了深度写入。事实上,它是如此简单,以至于我决定我什至不需要投影矩阵。在我完全的无知和独创性中,我认为对于任何三角形顶点,顶点着色器只需将 x,y(,z = <whatever>,w = 1) 传递给片段着色器。
我实际上认为片段着色器只需要 x,y 坐标,因为我们正在讨论正交投影,w = 1(没有透视分割),并且由于深度缓冲区无用,并且深度写入禁用,z 可以字面上是任何东西,没关系。
我当然错了。我很快发现光栅化器非常使用 z 组件,事实上,我有很多三角形根本没有被光栅化。
我还发现调整 z 组件会显着改变渲染的三角形。所以我实现了一个常规的正交投影矩阵,这当然解决了这个问题,现在一切都被正确地光栅化了。
现在,出于纯粹的好奇心,我开始使用正交投影矩阵,看看不同输入向量的实际结果是什么,近处和远处裁剪平面的值不同,我真的无法理解。好的,x,y 和 w 都符合预期,但是根据我的近/远剪辑平面,我得到完全不同的 z 值。
问题是:片段着色器对裁剪平面和投影矩阵一无所知,它只是得到一堆 x,y,z,w……z 分量在光栅化过程中的作用是什么?它如何知道视锥体内是否有东西?
我的意思是,对于正交投影矩阵中的任何给定近/远平面,我得到的 z 值对给定投影矩阵有效,而对其他投影矩阵无效。由于片段着色器无法知道矩阵中使用了哪些平面,它如何丢弃片段?同一个图元的每个顶点之间是否存在关系?
PS:我知道片段着色器甚至没有被调用,因为我设置了一个 SSBO + 原子计数器并检查了两者都没有改变。
【问题讨论】:
-
在片段着色器阶段之前执行光栅化 - 它实际上是生成片段的原因。 Znear/Zfar 对齐您的最小值/最大值以匹配剪辑空间中的 z=1 和 z=-1。只需剪掉不适合单位立方体的所有内容(在剪裁空间中 - 在投影和透视分割之后),一切都很好。
-
你得到的矩阵是什么?为什么您的 Zfar 大于 Znear? Z轴来自opengl中的深度到相机。纸上的快速计算给了我 ~
0.7317z=300 和 znear/zfar (当然是倒置的)。 -
你是对的..我删除了我之前的 incorrect 示例,我重新计算了所有内容,但出现了符号错误..你说得对..它只是将所有内容从-1 到 +1 如果在截锥体内..如果您发布答案,我会接受它。谢谢。