// $LastChangedDate: 2009-05-19 20:41:43 -0400 (Tue, 19 May 2009) $
// Based on osgShadow/StandardShadowMap (OpenSceneGraph Public License).

/*****************************************************************************
 * Spotlight.
 *****************************************************************************/
void
SpotLight( in int i,
           in vec3 eye,
           in vec3 ecPosition3,
           in vec3 normal,
           inout vec4 ambient,
           inout vec4 diffuse,
           inout vec4 specular )
{
    float nDotVP;          // normal . light direction
    float nDotHV;          // normal . light half vector
    float pf;              // power factor
    float spotDot;         // cosine of angle between spotlight
    float spotAttenuation; // spotlight attenuation factor
    float attenuation;     // computed attenuation factor
    float d;               // distance from surface to light source
    vec3 VP;               // direction from surface to light position
    vec3 halfVector;       // direction of maximum highlights

    // Compute vector from surface to light position.
    VP = vec3(gl_LightSource[i].position) - ecPosition3;

    // Compute distance between surface and light position.
    d = length(VP);
                                                                        
    // Normalize the vector from surface to light position.
    VP = normalize(VP);

    // Compute attenuation.
    attenuation = 1.0 / (gl_LightSource[i].constantAttenuation +
                         gl_LightSource[i].linearAttenuation * d +
                         gl_LightSource[i].quadraticAttenuation *d*d);

    // See if point on surface is inside cone of illumination.
    spotDot = dot(-VP, normalize(gl_LightSource[i].spotDirection));

    if (spotDot < gl_LightSource[i].spotCosCutoff)
        spotAttenuation = 0.0; // light adds no contribution
    else
        spotAttenuation = pow(spotDot, gl_LightSource[i].spotExponent);

    // Combine the spotlight and distance attenuation.                    
    attenuation *= spotAttenuation;

    halfVector = normalize(VP + eye);

    nDotVP = max(0.0, dot(normal, VP));
    nDotHV = max(0.0, dot(normal, halfVector));

    if (nDotVP == 0.0)
        pf = 0.0;
    else
        pf = pow(nDotHV, gl_FrontMaterial.shininess);

    ambient  += gl_LightSource[i].ambient * attenuation;
    diffuse  += gl_LightSource[i].diffuse * nDotVP * attenuation;
    specular += gl_LightSource[i].specular * pf * attenuation;
}                                                                        
