Upcoming Events
VIEW Conference 2009
11/4 - 11/7 @ Turin, Italy

Project Horseshoe
11/5 - 11/8 @ Burnet, TX

Independent Game Conference West
11/5 - 11/6 @ Los Angeles, CA

IGDA Leadership Forum
11/12 - 11/13 @ San Francisco, CA

More events...


Quick Stats
6350 people currently visiting GDNet.
2337 articles in the reference section.

Help us fight cancer!
Join SETI Team GDNet!



Link to us

Link to us

  search:   

Creating a GLSL Library


A One-Sided Per-Pixel Lighting Example

This example is fairly complicated so the discussion is broken up into parts. The first part will be the vertex shader. Since we're doing everything in the pixel shader, the vertex shader is fairly simple.

/**
 * \file Lighting.vert
 */
varying vec3 normal;
varying vec3 vertex;

void main()
{
    // Calculate the normal
    normal = normalize(gl_NormalMatrix * gl_Normal);
   
    // Transform the vertex position to eye space
    vertex = vec3(gl_ModelViewMatrix * gl_Vertex);
       
    gl_Position = ftransform();
}
All thats happening in the vertex shader is passing along the normal and the position of the vertex to the fragment shader. These values are needed for the lighting calculations coming in the fragment shader.
/**
 * \file OneSidedLighting.frag
 */
void calculateLighting(in int numLights, in vec3 N, in vec3 V, in float shininess,
                       inout vec4 ambient, inout vec4 diffuse, inout vec4 specular);

varying vec3 normal;
varying vec3 vertex;

void main()
{
    // Normalize the normal. A varying variable CANNOT
    // be modified by a fragment shader. So a new variable
    // needs to be created.
    vec3 n = normalize(normal);
   
    vec4 ambient  = vec4(0.0);
    vec4 diffuse  = vec4(0.0);
    vec4 specular = vec4(0.0);

    // In this case the built in uniform gl_MaxLights is used
    // to denote the number of lights. A better option may be passing
    // in the number of lights as a uniform or replacing the current
    // value with a smaller value.
    calculateLighting(gl_MaxLights, n, vertex, gl_FrontMaterial.shininess,
                      ambient, diffuse, specular);
   
    vec4 color = gl_FrontLightModelProduct.sceneColor  +
                 (ambient  * gl_FrontMaterial.ambient) +
                 (diffuse  * gl_FrontMaterial.diffuse) +
                 (specular * gl_FrontMaterial.specular);
                
    color = clamp(color, 0.0, 1.0);
   
    gl_FragColor = color;
}
Now if this were some shader library we were integrating into our own shaders the only thing we'd need to know is the interface for the function. From there we'd assume that it was doing the proper calculations and just leave it at that. But since this is a library that we're creating lets go over the functions of the Lighting library.



The Phong Lighting Shader

Contents
  Introduction
  A Texturing Example
  A Multi-Texturing Example
  A One-Sided Per-Pixel Lighting Example
  The Phong Lighting Shader
  A Two-Sided Per-Pixel Lighting Example
  Conclusion

  Source code
  Printable version
  Discuss this article