Per Fragment Lighting
In OpenGL Shading language you can access built in OpenGL lighting states. Implementing an advanced lightning model would be compatible with standard OpenGL statements.
Accessing Lighting States
You can access all OpenGL Lighting states and some derived states. The following tables can also be found in the OpenGL Shading Language specification:
Light Source Parameters
gl_LightSource is a built-in array you can access for all lights. gl_LightSource is defined this way:
You can access the values you set in C++ with glMaterial using the GLSL built-in variables gl_FrontMateral and gl_BackMaterial.
Derived State from Products of Light and Material
A shading model is a mathematical representation of the surface characteric of an object.
Diffuse Reflection (Lambert's cosine law)
The angle between the two vectors, is called the angle of incidence. Lambert's law states that the amount of reflected light is proportional to the cosine of the angle of incidence (dot product). A surface is illuminated by a light source only if the angle of incidence is between 0 and 90 degrees.
The current vertex position is transformed to eye space. This is done by multiplying the modelview matrix with the vertex position. The normal is passed to the fragment shader.
Lambert's Law is calculated for every fragment. Please note that the normal is an interpolated value and is may not be normalized, this is disregarded because the error is small.
Image: Specular Term
Specular reflection is the direct reflection of light by a surface. Shiny surfaces reflect almost all incident light and therefore have bright specular highlights or hot spots. The location of a highlight moves as you move your eye, while keeping the light source and the surface at the stationary positions. In order to make a surface mirror-like, decrease the diffuse reflection and increase the specular reflection.
Image: Ambient Term
Ambient reflection is a gross approximation of multiple reflections from indirect light sources (e.g., the surfaces of walls and tables in a room that reflect off the lights from light sources). Ambient reflection produces a constant illumination on all surface, regardless of their orientation. If you look at the faces of a cube to which only ambient reflection is applied, all the faces are illuminated by the same amount of light. Ambient reflection itself produces very little realism in images.
Some famous shading models are:
Phong Shading Model
Bui Tuong Phong published his illumination model in 1973: "Illumination for Computer-Generated Images".
Blinn-Phong Shading Model
This model was introduces by Blinn, James F. Models of Light Reflection for Computer Synthesized Pictures. Computer Graphics (SIGGRAPH 77 Proceedings) 11(2) July 1977, p. 192-198.
Cook-Torrance Shading Model
Robert L. Cook, Kenneth E. Torrance, A reflectance model for computer graphics, 1982.
Schlick Shading Model
This lighting model was created by Christophe Schlick, A Customizable Reflectance Model for Everyday Rendering, Fourth Eurographics Workshop on Rendering, 1993.
Implementing Phong Shader (for one Point-Light)
Using More Lights
To support more than one light you can simply add a loop to the fragment shader. For reasons of performance it is not a good idea to use a uniform variable for the loop, therefore the best approach is to compile different shaders for different numbers of lights. (Only the fragment shader changes, the vertex shader is same as above.)
In this example project the phong shader with 1 light is included. You can use this as base to implement it to support more lights and/or different shading models.
GLSL_Lighting.zip (Visual Studio 8 Project)