Ambient Term
Find a chair and look underneath it. What color do you see? The bottom of its seat is probably not pitch black. Even though the bottom doesn't face a light source, it still receives the light that bounces indirectly off of other surfaces in the environment. However, suppose you rendered the chair using the lighting model that we've seen so far. The bottom of the seat would be pitch black because it faces away from the overhead light source.
The light source in this renderer is positioned inside the torus, and the outside faces, whose normals point away from the light, are pitch black:
In a real environment, light would bounce off walls and other surface to illuminate these outer surfaces. In a virtual environment, tracing light as it bounces around a scene is expensive. Many renderers therefore make no attempt at illuminating surfaces with anything but direct rays of light. Instead we give the illusion of indirect light reaching a surface by adding a minimum amount of albedo. This minimum amount is called the ambient term.
A scalar ambient factor in [0, 1] is sent as a uniform to this fragment shader, which applies it to the albedo to compute the ambient term:
uniform float ambientFactor;
// ...
void main() {
// ...
vec3 ambient = ambientFactor * albedo * diffuseColor;
vec3 diffuse = (1.0 - ambientFactor) * litness * albedo * diffuseColor;
vec3 rgb = ambient + diffuse;
fragmentColor = vec4(rgb, 1.0);
}
uniform float ambientFactor; // ... void main() { // ... vec3 ambient = ambientFactor * albedo * diffuseColor; vec3 diffuse = (1.0 - ambientFactor) * litness * albedo * diffuseColor; vec3 rgb = ambient + diffuse; fragmentColor = vec4(rgb, 1.0); }
The ambient factor acts as a weight that sets the minimum amount of light that a surface reflects. Observe that the ambient term is not tempered by the litness as the diffuse term is. That's because the ambient term does not depend on the normal or light direction. The diffuse term is weighted by the complement of the ambient factor. This complementary weighting keeps the color intensities from exceeding 1 when summed in the assignment to rgb
.
In the renderer above, try changing the ambient factor to a different value in [0, 1]. As you approach 1, the scene loses contrast. This effect is called desaturation and is used to set a dour mood in games and movies.