1// $LastChangedDate: 2009-05-19 20:41:43 -0400 (Tue, 19 May 2009) $
2// Based on osgShadow/StandardShadowMap (OpenSceneGraph Public License).
3
4/*****************************************************************************
5 * Point light (w != 0).
6 *****************************************************************************/
7void
8PointLight( in int i,
9            in vec3 eye,
10            in vec3 ecPosition3,
11            in vec3 normal,
12            inout vec4 ambient,
13            inout vec4 diffuse,
14            inout vec4 specular )
15{
16    float nDotVP;      // normal . light direction
17    float nDotHV;      // normal . light half vector
18    float pf;          // power factor
19    float attenuation; // computed attenuation factor
20    float d;           // distance from surface to light source
21    vec3  VP;          // direction from surface to light position
22    vec3  halfVector;  // direction of maximum highlights
23
24    // Compute vector from surface to light position.
25    VP = vec3(gl_LightSource[i].position) - ecPosition3;
26
27    // Compute distance between surface and light position.
28    d = length(VP);
29
30    // Normalize the vector from surface to light position.
31    VP = normalize(VP);
32
33    // Compute attenuation.
34    attenuation = 1.0 / (gl_LightSource[i].constantAttenuation +
35                         gl_LightSource[i].linearAttenuation * d +
36                         gl_LightSource[i].quadraticAttenuation * d*d);
37
38    halfVector = normalize(VP + eye);
39
40    nDotVP = max(0.0, dot(normal, VP));
41    nDotHV = max(0.0, dot(normal, halfVector));
42
43    if (nDotVP == 0.0)
44        pf = 0.0;
45    else
46        pf = pow(nDotHV, gl_FrontMaterial.shininess);
47
48    ambient += gl_LightSource[i].ambient * attenuation;
49    diffuse += gl_LightSource[i].diffuse * nDotVP * attenuation;
50    specular += gl_LightSource[i].specular * pf * attenuation;
51}
52