The way to reconstruct position in Leadwerks

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 :slight_smile:

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)

Thanks, I’ll try that.

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.