我一直在使用延迟渲染器进行照明,虽然在我的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);
然而,我得到的远不及预期的结果,当然,照明不起作用:
(尽量忽略盒子周围的模糊,当时我正在弄乱别的东西。)
什么可能导致这些问题,我怎样才能从深度工作中成功完成位置重建?感谢。