从深度缓冲值中获取世界位置

时间:2015-08-26 12:55:57

标签: c++ opengl

我一直在使用延迟渲染器进行照明,虽然在我的G缓冲区中使用位置缓冲区,但它运行良好。照明是在世界空间完成的。

我试图实现一种算法,从深度缓冲区和纹理坐标重新创建世界空间位置,尽管没有运气。

我的顶点着色器没什么特别的,但这是我的片段着色器的一部分,我(试图)计算世界空间位置:

// Inverse projection matrix
uniform mat4 projMatrixInv;
// Inverse view matrix
uniform mat4 viewMatrixInv;

// texture position from vertex shader
in vec2 TexCoord;

... other uniforms ...

void main() {
    // Recalculate the fragment position from the depth buffer
    float Depth = texture(gDepth, TexCoord).x;
    vec3 FragWorldPos = WorldPosFromDepth(Depth);

    ... fun lighting code ...
}

// Linearizes a Z buffer value
float CalcLinearZ(float depth) {
    const float zFar = 100.0;
    const float zNear = 0.1;

    // bias it from [0, 1] to [-1, 1]
    float linear = zNear / (zFar - depth * (zFar - zNear)) * zFar;

    return (linear * 2.0) - 1.0;
}

// this is supposed to get the world position from the depth buffer
vec3 WorldPosFromDepth(float depth) {
    float ViewZ = CalcLinearZ(depth);

    // Get clip space
    vec4 clipSpacePosition = vec4(TexCoord * 2.0 - 1.0, ViewZ, 1);

    // Clip space -> View space
    vec4 viewSpacePosition = projMatrixInv * clipSpacePosition;

    // Perspective division
    viewSpacePosition /= viewSpacePosition.w;

    // View space -> World space
    vec4 worldSpacePosition = viewMatrixInv * viewSpacePosition;

    return worldSpacePosition.xyz;
}

我仍然有我的位置缓冲区,我会对它进行采样以便稍后将其与计算位置进行比较,所以一切都应该是黑色的:

vec3 actualPosition = texture(gPosition, TexCoord).rgb;
vec3 difference = abs(FragWorldPos - actualPosition);
FragColour = vec4(difference, 0.0);

然而,我得到的远不及预期的结果,当然,照明不起作用:

image of issue

(尽量忽略盒子周围的模糊,当时我正在弄乱别的东西。)

什么可能导致这些问题,我怎样才能从深度工作中成功完成位置重建?感谢。

0 个答案:

没有答案