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

时间:2013-11-06 18:01:45

标签: opengl glsl shader fragment-shader

我正在使用片段着色器,使用 discard 关键字丢弃某些片段。我的着色器还使用* early_fragment_tests *(图像存储加载权限)。

编辑: 我没有写gl_FragDepth,我让标准OpenGL处理​​深度值。

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

编辑: 我的NVidia Quadro 600和K5000上似乎没有

我能找到这些信息的任何线索吗?仅供参考,我搜索了http://www.opengl.org/registry/specs/ARB/shader_image_load_store.txt。我找到了足够接近但不是那个特别的主题。

2 个答案:

答案 0 :(得分:3)

  

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

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

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

DX11 / OpenGL 4.x中的此规则有例外。如果您以这样的方式编写着色器,即可以保证输出深度始终保留深度测试的结果(与光栅化期间生成的深度相同),可以在使用{{1的着色器 - 的着色器中启用早期片段测试或写入discard。此功能称为 conservative depth ,除非您使用此功能,否则通常会理解gl_FragDepth将彻底打破早期深度优化。

现在,因为在你知道你正在编写的值是否通过深度测试(discard可能不同)或者片段是否存活之前你永远不应该写入深度缓冲区({{1}可以使用),你可以看到为什么包含gl_FragDepth的片段着色器着色的原语在评估着色器之前无法写入深度缓冲区。

答案 1 :(得分:1)

我认为您要查找的信息在该页面上:

  

如果启用了早期片段测试,则由计算的任何深度值   片段着色器无效。另外,深度缓冲,模板   缓冲区和遮挡查询样本计数甚至可以更新   片段着色器后将丢弃的片段或样本   由于每个片段操作(例如alpha-to-coverage或)而执行   alpha测试。

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