如果我使用 early_fragment_tests 丢弃着色器中的片段,深度缓冲区会发生什么情况



我正在使用一个片段着色器,它使用discard关键字丢弃一些片段。我的着色器也使用early_fragment_tests(图像存储加载义务)。

编辑 :我不写gl_FragDepth,我让标准的OpenGL处理深度值。

在执行 discard 关键字之前,我的深度缓冲区是否会使用片段的深度进行更新?

编辑 :在我的 NVidia Quadro 600 和 K5000 上似乎并非如此

有什么线索可以在哪里找到这些信息吗?仅供参考,我搜索了 http://www.opengl.org/registry/specs/ARB/shader_image_load_store.txt。我找到了足够接近的主题,但不是那个特定的主题。

在执行 discard 关键字之前,我的深度缓冲区是否会使用片段的深度进行更新?

不,在包含discard或将任意值写入gl_FragDepth的着色器中明确禁止这种行为。这是因为在此类着色器中,着色后的片段深度可能与初始光栅化(预着色)期间生成的位置无关。

无需写入gl_FragDepth或丢弃,片段的深度实际上早在实际片段着色器执行之前就已经知道了,这为早期深度测试奠定了基础。如果可以确定在评估片段着色器之前无法通过深度测试,则可以跳过某些(单个平铺区域)或所有基元的光栅化/着色,但如果片段着色器本身决定了片段的深度,那么所有赌注都关闭了。

在DX11/OpenGL 4.x中,此规则有一个例外。如果以保证输出深度将始终保留深度测试结果(与光栅化期间生成的深度相同的结果)的方式编写着色器,则可以在使用discard或写入gl_FragDepth的着色器中启用早期片段测试。此功能称为保守深度,除非您使用它,否则通常认为discard将全面破坏早期深度优化。

现在,由于在知道正在写入的值是否通过深度测试(gl_FragDepth可能不同)或片段是否存活(可以使用discard之前,切勿写入深度缓冲区,因此您可以了解为什么由包含discard的片段着色器的基元在评估着色器之前无法写入深度缓冲区。

我认为您正在寻找的信息在该页面上:

如果启用了早期片段测试,则由 片段着色器不起作用。 此外,深度缓冲区、模板 缓冲区和遮挡查询样本计数可能会更新,即使对于 片段着色器后将丢弃的片段或样本 由于每个片段的操作(例如 Alpha 到覆盖率或 阿尔法测试。

"深度缓冲区,[等]可能会更新"中的单词"可能"意味着它是依赖于实现的(或完全随机的)。

最新更新