|
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.
Update: This works with ATI Catalyst 4.1 (and higher) drivers only.

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 Paramters:
You can access light source parameters defined in your OpenGL Program with the pre-defined uniform variable "gl_LightSource". In the C++ application you simply define values with "glLight*".
struct gl_LightSourceParameters {
vec4 ambient; // Acli
vec4 diffuse; // Dcli
vec4 specular; // Scli
vec4 position; // Ppli
vec4 halfVector; // Derived: Hi
vec3 spotDirection; // Sdli
float spotExponent; // Srli
float spotCutoff; // Crli
// (range: [0.0,90.0], 180.0)
float spotCosCutoff; // Derived: cos(Crli)
// (range: [1.0,0.0],-1.0)
float constantAttenuation; // K0
float linearAttenuation; // K1
float quadraticAttenuation;// K2
};
uniform gl_LightSourceParameters gl_LightSource[gl_MaxLights];
|
Material Parameters:
You can access the values you set in C++ with "glMaterial*" with gl_FrontMaterial and gl_BackMaterial.
struct gl_MaterialParameters
{
vec4 emission; // Ecm
vec4 ambient; // Acm
vec4 diffuse; // Dcm
vec4 specular; // Scm
float shininess; // Srm
};
uniform gl_MaterialParameters gl_FrontMaterial;
uniform gl_MaterialParameters gl_BackMaterial; |
Derived state from products of light and material:
struct gl_LightModelProducts
{
vec4 sceneColor; // Derived. Ecm + Acm * Acs
};
uniform gl_LightModelProducts gl_FrontLightModelProduct;
uniform gl_LightModelProducts gl_BackLightModelProduct;
struct gl_LightProducts {
vec4 ambient; // Acm * Acli
vec4 diffuse; // Dcm * Dcli
vec4 specular; // Scm * Scli
};
uniform gl_LightProducts gl_FrontLightProduct[gl_MaxLights];
uniform gl_LightProducts gl_BackLightProduct[gl_MaxLights]; |
Shader Source Code
Vertex Shader
varying vec3 N; varying vec3 v;
void main(void)
{
v = vec3(gl_ModelViewMatrix * gl_Vertex);
N = normalize(gl_NormalMatrix * gl_Normal);
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
} |
Fragment Shader
varying vec3 N; varying vec3 v;
void main (void)
{
vec3 L = normalize(gl_LightSource[0].position.xyz - v);
vec3 E = normalize(-v); // we are in Eye Coordinates, so EyePos is (0,0,0)
vec3 R = normalize(-reflect(L,N));
//calculate Ambient Term:
vec4 Iamb = gl_FrontLightProduct[0].ambient;
//calculate Diffuse Term:
vec4 Idiff = gl_FrontLightProduct[0].diffuse * max(dot(N,L), 0.0);
// calculate Specular Term: vec4 Ispec = gl_FrontLightProduct[0].specular
* pow(max(dot(R,E),0.0),0.3*gl_FrontMaterial.shininess);
// write Total Color:
gl_FragColor = gl_FrontLightModelProduct.SceneColor + Iamb + Idiff + Ispec;
} |
Questions:
1. Implement lighting for n lights, where n = gl_MaxLights. (note: there is no good solution for this question with current drivers yet)
2. This implementation uses point lights only. Add spot light support.
Possible solution with 2 lights:

Author: Martin Christen, christen@clockworkcoders.com
|