我一直在使用延迟渲染器进行照明,虽然在我的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;
}
Run Code Online (Sandbox Code Playgroud)
我仍然有我的位置缓冲区,我将其采样以便稍后将其与计算位置进行比较,所以一切都应该是黑色的:
vec3 actualPosition = texture(gPosition, TexCoord).rgb;
vec3 difference = abs(FragWorldPos - actualPosition);
FragColour = vec4(difference, 0.0);
Run Code Online (Sandbox Code Playgroud)
但是,我得到的远不及预期的结果,当然,照明不起作用:
(试着忽略盒子周围的模糊,当时我正在弄乱别的东西.)
什么可能导致这些问题,我怎样才能从深度工作成功获得位置重建?谢谢.
And*_*man 15
您处于正确的轨道上,但尚未按正确的顺序应用转换.
鉴于纹理坐标[ 0,1 ]和深度[ 0,1 ],计算裁剪空间位置
w= 1.0和x,y,z= [ -w,w ]从剪辑空间转换到视图空间(反向投影)
从视图空间转换到世界空间(反向视图转换)
// this is supposed to get the world position from the depth buffer
vec3 WorldPosFromDepth(float depth) {
float z = depth * 2.0 - 1.0;
vec4 clipSpacePosition = vec4(TexCoord * 2.0 - 1.0, z, 1.0);
vec4 viewSpacePosition = projMatrixInv * clipSpacePosition;
// Perspective division
viewSpacePosition /= viewSpacePosition.w;
vec4 worldSpacePosition = viewMatrixInv * viewSpacePosition;
return worldSpacePosition.xyz;
}
Run Code Online (Sandbox Code Playgroud)
我会考虑更改名称CalcViewZ (...),这是非常误导.考虑称之为更合适的东西CalcLinearZ (...).
| 归档时间: |
|
| 查看次数: |
6625 次 |
| 最近记录: |