Rendering normals in eye space

Rendering Methods | Thursday 25 September 2008 12:46 am

Here’s a simple shader for rendering the normals in a scene in eye space. This shader can be useful for debugging or then you want to do SSAO or edge detection. Below is a rendering of the normals of a sphere in eye space.

Normals in screen space

Vertex shader:

varying vec3 normal;
void main()
{
   gl_Position = ftransform();
   normal = gl_NormalMatrix * gl_Normal;
}

Fragment shader:

varying vec3 normal;
void main()
{
   gl_FragColor.rgb = normal;
}

If you want to save it in a RGB texture then you need to convert the normal to the 0..1 range with the following normal = (normal + 1.0) / 2.0 .

The same shader can be used to render the tangent or binormal in screen space too. Just switch the gl_Normal to your other input.

Please share:
  • Print this article!
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Current
  • LinkedIn
  • Live
  • MySpace
  • Netvibes
  • StumbleUpon
  • Twitter
  • Reddit
  • Technorati
  • Yahoo! Bookmarks

4 Comments »

  1. Comment by Matt — January 20, 2009 @ 1:48 am

    How are the ‘varying’ variables dealt with? There are normally a different number of fragments to vertices, so how does the pipeline know what the value of (in the above case) ‘normal’ is?

  2. Comment by admin — January 20, 2009 @ 2:01 am

    This solution does not work with normal mapping if that’s what your asking for?

    You can read about varying variables here if that’s what your wondering about.
    http://www.lighthouse3d.com/opengl/glsl/index.php?varying

  3. Comment by Max — February 20, 2009 @ 6:44 am

    Did you mean: “gl_NormalMatrix” instead of “gl_ModelViewMatrix”?

    If I understand you correctly, you want to move normals from
    object’s coordinate system to eye coordinate system.
    The transformation from one to another, transforms only points
    and tangent vectors correctly (the later is true as long as it’s
    linear), however normals won’t be transformed correctly this way.
    One easy explanation is (M is 3×3):
    cross(M*v1,M*v2)==transpose(adj(M))*cross(v1,v2)!=M*cross(v1,v2)
    Actually there will be equality iff M is special orthogonal.

    Or maybe you wanted to do something else, and I totally misunderstood you?

  4. Comment by admin — February 22, 2009 @ 7:18 pm

    Yes, you’re correct, it’s wrong and I will fix it. Thanks for pointing it out.

    I think it was the wrong code I posted. Was a while since I wrote it so I don’t remember exactly what this code should do. Maybe normals in screen space? =/

RSS feed for comments on this post. TrackBack URI

Leave a comment