PDA

View Full Version : The way to reconstruct position in Leadwerks



LangFox
07-08-2009, 09:46 PM
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;

http://i724.photobucket.com/albums/ww246/LangFox/831dce1d.jpg

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;

......
}

http://i724.photobucket.com/albums/ww246/LangFox/8fb29ef0.jpg

The second img looks obviously wrong. I thought position.z should be -DepthToZPosition(depth), but the result is still wrong.

Any idea?

James A.
07-09-2009, 12:58 AM
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)

LangFox
07-09-2009, 06:28 PM
Thanks, I'll try that.

James A.
07-29-2009, 07:06 PM
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?

James A.
07-29-2009, 10:32 PM
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.