Albedo and Light Color

In which you give the surface and light source their own colors.

Litness is a proportion that measures how much a fragment's normal points toward the light. A value of 1 means the surface receives 100% of the light. This line from the fragment shader effectively makes all of that light bounce back into the eye:

fragmentColor = vec4(vec3(litness), 1.0);

In nature, not all light is reflected. Some is absorbed. The proportion of light that is reflected is sometimes called albedo, a word that has the some root as albino. In computer graphics, albedo is effectively the surface's base color. A yellow surface has an albedo of \(\begin{bmatrix}1&1&0\end{bmatrix}\), which means it reflects all red and green light.

This fragment shader applies the litness proportion to the fragment's albedo to compute the diffuse term:

uniform vec3 albedo;
// ...

void main() {
  // ...
  vec3 diffuse = litness * albedo;
  fragmentColor = vec4(diffuse, 1.0);
}

The albedo here is a uniform. As you have seen, it could also be an interpolated vertex attribute.

Just as a surface's material properties influence the light that reaches the eye, so does the light source itself. The light may generate varying amounts of red, green, and blue light. The light color is another set of proportions that can be applied to the diffuse term:

uniform vec3 diffuseColor;
uniform vec3 albedo;
// ...

void main() {
  // ...
  vec3 diffuse = litness * albedo * diffuseColor;
  fragmentColor = vec4(diffuse, 1.0);
}

In the previous renderers, the light color has been implicitly white. You have now broken free and can make lights whatever color you like. The interaction between albedo and light color can be difficult to reason about, however. Consider this torus with a magenta albedo:

The diffuse light color is orange, which cancels out all the blue frequencies from the magenta albedo, leaving only red.