Jump to content
  • Advertisement
Sign in to follow this  
Haptic

OpenGL Another Position From Depth Thread

This topic is 3024 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey everyone,

So I am trying to reconstruct a pixel's position in 3D space from its depth in GLSL, OpenGL and C++.

I was hoping I could run my code by you guys and see if you can spot the mistake.

I have been following the tutorials by MJP and the frustum one from Lighthouse3D, as well as the original posts MJP was responding to.

To give you an idea of what I'm after, here is the output using forward rendering.
Photobucket

And my result using the deferred method.
Photobucket

I think my problem might be the spaces I am working in, ie. View or World etc. I'm pretty average with these and have most likely made some errors I can't track down.

Frustum Corner Calculations:

float fov = 45.0f;
float nearDist = 0.1f;
float farDist = 100.0f;


// .....
// Assuming projection is set as follows

gluPerspective(fov,(float)width/(float)height, nearDist, farDist);

// .....


// Camera is positioned using
// glTranslatef(0.0f, 0.0f, -45.0f);

float Hfar = 2 * tan(Rad(45.0f)/2.0f) * farDist;
float Wfar = Hfar * ((float)width / (float)height);

vec3 p = vec3(0.0f, 0.0f, 45.0f);
vec3 dir = vec3(0.0f, 0.0f, -1.0f);
vec3 up = vec3(0.0f, 1.0f, 0.0f);
vec3 right = vec3(1.0f, 0.0f, 0.0f);

vec3 fc = p + dir * farDist ;

vec3 ftl = fc + (up * Hfar/2.0f) - (right * Wfar/2.0f);
vec3 ftr = fc + (up * Hfar/2.0f) + (right * Wfar/2.0f);
vec3 fbl = fc - (up * Hfar/2.0f) - (right * Wfar/2.0f);
vec3 fbr = fc - (up * Hfar/2.0f) + (right * Wfar/2.0f);






Geometry Pass
VERTEX SHADER:

varying vec3 N;
varying vec4 V;

void main()
{
N = gl_Normal;
V = gl_Vertex; // View independent. Is this world space?

gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}

FRAGMENT SHADER:

uniform sampler2D diff;
uniform sampler2D norm;
uniform sampler2D spec;

uniform float farDist;
varying vec3 N;
varying vec4 V;

void main()
{

vec4 d = texture2D(diff, gl_TexCoord[0].st);
vec4 n = texture2D(norm, gl_TexCoord[0].st);
vec4 s = texture2D(spec, gl_TexCoord[0].st);

n = normalize(n);

gl_FragData[0] = d; // Diffuse
gl_FragData[1] = n; // Normal
gl_FragData[2] = s; // Specular

//Linear normalised depth
gl_FragData[3] = vec4(-V.z / farDist, 0.0, 0.0, 1.0);
}






Reconstruction Pass
VERTEX SHADER:

varying vec4 v;
varying vec3 viewDir;
attribute vec3 corner;

void main()
{
viewDir.xyz = corner.xyz;
v = gl_Vertex;

gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}


FRAGMENT SHADER:

uniform sampler2D diff;
uniform sampler2D norm;
uniform sampler2D spec;
uniform sampler2D depth;

varying vec4 v;
varying vec3 viewDir;


void main()
{

float z = texture2D(depth, gl_TexCoord[0].st).r; // normalisedDepth

// pos = frustumRay * normalisedDepth
// need this to be identical to gl_Vertex in geometry pass
vec4 pos = vec4(viewDir.xyz * z, 1.0);

...

// Lighting Calculations

}






If you need any more info let me know.

Thanks alot

[Edited by - Haptic on August 26, 2010 10:30:54 PM]

Share this post


Link to post
Share on other sites
Advertisement
Ok, so my frustum corners are not in view-space.

Because it's view space, am I right in saying it will never change? It will always be a plane with z = -farDist?

So ignoring the 45.0f z-translation, my frustum calculations become

float Hfar = 2 * tan(Rad(45.0f)/2.0f) * farDist;
float Wfar = Hfar * ((float)width / (float)height);

vec3 p = vec3(0.0f, 0.0f, 0.0f);
vec3 dir = vec3(0.0f, 0.0f, -1.0f);
vec3 up = vec3(0.0f, 1.0f, 0.0f);
vec3 right = vec3(1.0f, 0.0f, 0.0f);

vec3 fc = p + dir * farDist ;

vec3 ftl = fc + (up * Hfar/2.0f) - (right * Wfar/2.0f);
vec3 ftr = fc + (up * Hfar/2.0f) + (right * Wfar/2.0f);
vec3 fbl = fc - (up * Hfar/2.0f) - (right * Wfar/2.0f);
vec3 fbr = fc - (up * Hfar/2.0f) + (right * Wfar/2.0f);




Also, my depth was not in view-space. I think it is now..?
varying vec3 N;
varying vec4 V;

void main()
{
N = gl_Normal;
V = gl_ModelViewMatrix * gl_Vertex; // multiply by modelview = View space?

gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}




This doesn't change anything much. Fiddling with the lights z-pos, the best picture I can get is
Photobucket

Share this post


Link to post
Share on other sites
I've found the main mistake, for those interested.

The reason half of the picture is black while the other is lit is because I was normalising the normal map in the geometry-pass shader. No idea why I did that, but anyway, the output is now looking almost exactly like the desired output in the first post.

Oddly, there's a few parameters that have to be tweaked to get it exactly the same, but I'm far less concerned about that.

Share this post


Link to post
Share on other sites
Thanks for the reply jcabeleira.

I fixed a couple of errors including adding the camera position and it now works perfectly!
Thanks for the tip.

Share this post


Link to post
Share on other sites
I still have one last problem!

When I rotate the plane that is being lit, it gets all blocky around the center of the light.

Photobucket

Could this be some kind of accuracy issue with my depth values or something? Any ideas?

Thanks again

Share this post


Link to post
Share on other sites
Problem solved.

It was indeed a precision error. I now create my textures using the GL_RGBA32F_ARB format instead of GL_RGBA.

Unfortunately it has halved the framerate, but I guess I'll have to live with that.

Edit: GL_RGBA16F_ARB also works. I assumed they were already 16 bit but they must have been 8. Anyway, it's running a fair bit faster now.

[Edited by - Haptic on August 31, 2010 9:05:28 PM]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!