I know this has been asked a lot of time before but none of those answers fixed my problem. I try to implement deferred shading and to do so I need to reconstruct the world space position from the depth. (Having a position texture in the gbuffer would be a waste of data)

The calculation works fine for rotationing the camera (-> moving the mouse) but as soon as I move the camera (-> pressing wasd) they get weird.

Cube front Cube with camera rotated (correct) Cube front with camera moved (incorrect) Cube with camera moved and rotated (incorrect)


vec4 screenSpacePosition = vec4(pass_Texture * 2.0 - 1.0, texture(gbuffer_texture[2],     pass_Texture).r, 1);
vec4 worldSpacePosition = invertedViewProjection  * screenSpacePosition;
vec3 finalPosition = worldSpacePosition.xyz / worldSpacePosition.w;

gbuffer_texture[2] is the depth attachment of OpenGL. invertedViewProjection is the matrix I used to render the scene inverted on the CPU.

  • \$\begingroup\$ What's your question/problem? \$\endgroup\$ – Fault Mar 9 '14 at 23:07
  • \$\begingroup\$ @Fault Facepalm@me. I would help to descripe the problem. \$\endgroup\$ – user205695 Mar 9 '14 at 23:10
  • \$\begingroup\$ You need to use a linear depth value for your computation (mapped to the range [-1, 1]). Check out the answer over here for how to get the linear value: stackoverflow.com/questions/19750351/… \$\endgroup\$ – Fault Mar 9 '14 at 23:47

The result sampled from gbuffer_texture[2] will be in the [0, 1] range, but in OpenGL, NDC space ranges from -1 to 1 along all three axes. (This is different from D3D, where the NDC space ranges from 0 to 1 along the z axis.)

So, you need to multiply the depth result by 2 and subtract 1 to convert the range to [-1, 1], just as you're doing already for the xy components of screenSpacePosition. Then you'll have the proper NDC position, and you can apply the inverse view-projection matrix as you're doing.

FYI, there are more optimized ways to do this that don't require a full matrix multiply per pixel. However, it's a good idea to get things working in a simple way first (which you're doing) before attempting more optimized approaches. Some optimizations that can be done are discussed in Matt Pettineo's Position From Depth article.

  • \$\begingroup\$ Thank you so much. I had been thinking about this solution a few times already but never tried it. \$\endgroup\$ – user205695 Mar 10 '14 at 17:46
  • \$\begingroup\$ @user205695 If you return to the site, perhaps check the checkbox beside Nathan's answer. \$\endgroup\$ – Engineer Mar 3 '15 at 10:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.