Spotlight shaders

I’m sure it’s been done hundreds of time, so I’m just too lazy to do it again…

Do you know where I can find a spotlight shader source code?

Here is a spotlight shader, as given in the book OpenGL Shading Language by Randi Rost. There are a couple slight changes to it, and you will want to probably make adjustments to it to take advantage of GLSL fully. This shader is meant to mimic what you would get from OpenGL Fixed Functionality, and uses built in uniform variables that access the OpenGL state, by making these user adjustable uniforms you will have more power over the final look.

Vertex Shader:

 
/************************************************************************
*                                                                       
*               
*        Copyright (C) 2002-2004  3Dlabs Inc. Ltd.                      *
*                                                                       *
*                        All rights reserved.                           *
*                                                                       *
* Redistribution and use in source and binary forms, with or without    *
* modification, are permitted provided that the following conditions    *
* are met:                                                              *
*                                                                       *
*     Redistributions of source code must retain the above copyright    *
*     notice, this list of conditions and the following disclaimer.     *
*                                                                       *
*     Redistributions in binary form must reproduce the above           *
*     copyright notice, this list of conditions and the following       *
*     disclaimer in the documentation and/or other materials provided   *
*     with the distribution.                                            *
*                                                                       *
*     Neither the name of 3Dlabs Inc. Ltd. nor the names of its         *
*     contributors may be used to endorse or promote products derived   *
*     from this software without specific prior written permission.     *
*                                                                       *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     *
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS     *
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE        *
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, *
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,  *
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      *
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER      *
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT    *
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN     *
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE       *
* POSSIBILITY OF SUCH DAMAGE.                                           *
*                                                                       *
************************************************************************/

vec4 Ambient;
vec4 Diffuse;
vec4 Specular;


    void spotLight(in int i, in vec3 normal, in vec3 eye, in vec3 ecPosition3)
    {
        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;
        Diffuse  += gl_LightSource[i].diffuse * nDotVP * attenuation;
        Specular += gl_LightSource[i].specular * pf * attenuation;

    }

    vec3 fnormal(void)
    {
        //Compute the normal 
        vec3 normal = gl_NormalMatrix * gl_Normal;
        normal = normalize(normal);
        return normal;
    }

    void flight(in vec3 normal, in vec4 ecPosition, float alphaFade)
    {
        vec4 color;
        vec3 ecPosition3;   // 3-space (non-homogeneous) eye coordinate position
        vec3 eye;

        ecPosition3 = (vec3 (ecPosition)) / ecPosition.w;
        eye = vec3 (0.0, 0.0, 1.0);

        // Clear the light intensity accumulators
        Ambient  = vec4 (0.0);
        Diffuse  = vec4 (0.0);
        Specular = vec4 (0.0);

       spotLight(0, normal, eye, ecPosition3);

        color = gl_FrontLightModelProduct.sceneColor +
                    Ambient  * gl_FrontMaterial.ambient +
                    Diffuse  * gl_FrontMaterial.diffuse;
        color += Specular * gl_FrontMaterial.specular;
        color = clamp( color, 0.0, 1.0 );
        gl_FrontColor = color;
        gl_FrontColor.a *= alphaFade;
    }  


    void main(void)
    {
        vec3  transformedNormal;
        float alphaFade = 1.0;

        // Eye-coordinate position of vertex, needed in various calculations
        vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex;

        // Do fixed functionality vertex transform
        gl_Position = ftransform();
        transformedNormal = fnormal();
        flight(transformedNormal, ecPosition, alphaFade);
    }
 

. . . and a trivial Fragment Shader

    
void main (void) 
    {
        vec4 color;

        color = gl_Color;

        gl_FragColor = color;
    }

Again, I reiterate that written as it is, this shader queries the OpenGL state and uses it, to make this more useful replace the built in uniforms with your own!

Thanks kingjosh,

I didn’t even know this book exist. Have you read it (you or anybody else)? Is it any good?

I’ll consider buying it.

Sorry for the delay in responding. I’m a bit partial (The author is my boss) . . . but yes, it is a great book. My copy is dog-eared with pages falling out, definitely was very helpful (read: a necessity) in learning GLSL! You can pick up a copy of OpenGL Shading Language at with a discount from http://www.3dshaders.com

I’ve used other books as well, but most of them are more based on shader algorithms and theory. Furthermore they use other shading languages such as Renderman, CG and HLSL.

I bought it in december :slight_smile:

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.