PDA

View Full Version : Getting World position from depth buffer in FS



al.davidson23
10-13-2010, 01:54 PM
Hey guys,
I am having some problems getting a pixels world position from the depth buffer. I am basicly trying to render a water plane in the fragment shader. for the time being just rendering the water plane red.

I am rendering a quad over the screen and passing in the depth buffer and other params into the fragment shader.

Could you guys have a quick look and see if i am missing anything glaringly obvious?

Fragment shader


uniform sampler2D depthBuf;
uniform mat4 g_ModelViewProjectionInverseMatrix;
uniform vec4 viewport;

float waterLevel = 10.0;

void main()
{

vec3 color2 = texture2D(depthBuf, vec2( gl_FragCoord.x /600.0, gl_FragCoord.y /600.0) ).rgb; //600 screen dimensions

// Sample the depth buffer (stored as float32 data)
float rawDepth = texture2D(depthBuf, vec2( gl_FragCoord.x /600.0, gl_FragCoord.y /600.0) ).r;

// Construct clip-space position using gl_FragCoord, raw
// depth value, and the GL viewport
vec4 clipPos = vec4(
2.0 * (gl_FragCoord.x - viewport.x) / viewport.z - 1.0,
2.0 * (gl_FragCoord.y - viewport.y) / viewport.w - 1.0,
2.0 * rawDepth - 1.0,
1.0
);

// Multiply by inverse projection matrix to get
// world space position
vec4 worldPos = g_ModelViewProjectionInverseMatrix * clipPos;
worldPos.xyz /= worldPos.w;

//set original colour of pixel
gl_FragColor = vec4( color2.x, color2.y, color2.z, 1.0);

//if the position of the current pixel is under water set it to red!
if(worldPos.y < waterLevel )
{
gl_FragColor = vec4( 1.0 , 0.0, 0.0 , 1.0);
}


}



Vertex shader


void main(void)
{
gl_Position = ftransform();
}


Here is how i am calculating the matrices and stuff that i am passing in to the fragment shader. (These are called after setting up the projection etc).



glGetFloatv( GL_MODELVIEW_MATRIX, modelview );
glGetFloatv( GL_PROJECTION_MATRIX, projection );
glGetFloatv( GL_VIEWPORT, viewport );

//create hte projection matrix and pass it on to the shader!

glm::mat4 glm_ProjectionMatrix;
glm::mat4 glm_ViewMatrix;


glm_ProjectionMatrix = glm::mat4( projection[0], projection[1], projection[2], projection[3],
projection[4], projection[5] , projection[6] , projection[7],
projection[8], projection[9], projection[10],projection[11],
projection[12], projection[13], projection[14],projection[15]);

glm_ViewMatrix = glm::mat4(modelview[0], modelview[1], modelview[2], modelview[3],
modelview[4], modelview[5] , modelview[6] , modelview[7],
modelview[8], modelview[9], modelview[10],modelview[11],
modelview[12], modelview[13], modelview[14],modelview[15]);



glm::mat4 glm_PModelViewMatrix = glm_ProjectionMatrix * glm_ViewMatrix ;

glm_PModelViewMatrix = glm::gtx::inverse::affineInverse(glm_PModelViewMat rix) ;
glUniformMatrix4fv(glm_ViewProjectionMatrix_id , 1, false, &amp;glm_PModelViewMatrix[0][0]); // set the shader value

//send int he viewport details!
glUniform3fv( viewportLoc, 4, &amp;viewport[0]);


As a side note i am creating my texture like this:


glGenTextures(1, &amp;depthBuf);
glBindTexture(GL_TEXTURE_2D, depthBuf);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);


Any clues?
At the moment it just renders the backbuffer back at me. What i am hoping to see is a sea of red and the tops of some triangles poking out at me.

Heres an image of what i am getting back (just the normal back buffer).

Anything glaringly obvious wrong?