对数深度缓冲线性化

5
如何使对数深度缓冲线性化?
在片段着色器中实现对数深度缓冲的线性可视化。
  float n = 1.0; // camera z near
  float f = 27000000.0; // camera z far
  float z = texture( DepthTex, TexCoord ).x;
  float d = (2.0 * n) / (f + n - z * (f - n));
  FragColor=vec4(d,d,d,1);

球体顶点着色器

vec4 ClipCoords(vec3 position,mat4 matrix)
{
   vec4 clip = matrix * vec4(position,1.0f);
   clip.z =((2.0f * log(1.0f * clip.z + 1.0f) / log(1.0f * 27000000.0f + 1.0f)) - 1.0f) * clip.w;
   return clip;
}
 gl_Position = ClipCoords(position,matrix);

左侧显示对数深度缓冲线性化的不足,而右侧显示没有使用 log 的线性化,只是使用了 gl_Position = matrix * vec4(position,1.0f);

enter image description here
1个回答

7
使用对数深度缓冲,场景(相机空间)深度到最终存储在深度缓冲区(0..1)中的值的映射如下:
depth_value = log(C*z + 1) / log(C*Far + 1)

其中z是进入场景的正深度,否则可从投影后剪辑空间中的w分量获取(在您的代码中,您可以使用..log(clip.w + 1.0)..)。

要在片段着色器中检索相机空间深度,需要反转该方程:

z = (exp(depth_value*log(C*far+1)) - 1)/C

或者等价地
z = (pow(C*far+1,depth_value)-1)/C

要将0..far的线性映射转换为0..1,只需将其除以far值。


这些方程中的 C(和在较小程度上 far)是什么?我假设 far 是 FrustumFar 吗? - Richard Tingle
C是一个常数,用于调整对数曲线的轮廓。它的影响在http://outerra.blogspot.com/2012/11/maximizing-depth-buffer-range-and.html中描述了对数深度函数的比较。通常情况下,您可以将其安全地设置为1。far对应于视锥体远端距离。 - camenomizoratojoakizunewake

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接