Part of the Khronos Group

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 2 of 2

Thread: Deferred shader for depth, normals, and position

  1. #1
    Newbie Newbie
    Join Date
    Nov 2012

    Deferred shader for depth, normals, and position

    I'm trying to get a deferred shader working for depth, normals, and position. The first two seem to be working, but the last one is causing problems.

    Code :
    varying float depth;
    varying vec3 normal;
    varying vec3 eye;
    void main()
      // get the depth and eye position
      vec4 transformedVertex = gl_ModelViewMatrix * gl_Vertex;
      depth = -transformedVertex.z;
      eye =;
      // transform normals to the current view
      normal = normalize(gl_NormalMatrix * normalize(gl_Normal));
      gl_Position = ftransform();

    Code :
    varying float depth;
    varying vec3 normal;
    varying vec3 eye;
    void main()
      float near = 1.3;
      float far = 2.5;
      // get shifted versions for better visualization
      float depthShift = (depth - near) / (far - near);
      vec3 normalShift = (normal + vec3(1.0)) * 0.5;
      gl_FragData[0] = vec4(normalShift, depthShift);
      gl_FragData[1] = vec4(normalize(eye), 1.0);
    Side question for above: why is the depthShift and normalShift necessary?

    Code :
    uniform sampler2D depthTexture;
    uniform sampler2D eyeTexture;
    uniform int renderType;
    void main() 
      // pull everything we want from the textures
      float depth   = texture2D(depthTexture, gl_TexCoord[0].st).a; // depth in eye coordinates
      vec3 normal   = texture2D(depthTexture, gl_TexCoord[0].st).rgb; // normal in eye coordinates
      vec3 frag     = texture2D(eyeTexture,   gl_TexCoord[0].st).rgb; // position of frag in eye coordinates
      normal = normal * 2.0 - vec3(1.0);
      normal = normalize(normal);
      if(renderType == 1) // normals
        color = vec3(normal);
      else if(renderType == 2) // depth
        color = vec3(depth);
      else if(renderType == 3) // position
        color = vec3(frag);
      gl_FragColor = vec4(vec3(color), 1.0);

    When I run this for renderType == 3 (position), all the objects in the scene are pure blue. The normals and the depths seem to both be working, but the position doesn't work. Can someone point me in the right direction?

    Last edited by take2316; 11-24-2012 at 07:20 PM.

  2. #2
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Your "position" channel logic is confusing. It is not an eye-space position. It's a unit vector (not a position) in some negated EYE-SPACE.

    Code glsl:
    vec4 transformedVertex = gl_ModelViewMatrix * gl_Vertex;
    eye =;
     gl_FragData[1] = vec4(normalize(eye), 1.0);

    Also, you'll notice that the "blue" in your bunny is not 100% blue but mostly blue. And if you adjust the contrast to focus in on the dynamic range of the blues, you'll see a quantized radially-decreasing gradient, which you'd expect from an eye-space vector from the origin. Similarly, if you mask the blue and gain-up the red and green, you'll see what you'd expect from a unit vector in negated eye-space (see below).

    There are all kinds of ways to fry this "position from depth" fish, but suggest you just write an ordinary depth buffer (window-space depth), which the normal Z-buffer rendering pipeline will do for you, and then use the PositionFromDepth_DarkPhoton() method at the end of this post (or something similar) to reconstruct eye-space position. Matt Pettineo has a bunch more options in his blog with analysis.
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	2emcsc2.contrast.jpg 
Views:	372 
Size:	6.8 KB 
ID:	910   Click image for larger version. 

Name:	2emcsc2.rg_contrast.jpg 
Views:	428 
Size:	6.4 KB 
ID:	911  
    Last edited by Dark Photon; 11-27-2012 at 05:39 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts