Course list http://www.c-jump.com/bcc/

Diffuse and Specular Light


  1. Directional lights
  2. Point lights
  3. Lighting models
  4. Useful concepts
  5. Light components and color range
  6. Light component types
  7. Diffuse lighting
  8. Diffuse lighting
  9. Diffuse lighting, cont.
  10. Diffuse lighting in vertex shader
  11. Translating normal vectors into the world space
  12. Rotating light
  13. The smooth type qualifier
  14. Diffuse lighting in fragment shader
  15. Specular light
  16. Specular light shininess
  17. Specular light example
  18. Sources of lights

1. Directional lights


2. Point lights



3. Lighting models



4. Useful concepts



5. Light components and color range



6. Light component types



7. Diffuse lighting


  • Diffuse lighting is also known as Lambertian reflectance

  • Lambertian diffuse reflection model proposes a formula to compute the intensity of the reflected light.

  • Lambertian model is good for rough surfaces without specular highlights.

  • diffuse light

    The model assumes that the light falling on a surface appears the same regardless of the observer's viewpoint.


8. Diffuse lighting


  •                 L·N
        cos(a) = _________
                   |L||N|

    • Please note that lighting direction L is from the surface towards the light.

    • The angle between the surface normal and the light source vector is called the angle of incidence of the light

  • Lambertian reflectance

  • L – the incoming light vector

  • N – the normal of the plane/vertex


9. Diffuse lighting, cont.


  • If vectors L and N are normalised, cos(a) is the dot product:

    • cos(a) = L·N

  • The diffuse intensity Id is computed by adding the diffuse component of the object's material, Kd:

    • Id = Kd * L·N

  • In practice, we need to avoid negative L·N values:

    • Id = Kd * max( L·N, 0 )

  • Also, we can now easily add ambient light Ia to the result:

    • Id = max(
               Kd * max( L·N, 0 ),
               Ia
              )

  • where Ia is the ambient light intensity.

  • Lambertian reflectance

  • L – the incoming light vector

  • N – the normal of the plane/vertex


10. Diffuse lighting in vertex shader


  • Vertex shader

    
    #version 130
    
    in vec4 s_vPosition;
    in vec4 s_vNormal;
    
    uniform mat4 mM;    // model matrix
    uniform mat4 mV;    // camera view matrix
    uniform mat4 mP;    // perspective matrix
    
    uniform mat4 mRotations; // all model rotations matrix
    
    uniform vec4 vLight; // direction of light
    
    smooth out vec4 interpolated_color;
    
    void main () {
        
        // Rotate the normal and use as vec3:
        // No need tp normalize after rotation since it remains a unit vector:
        vec3 normal_in_cam_space = (mRotations*s_vNormal).xyz;
        // The angle between the surface normal and the light source vector
        // is called the angle of incidence of the light:
        float cos_incidence = dot( normal_in_cam_space, vLight.xyz );
        // Note that cosine of the angle of incidence can become negative
        // for angles greater than 90 degrees, hence we use the clamp() to
        // keep it in range from zero to one:
    	cos_incidence = clamp( cos_incidence, 0, 1 );
        vec4 light_color = vec4( 1.0, 1.0, 0.0, 1.0 ); // R + G = yellow
        interpolated_color = vec4( light_color.rgb * cos_incidence, 1.0);
    
        gl_Position = mP*mV*mM*s_vPosition;
    }
    
    
  • Fragment shader

    
    #version 130
    
    smooth in vec4 interpolated_color;
    
    out vec4 fColor;
    
    void main()
    {
    	fColor = interpolated_color;
    }
    
    

11. Translating normal vectors into the world space



12. Rotating light



13. The smooth type qualifier



14. Diffuse lighting in fragment shader


  • Vertex shader

    
    #version 130
    
    in vec4 s_vPosition;
    in vec4 s_vNormal;
    
    uniform mat4 mM;    // model matrix
    uniform mat4 mV;    // camera view matrix
    uniform mat4 mP;    // perspective matrix
    
    uniform mat4 mRotations; // all model rotations matrix
    
    uniform vec4 vLight; // direction of light
    
    out vec3 fN; // output of the normal
    out vec3 fL; // output of light vector
    
    void main () {
        
        // Rotate the normal and pass on as vec3
        fN = (mRotations*s_vNormal).xyz;
        fL = vLight.xyz;
        
        // From local, to world, to camera, to NDCs
        gl_Position = mP*mV*mM*s_vPosition;
    }
    
    
  • Fragment shader

    
    #version 130
    
    in vec3 fN;
    in vec3 fL;
    
    out vec4 fColor;
    
    void main () {
        // NOTE: We ALWAYS need to normalize the vectors after interpolation!
        vec3 N = normalize(fN);
        vec3 L = normalize(fL);
        float diffuse_intensity = max(dot(N, L), 0.0);
        vec4 light_color = vec4( 1.0, 1.0, 0.0, 1.0); // R + G = yellow
        fColor = light_color * diffuse_intensity; // yellow diffuse light
    }
    
    

15. Specular light


  • Blinn-Phong shading model is based on lighting calculation per pixel, so it has to be implemented in the fragment shader.

  • The specular light is based on the half-vector.

  • According to the model, the intensity of specular light component is based on the cosine of the angle between the half vector and the normal.

  • The intensity of the specular light Is is

    • Is = ( N·H )shininess

    where H is the half-vector

  • In practice, GLSL formula becomes

    
      float Is = pow( max( dot( N, H ), 0.0), shininess );
    
    
  • specular light

  • Blinn-Phong light model is based on the half-vector:

  • L – the incoming light vector

  • N – the normal of the plane/pixel

  • E – the vector from the pixel to the camera

  • H – the half-vector: H = L + -E

     


16. Specular light shininess


  • specular light shininess 1

  • shininess close to 1

  • specular light shininess 30

  • shininess 30

  • specular light shininess 255

  • shininess 255


17. Specular light example


  • Vertex shader:

    
    #version 130
    
    in vec4 s_vPosition;
    in vec4 s_vNormal;
    
    uniform mat4 mM;    // model matrix
    uniform mat4 mV;    // camera view matrix
    uniform mat4 mP;    // perspective matrix
    
    uniform mat4 mRotations; // all model rotations matrix
    
    uniform vec4 vLight; // direction of light
    
    out vec3 fN; // output of the normal
    out vec3 fL; // output of light vector
    out vec3 fE; // vector between the camera and a vertex
    
    void main () {
        
        // Rotate the normal and pass on as vec3
        fN = (mRotations*s_vNormal).xyz;
        fL = vLight.xyz;
        // vertex is relative to the camera:
        fE = (mV*mM*s_vPosition).xyz;
        
        // From local, to world, to camera, to NDCs
        gl_Position = mP*mV*mM*s_vPosition;
    }
    
    
  • Fragment shader:

    
    #version 130
    
    in vec3 fN;
    in vec3 fL;
    in vec3 fE; // interpolated from the vertex shader
    
    out vec4 fColor;
    
    void main () {
        // ALWAYS normalize the vectors after interpolation:
        vec3 N = normalize(fN);
        vec3 L = normalize(fL);
        // Reverse E: becomes vector from pixel to camera:
        vec3 E = normalize(-fE);
        vec3 H = normalize( L + E ); // Create the half vector    
    
        float diffuse_intensity = max(dot(N, L), 0.0);
        vec4 diffuse_color = vec4( 0.5, 0.2, 0.0, 1.0 ); // dark orange
        diffuse_color = diffuse_color * diffuse_intensity;
    
        float shininess = 30.0;
        float specular_intensity = pow(max(dot(N, H), 0.0), shininess);
        vec4 specular_color = vec4( 0.9, 0.1, 0.1, 1.0 ); // red
        specular_color = specular_intensity * specular_color;
        //fColor = diffuse_color; // only diffuse light
        //fColor = specular_color; // only specular light
    
        // dark orange with bright specular red:
        fColor = diffuse_color + specular_color;
    }
    
    

18. Sources of lights