OpenGL 从深度恢复 z

OpenGL restore z from depth

我试图了解如何从深度缓冲区恢复 z 并尝试根据这两个 post 进行数学计算:

Getting the true z value from the depth buffer(计算器溢出) http://ogldev.atspace.co.uk/www/tutorial46/tutorial46.html

这两个 post 使用不同的投影矩阵(具体来说,右下角的 2x2 部分不同,一个区别是在 [3][4] 中使用 -1 与 +1)。不太确定为什么会这样,afaik -1 是 "the correct OpenGL projection-matrix"(对吗?)

现在我尝试对两者进行计算,奇怪的是在 SO-post 中它提到了 -A-B/z(或者在我的计算中 -S-T/z)。然后代码显示

解决 A 和 B(或 S 和 T)的问题得到

好的,现在从头开始计算两个投影矩阵,(left=ogldev.atspace.co.uk, right=Whosebug) 现在它变得混乱,因为直到 -S-T/z 部分一切都是很好,但是当我们比较应该是 Whosebug 案例(-1 投影矩阵)的已求解公式时,它与 ogldev.atspace.co.uk(+1 投影矩阵)中的公式相匹配 - 红色...

这令人困惑,有什么线索是我做错了什么吗?!

已更新计算,请参阅下面 "derhass" 的评论:

The two posts use different projection matrices (specifically the lower-right 2x2 part is different, one difference being use of a -1 vs a +1 in [ 3 ][ 4 ]). Not really sure why that would be, afaik the one with -1 is "the correct OpenGL projection-matrix" (right?)

没有。这里没有"right"和"wrong"。只有惯例。对于您选择使用的约定,"correct" 矩阵是做正确事情的矩阵。 Classic GL 的 glFrustum 函数确实使用了来自 Whosebug post 的矩阵。这里的约定是投影中心在原点,视角方向-zx向右,y向上。但是您可以使用任何约定,具有任意主点和任意投影方向。另一个矩阵只是+z作为投影方向,可以理解为坐标space的反手性。也可以解释为只是朝相反的方向看,同时仍然保持左手坐标系。

this is confusing, any clues what I'm doing wrong?!

我不确定你想在这里证明什么,除了引入小符号错误会产生虚假结果之外...

您对“+z”投影矩阵的推导似乎没问题。它将 depth=0 映射到 z=n,将 depth=1 映射到 z=f,这是映射它们的标准方式 - 只是另一种约定。您还可以使用反向 Z 映射,其中近平面映射到深度 1,远平面映射到深度 0。

更新

对于第二个矩阵,您再次翻转了符号,即使在我的评论更正之后也是如此。当您在最终公式中替换 ST 时,您实际上替换了 -S。如果你做了正确的替换,你会得到 [现在你再次修正计算后,你有] 在 +z 矩阵情况下恰好是否定形式 - depth = 0 映射到 -n,depth=1 映射到 -f,这正是这些参数的定义方式在经典的 GL 约定中,nf 只是描述到这些平面的距离,在观察方向 (-z)。