【发布时间】:2018-05-27 20:53:09
【问题描述】:
许多人使用带有第三行的常用透视矩阵,如下所示:
(0 0 (n+f)/(n-f) 2*n*f/(n-f))
但它在远裁剪面附近的浮点精度方面存在问题。结果是z-fighting。 如何使用 z 的线性变换?让我们把矩阵第三行改成这样:
(0 0 -2/(f-n) (-f-n)/(f-n))
这将是从 [-n, -f] 到 [-1, 1] 的线性变换 z。然后,我们将在顶点着色器中添加这条线:
gl_Position.z *= gl_Position.w;
透视分割后z值会恢复。
为什么不到处使用它?我在网上找到了很多文章。他们都使用了通常的矩阵。 我描述的线性变换是否有我看不到的问题?
更新:这不是this 的副本。我的问题不是关于如何做线性深度缓冲。就我而言,缓冲区已经是线性的。我不明白,为什么不使用这种方法?内部 webgl 管道中是否存在陷阱?
【问题讨论】:
-
如果您看到我链接的副本,它应该会回答您的问题。如果您没有看到它:如果您对片段中的值进行线性化,那么您会失去精度,因为您已经获得了四舍五入的值。这个想法是将线性化的值存储到 Z 缓冲区,而不是在存储后对其进行线性化。这样你就可以绕过透视分割,一切都很好......线性Z缓冲区仅用于大深度视图。对于较小的,最好使用 OpenGL 非线性的,因为它在视觉上具有相同的深度分辨率。
-
@Spektre:这个问题不是您链接的问题的重复(在我看来),所以我重新打开它。虽然这两个问题都与线性深度缓冲区有关,但这里的这个问题专门询问通过修改顶点着色器中的剪辑空间 z 来线性化深度(无法完成),而链接的问题(正确地)在每个片段上线性化 z水平。
-
@derhass OK btw +1 答案这些准确度图很好
标签: opengl-es webgl depth-buffer