0
votes
#version 150
uniform float shade;
in vec3 cshade;
in vec3 v_o;
in vec3 locallight_o;
in vec3 n;
in float shadescale_o;
out vec4 pixelcolour;
void main( )
{
    float shadescale;
    shadescale=shadescale_o;
    vec3 vn,l,ln,nn,h,hh;
    vec3 ambient = vec3(0.4,0.4,0.4);       // ambient light    

   vn=normalize(v_o);
    ln=normalize(locallight_o);
    if (dot(ln,n)<0)
    {
        h=vn-ln;//light direction shines from source to object
        hh=h;
        h=normalize(h);
        nn=normalize(n);
        shadescale= dot(h,nn);//inward normal
        if (shadescale<0)
            shadescale=0;
        shadescale*=shadescale;
        shadescale*=shadescale;
    }
    else
    shadescale=0;

    // Get pixel colour from input shade
    if (shade>=0.5)
    {       
        pixelcolour = vec4( (cshade * shadescale) + (ambient * cshade), 1.0 );  // ambient lighting     

        //pixelcolour = vec4( (cshade*ambient)+ambient, 1.0 );
        //pixelcolour += vec4(ambient, 1.0);
    }
    else
    {
        pixelcolour = vec4( (cshade * shadescale_o) + (ambient * cshade), 1.0 );

        //pixelcolour = vec4( (cshade*ambient)+ambient, 1.0 );      
        //pixelcolour += vec4(ambient, 1.0);

    }               

}

The above code is a straight forward pixel shader, used in an openGL framework that shows a cube. Currently ambient lighting has been implemented, but how do I go about adding diffuse and specular reflection (not simultaneously of course!) to this code? I understand I will need some extra uniforms i.e. vec3's called diffuse and specular, but what exact operations should I perform?

1

1 Answers

1
votes

I'm not going to paste the code into here, but the answer to all your questions is http://www.lighthouse3d.com/opengl/glsl/index.php?lights.

In a nutshell, diffuse = -dot(normal, lightDir). Why? Well the dot product evaluates the "sameness" of two vectors, yeilding 1 if they are the same, 0 if they are at right angles, and -1 if they are opposite. If the normal of the face is pointing directly into the light(normal and lightDir are opposite), it should take on the maximum value. If the light is shining in on an angle, the dot product returns a value closer to 0, making the final lighing value next.

It should be noted that lightDir and normal must be normalized.