gpt4 book ai didi

optimization - DirectX 11 中的早期 Z 测试/深度测试

转载 作者:行者123 更新时间:2023-12-03 15:49:43 26 4
gpt4 key购买 nike

作为一个 DirectX 菜鸟,我正试图围绕深度缓冲区,特别是如何为模糊像素调用像素着色器。

据我所知,光栅化器为覆盖原始绘制的每个像素调用像素着色器,然后在输出合并阶段的后期,输出合并检查深度缓冲区并丢弃、写入或混合后台缓冲区中的像素.

尽管如果我在一个非常复杂的对象前面渲染一个简单的不透明对象,这似乎很浪费,因此在为复杂对象调用像素着色器之前,让光栅化器检查深度图似乎很有用。

在做研究时,我发现了对早期 Z 测试/保守 Z 测试等的引用,但关于它的文档似乎也很少。我寻找一种在光栅化器状态 desc 对象上配置它的方法,但我只在 OM 状态 desc 上找到了类似的东西。

这似乎也可以在 DX9 中使用 SetRenderState 进行设置(尽管我也没有使用 DX9 的经验)

从我的研究来看,如果我前后渲染对象,这似乎是某些硬件所做的事情,对吗?我怎么知道?使用 DirectX 的所有控件,您似乎无法控制它,这似乎很奇怪,因为它似乎是一个很好的优化 :)

任何有关此的信息或引用都适用

最佳答案

就深度测试而言,DirectX 声明它必须在像素着色器之后进行深度测试,但并没有说它实际上必须这样做。实际上,early z 在许多制造商的硬件上已经存在多年。通常有一种比早期 Z 测试更早的形式,称为分层 Z,它不是在单个像素上运行,而是在多个像素的“平铺”上运行,以避免早期 Z 的成本。

Early Z 不是您可以通过您在设备上设置的任何特定状态打开或关闭的东西。硬件将尽可能早地执行 z 测试,并且您不知道它在像素着色器之后的任何地方。

不过,您可以做某些事情,这可能会限制硬件尽可能早地进行 z 测试。 Alpha 测试、使用“丢弃”(杀死像素)和 Alpha 覆盖肯定会禁用早期 z 写入,因为像素着色器需要在硬件确定是否写入深度值之前运行。如果您正在使用 alpha 测试/丢弃并且不需要 z-writes,那么将它们关闭,您就有可能获得 early-z 的最佳机会。

如果你想要早期的 Z,在像素着色器中修改/写入“深度”是一个明确的禁忌。在这种情况下,硬件甚至无法执行早期测试,因为它在你之前还不知道像素的深度是多少已经在像素着色器中决定了它,它既不能执行早期 z 测试,也不能执行早期 z 写入。

如果您需要从像素着色器写入深度但可以保证您只会写入大于或等于光栅化器生成的深度值,您可以使用相当未记录的 SV_DepthGreater输出语义。由于您 promise 不会写入小于插值深度的深度值,因此硬件仍然可以尝试执行 early-z 测试,但随后将 z 写入推迟到像素着色器结束。 (如果您碰巧使用倒置的 z-test/z-buffer,则有一个 SV_DepthLessEqual 等效项)。

由于 z-testing 必须出现在管道的末尾,因此在像素着色器中使用 UAV 也会禁用 early-z。由于渲染目标现在不是唯一的输出,并且因为 DirectX 规范说它必须出现在最后进行 z-testing,因此即使对于最终会失败 z-test 的像素,您的 UAV 写入也应该发生。为此,在着色器模型 5 中添加了一个名为 [earlydepthstencil] 的属性。这告诉 DirectX 您很高兴发生 early-z(如果可能),并且即使您有 UAV 写入,也不要运行像素着色器。

总而言之,如果您没有做上面提到的任何稍微古怪的事情(使用 SV_DEPTH 修改深度、覆盖范围的 alpha、使用剪辑/丢弃等),那么您很有可能已经获得了 early-Z 的好处。如果您不想要 z-writes,请始终关闭 z-writes,并避免写入 SV_DEPTH,因为在启用该选项后,您绝对无法获得 early-z。

关于optimization - DirectX 11 中的早期 Z 测试/深度测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17898738/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com