3

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

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

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

编辑:在我的 NVidia Quadro 600 和 K5000 上似乎不是这样。

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

4

2 回答 2

4

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

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

在不写入gl_FragDepth或丢弃的情况下,片段的深度实际上在实际片段着色器执行之前很久就知道了,这为早期深度测试奠定了基础。如果可以确定在评估片段着色器之前它会通过深度测试失败,但如果片段着色器本身决定了片段的深度,则可以跳过某些(单个平铺区域)或所有图元的光栅化/着色,然后所有赌注都关闭。

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

现在,由于在知道所写入的值是否通过深度测试(gl_FragDepth可能不同)或片段是否存活(discard可能被使用)之前,您永远不应该写入深度缓冲区,您可以看到为什么原始着色由包含discard无法在计算着色器之前写入深度缓冲区的片段着色器。

于 2013-11-07T00:22:51.833 回答
1

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

如果启用了早期片段测试,则片段着色器计算的任何深度值都无效。此外,深度缓冲区、模板缓冲区和遮挡查询样本计数可能会更新,即使对于在片段着色器执行后由于每个片段的操作(例如 alpha 到覆盖或 alpha 测试)而将被丢弃的片段或样本。

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

于 2013-11-06T18:32:37.517 回答