gpt4 book ai didi

opengl - 从深度缓冲区获取真实的 z 值

转载 作者:行者123 更新时间:2023-12-03 05:57:07 25 4
gpt4 key购买 nike

正如预期的那样,从着色器中的深度缓冲区进行采样会返回 0 到 1 之间的值。给定相机的近剪裁平面和远剪裁平面,如何计算此时的真实 z 值,即距相机的距离?

最佳答案

来自http://web.archive.org/web/20130416194336/http://olivers.posterous.com/linear-depth-in-glsl-for-real

// == Post-process frag shader ===========================================
uniform sampler2D depthBuffTex;
uniform float zNear;
uniform float zFar;
varying vec2 vTexCoord;
void main(void)
{
float z_b = texture2D(depthBuffTex, vTexCoord).x;
float z_n = 2.0 * z_b - 1.0;
float z_e = 2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear));
}

[编辑]所以这是解释(有两个错误,请参阅下面 Christian 的评论):

OpenGL 透视矩阵如下所示:from songho.ca

当你将此矩阵乘以齐次点 [x,y,z,1] 时,它会给出:[don't care, don't care, Az+B, -z](其中 A 和 B 为矩阵中的 2 个大组成部分)。

OpenGl 接下来进行透视除法:它将这个向量除以它的 w 分量。此操作不是在着色器中完成的(除了阴影贴图等特殊情况),而是在硬件中完成;你无法控制它。 w = -z,因此Z值变为-A/z -B。

我们现在处于标准化设备坐标中。 Z值在0和1之间。由于某些愚蠢的原因,OpenGL要求它应该移动到[-1,1]范围(就像x和y一样)。应用缩放和偏移。

该最终值随后存储在缓冲区中。

上面的代码执行完全相反的操作:

  • z_b 是存储在缓冲区中的原始值
  • z_n 将 z_b 从 [-1,1] 线性变换到 [0,1]
  • z_e 与 z_n=-A/z_e -B 的公式相同,但求解为 z_e。它相当于 z_e = -A/(z_n+B)。顺便说一句,A 和 B 应该在 CPU 上计算并作为制服发送。

相反的函数是:

varying float depth; // Linear depth, in world units
void main(void)
{
float A = gl_ProjectionMatrix[2].z;
float B = gl_ProjectionMatrix[3].z;
gl_FragDepth = 0.5*(-A*depth + B) / depth + 0.5;
}

关于opengl - 从深度缓冲区获取真实的 z 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6652253/

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