10.3 - The Color of a Light Source

If you shine a red light onto a blue object you see black! In lesson 10.1 we discussed that when you see a blue object you are seeing a blue light ray that was reflected from the object. The ray is blue because the object absorbed all of the non-blue light. This lesson discusses how to model the color of a light source.

The Math for Light Color

A light source is assigned an RGB color that represents its intensity of red, green and blue light. White light has a color of (1,1,1) while a red light has a color of (1,0,0).

To simulate a light’s color it is multiplied, component-by-component, times a surface’s color to determine the final color of a surface. For example, if a surface has a color of (1.00, 0.76, 0.12), and a light source has a color of (1.0, 0.0, 0.5), then the color of the surface would be calculated as (1.00*1.0, 0.76*0.0, 0.12*0.5), or (1.0, 0.0, 0.06). Notice that since the light source contains no amount of green light, all of the surface’s green color goes to zero. The surface can’t reflect green light because there is no green light from the light source to reflect.

A WebGL Program for the Color of a Light Source

Experiment with the following WebGL program. Note that although the objects in the scene might appear to be solid colors, they are actually not pure colors. The objects have the following colors:

Object Color Comments
“red cube” (0.640000, 0.150003, 0.109216) Mostly red, some green and blue.
“red letter X” (0.800000, 0.000000, 0.000000) All red.
“green cube” (0.310609, 0.640000, 0.346694) Mostly green, significant red and blue.
“green letter Y” (0.000000, 0.800000, 0.000000) All green.
“blue cube” (0.075294, 0.285289, 0.800000) Mostly blue, very little red.
“blue letter Z” (0.000000, 0.000000, 0.800000) All blue.

Experiment with the Color of a Light

Virtual World  Rendering with diffuse lighting.
Please use a browser that supports "canvas"   Please use a browser that supports "canvas"
camera eye (0.0, 0.0, 5.0) camera center (0.0, 0.0, 0.0)
X: -5.0 +5.0 X: -5.0 +5.0
Y: -5.0 +5.0 Y: -5.0 +5.0
Z: -5.0 +5.0 Z: -5.0 +5.0
light position (3.0, 0.0, 5.0) light color (1.00, 1.00, 1.00)
X: -5.0 +5.0 Red: 0.0 1.0
Y: -5.0 +5.0 Green: 0.0 1.0
Z: -5.0 +5.0 Blue: 0.0 1.0

Open this webgl demo program in a new tab or window

As you experiment with the WebGL program, please make sure you observe the following characteristics of light color.

  • Setting the light source to a red light, (1,0,0), gives the entire object a “reddish hue” and the blue cube appears black. This is due to the fact that the red component of the blue cube’s color, (0.07, 0.28, 0.8) is so small, 0.07.
  • Setting the light source to a green light, (0,1,0), gives the entire object a “greenish hue”. Every object has enough green in its color, except the “red X” and the “blue Z”, to give off some green reflected light.

Light Color in Shader Programs

Please study the following shader programs using the comments below as your guide.

Vertex Shader

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// Vertex Shader
precision mediump int;
precision mediump float;

// Scene transformations
uniform mat4 u_To_clipping_space; // Projection, camera, model transform
uniform mat4 u_To_camera_space;   // Camera, model transform

// Light model
uniform vec3 u_Light_position;
uniform vec3 u_Light_color;

// Original model data
attribute vec3 a_Vertex;
attribute vec3 a_Color;
attribute vec3 a_Normal;

// Values initialized for the fragment shader (interpolated values)
varying vec3 v_Vertex;
varying vec4 v_Color;
varying vec3 v_Normal;

void main() {

  // Perform the model and view transformations on the vertex and pass
  // this location to the fragment shader.
  v_Vertex = vec3( u_To_camera_space * vec4(a_Vertex, 1.0) );

  // Perform the model and view transformations on the vertex's normal
  // vector and pass this normal vector to the fragment shader.
  v_Normal = vec3( u_To_camera_space * vec4(a_Normal, 0.0) );

  // Pass the vertex's color to the fragment shader.
  v_Color = vec4(a_Color, 1.0);

  // Transform the location of the vertex for the graphics pipeline
  gl_Position = u_To_clipping_space * vec4(a_Vertex, 1.0);
}
Line(s) Description
11 u_Light_color is a uniform variable for the vertex shader.

Fragment Shader

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// Fragment shader program
precision mediump int;
precision mediump float;

// Light model
uniform vec3 u_Light_position;
uniform vec3 u_Light_color;

// Data coming from the vertex shader
varying vec3 v_Vertex;
varying vec4 v_Color;
varying vec3 v_Normal;

void main() {

  vec3 to_light;
  vec3 fragment_normal;
  float cos_angle;

  // Calculate a vector from the fragment location to the light source
  to_light = u_Light_position - v_Vertex;
  to_light = normalize( to_light );

  // The fragment's normal vector is being interpolated across the
  // geometric primitive which can make it un-normalized. So normalize it.
  fragment_normal = normalize( v_Normal);

  // Calculate the cosine of the angle between the vertex's normal
  // vector and the vector going to the light.
  cos_angle = dot(fragment_normal, to_light);
  cos_angle = clamp(cos_angle, 0.0, 1.0);

  // Scale the color of this fragment based on its angle to the light.
  // Don't scale the alpha value, which would change the transparency
  // of the fragment
  gl_FragColor = vec4(vec3(v_Color) * u_Light_color * cos_angle, v_Color.a);
}
Line(s) Description
7 u_Light_color is a uniform variable for the fragment shader.
36 The color of the light source, u_Light_color, is multiplied times the color of the surface, v_Color. In GLSL, when two vectors are multiplied together, the default operation is an element-by-element multiplication. For example, (v_Color[0]*u_Light_color[0], v_Color[1]*u_Light_color[1], v_Color[2]*u_Light_color[2])

Summary

Modeling the color of a point light source required a very small change to previous diffuse reflection code. The remaining lighting models in this chapter include the modeling of a light source’s color.

Glossary

light color
An RGB, (red, green, blue), value that describes the color of a light source.

Self Assessment

    Q-217: A flashlight that shines a pure blue light would have a color of?

  • (0.0, 0.0, 1.0)
  • Correct.
  • (1.0, 0.0, 0.0)
  • Incorrect. This is a red light.
  • (1.0, 1.0, 1.0)
  • Incorrect. This is a white light.
  • (1.0, 1.0, 0.0)
  • Incorrect. This is a yellow light.

    Q-218: When a light defined by a color of (1, 0.5, 0.8) shines on a pixel whose color is (0.1, 0.2, 0.3), what would be the color of the rendered pixel?

  • (0.1, 0.1, 0.24)
  • Correct. You multiply the pixel’s color times the color of the light.
  • (1, 0.5, 0.8)
  • Incorrect.
  • (1.0, 1.0, 1.0)
  • Incorrect.
  • (0.1, 0.2, 0.3)
  • Incorrect.
Next Section - 10.4 - Specular Lighting