Hi guys,
Recently, I’m interested in trying different ways to reconstruct view space position from zbuffer.
Fisrt, let’s see the position buffer with GL_RGBA16F
vec3 position = texelFetch(g_TexPosition, ivec2(gl_FragCoord.xy), 0).xyz;
Then, I tried to use the formula from Leadwerks
const vec2 camerarange = vec2(0.1, 1000.0);
const vec2 buffersize = vec2(1024.0, 600.0);
float DepthToZPosition(in float depth)
{
return camerarange.x / (camerarange.y - depth * (camerarange.y - camerarange.x)) * camerarange.y;
}
void main()
{
float depth = texelFetch(g_TexDepth, ivec2(gl_FragCoord.xy), 0).r;
vec3 position;
position = vec3(((gl_FragCoord.x/buffersize.x)-0.5) * 2.0,((-gl_FragCoord.y/buffersize.y)+0.5) * 2.0 / (buffersize.x/buffersize.y),DepthToZPosition(depth));
position.x *= position.z;
position.y *= -position.z;
......
}
The second img looks obviously wrong. I thought position.z should be -DepthToZPosition(depth), but the result is still wrong.
Any idea?
Maybe try this
float DepthToZPosition(in float depth)
{
return -cameraRange.x / (cameraRange.y - depth * (cameraRange.y - cameraRange.x)) * cameraRange.y;
}
and…
position= vec3( ((gl_FragCoord.x/buffersize.x)-0.5) * 2.0,
((-gl_FragCoord.y/buffersize.y)+0.5) * 2.0,
DepthToZPosition( depth.x ));
position.x *= -position.z * frustumRange.x;
position.y *= position.z * frustumRange.y;
where frustumRange.x is the frustum’s right value and frustumRange.y is the frustum’s top value
(this is assuming frustum.left = -frustum.right and frustum.bottom = -frustum.top)
Hey LangFox/Anyone else: Did this work out for you?
float DepthToZPosition(in float depth)
{
return -cameraRange.x / (cameraRange.y - depth * (cameraRange.y - cameraRange.x)) * cameraRange.y;
}
I am having trouble again with this method, It seems that for my frustum.near any value aside from 1.0 gives incorrect results.
If I use the same frustum values (above or below 1.0) with a RGBF32 FBO to store the position rather than reconstructing I get the correct result.
Anyone have Ideas as to why?
Solved!
position= vec3( ((gl_FragCoord.x/buffersize.x)-0.5) * 2.0,
((-gl_FragCoord.y/buffersize.y)+0.5) * 2.0,
DepthToZPosition( depth.x ));
position.x *= -position.z * frustumRange.x;
position.y *= position.z * frustumRange.y;
This assume that frustum.near is 1.0!
to adjust for cases where it is not 1.0 you need to change it to:
position.x *= -position.z * frustumRange.x * (1.0/frustum.near);
position.y *= position.z * frustumRange.y * (1.0/frustum.near);
you can compute
frustumRange.x * (1.0/frustum.near)
and
frustumRange.y * (1.0/frustum.near)
in the application as:
frustum.right * (1.0/frustum.near),
frustum.top * (1.0/frustum.near)
and pass it through as a new uniform to save time!
Thanks for reading.