screen space to world position using depth texture


i´m having this problem for quite some time, i want to be able to get a valid world coordinate from a sample pixel from the depth texture in the fragment shader, i´m rendering the geometry throught 3 textures : normal, difuse and depth.
I just wanted to be able some how to “test” if i´m doing the right calculations to see if in fact the position is “true”.

I´ll post the vertex shader and the pixel shader, but right now i get nothing but a black screen if i try to “see any world space position” maybe i´m doing something really wrong…

Vertex Shader:

varying vec2 TexCoord;
varying vec4 Position;

void main()
    gl_Position = ftransform();
    TexCoord = vec2(gl_MultiTexCoord0);
    Position = gl_Position;

Fragment Shader:

uniform sampler2D NormalTex;		
uniform sampler2D DiffuseTex;		
uniform sampler2D DepthTex;			 

uniform mat4 ModelViewInv;		
uniform mat4 ProjInv;	    

varying vec2 TexCoord;				
varying vec4 Position;	

void main()

	vec4 viewport = vec4(0,0,512,512);
	vec2 Cam = vec2(1.0,325.0);
	vec4 normal = texture2D(NormalTex,TexCoord);
	vec4 difuse = texture2D(DiffuseTex,TexCoord);
	float depth = texture2D(DepthTex,TexCoord).r;
	//compute screen-space position
    vec4 position;
    position.x = TexCoord.x * 2.0 - 1.0;
    position.y = -TexCoord.x * 2.0 - 1.0;
    position.z = depth;
    position.w = 1.0;

	//transform to world space
    position = position * ModelViewInv * ProjInv;
    position /= position.w;

	gl_FragData[0] = difuse * normal * position;


position = ModelViewInv * ProjInv * position;

What is this supposed to do?

gl_FragData[0] = difuse * normal * position;

hello skynet,

for now i would just like to see some geometry being “rebuilt” never mind about that line it´s just a test for me to try and see “anything”…

I´ll try that and i´ll get to you with some feedback…
Thanks for the anwser.

Cherrs :slight_smile:

A few days ago I created my first (very simple) deferred renderer. To check whether the calculation to world position from the depth texture was correct, I did the following:

// vertex shader used to fill the g-buffer
#version 150

in vec4 vertex;

uniform mat4x4 modelviewMatrix;
uniform mat4x4 projectionMatrix;

smooth out vec3 worldPosition;

void main(void)
  // this variable is used to check whether later on whether
  // the calculation is correct
  worldPosition = (modelviewMatrix * vertex).xyz;

  gl_Position = projectionMatrix * modelviewMatrix * vertex;

// fragment shader to fill the g-buffer
#version 150

smooth in vec3 worldPosition;
out vec3 frag;

void main(void)
  // write the world position to a texture bound to `frag'
  // in this case I used my GL_RGB16F normal texture temporarily
  // for testing, I think a texture with less precision would
  // cause more artifacts

  frag = worldPosition;

Now the glsl code for checking whether you calculate the right world position when rendering from the g-buffer.

// fragment shader for drawing from the g-buffer
#version 150

sampler2D depth_sampler;
sampler2D worldpos_sampler;

in vec2d texcoord;

out vec4 frag;

void main(void)
  // read the depth from the depth texture
  float depth = texture(depth_sampler, texcoord).x;

  // calculate the world position from the depth
  // (assumes you are doing the calculation to obtain the
  // world position in the function `my_worldpos_calculator)
  vec3 calculated_worldpos = my_worldpos_calculator(depth);

  // read the stored world postion
  vec3 stored_worldpos = texture(worldpos_sampler, texcoord);

  // now the check:

  frag.a = 0.0;

  // get the absolute difference from the value you've stored
  // (and thereby you now it is correct) and the value you've
  // calculated = abs(calculated_worldpos - stored_worldpos);

This code should render your geometry in black (meaning there is no difference in the calculated world postion and the stored world postion).

To calculate the world position from the depth, I used a formula found in another topic about deferred shading (although I had to change some signs in this calculation, I’ll have to check later on what caused the difference):

hello heiko,

thanks to you i got things working, so now i can see the geometry and also recovering the world position form the depth is much faster than getting it with the inverse of model and projection matrixes.

So thanks to both of you, now i got things rollin´ :slight_smile: