我正在阅读一篇很棒的OpenGL教程。真的很棒,相信我。我目前的主题是Z-buffer。除了解释它的全部内容外,作者还提到我们可以执行自定义深度测试,例如GL_LESS, GL_ALWAYS等。他还解释说,深度值的实际含义(哪些是top,哪些不是)也可以自定义。到目前为止我明白了。然后作者说了一些难以置信的话

The range zNear can be greater than the range zFar; if it is, then the window-space values will be reversed, in terms of what constitutes closest or farthest from the viewer. Earlier, it was said that the window-space Z value of 0 is closest and 1 is farthest. However, if our clip-space Z values were negated, the depth of 1 would be closest to the view and the depth of 0 would be farthest. Yet, if we flip the direction of the depth test (GL_LESS to GL_GREATER, etc), we get the exact same result. So it's really just a convention. Indeed, flipping the sign of Z and the depth test was once a vital performance optimization for many games.

如果我理解正确的话,在性能方面,翻转Z的符号和深度测试只不过是将<比较更改为>比较。所以,如果我理解正确,作者没有说谎或编造,那么将<改为>对许多游戏来说是一个至关重要的优化。

是作者编造的东西,是我误解了什么,还是确实是这样,一旦<比>慢(至关重要,正如作者所说)?

谢谢你澄清这个相当奇怪的问题!

免责声明:我充分意识到算法的复杂性是优化的主要来源。此外,我怀疑现在它肯定不会有任何不同,我并不是要求优化任何东西。我只是极度的,痛苦的,也许是极度的好奇。


当前回答

如果我理解正确的话,在性能方面,翻转Z的符号和深度测试只不过是将<比较更改为>比较。所以,如果我理解正确,作者没有说谎或编造,那么将<改为>对许多游戏来说是一个至关重要的优化。

我没有解释得特别好,因为这并不重要。我只是觉得这是一个有趣的小细节,我不打算详细介绍算法。

然而,背景是关键。我从未说过<比较比>比较快。记住:我们讨论的是图形硬件深度测试,而不是CPU。没有操作符<。

我指的是一个特定的旧优化,其中一帧你将使用范围为[0,0.5]的GL_LESS。下一帧,你用GL_GREATER渲染范围为[1.0,0.5]。你来来回回,字面上“翻转Z的符号和深度测试”每帧。

这将损失一点深度精度,但您不必清除深度缓冲区,这曾经是一个相当缓慢的操作。由于深度清理不仅是免费的,而且实际上比这种方法更快,人们不再做这种方法了。

其他回答

它与高度调优的汇编中的标志位有关。

x86有jl和jg指令,但大多数RISC处理器只有jl和jz指令(没有jg)。

如果我理解正确的话,在性能方面,翻转Z的符号和深度测试只不过是将<比较更改为>比较。所以,如果我理解正确,作者没有说谎或编造,那么将<改为>对许多游戏来说是一个至关重要的优化。

我没有解释得特别好,因为这并不重要。我只是觉得这是一个有趣的小细节,我不打算详细介绍算法。

然而,背景是关键。我从未说过<比较比>比较快。记住:我们讨论的是图形硬件深度测试,而不是CPU。没有操作符<。

我指的是一个特定的旧优化,其中一帧你将使用范围为[0,0.5]的GL_LESS。下一帧,你用GL_GREATER渲染范围为[1.0,0.5]。你来来回回,字面上“翻转Z的符号和深度测试”每帧。

这将损失一点深度精度,但您不必清除深度缓冲区,这曾经是一个相当缓慢的操作。由于深度清理不仅是免费的,而且实际上比这种方法更快,人们不再做这种方法了。

答案几乎可以肯定的是,无论使用哪种芯片+驱动程序,分层Z都只能在一个方向上工作——这在当时是一个相当常见的问题。低级组装/分支与此无关——z缓冲是在固定功能硬件中完成的,并且是流水线化的——没有推测,因此也没有分支预测。