Notes on Phong Shading

Phong shading (devised by Bui Tong Phong) is a very simple but in some ways effective visual approximation to the way that light interacts with surfaces.

It consists of three terms: ambient, diffuse and specular. The ambient term corresponds to light in the environment coming from all different directions toward the surface. The diffuse term corresponds to light entering into the surface and coming out again in equally all different directions, which is the sort of effect you get with a very dusty surface. The specular term corresponds to light that exits in more or less a mirror highly direction, such as you would get with a shiny or polished surface.

The ambient, diffuse and specular terms can each have a color, described by a [red,green,blue] color vector. Generally speaking, metal surfaces have specular color and diffuse color which are the same "hue" (ie: differing only in brightness), whereas plastic surfaces have white specular color (ie: white hilights).

When you use the Phong model, you generally place some number of light sources Light1, Light2, Light3... in the scene. Each light source j has a light direction vector Lj, and an RGB color vector to describe its illuminance color Ij.

If you want to model light sources "at infinity" (a good approximation for the Sun, for example) then you just set each Lj to a constant direction vector for every point you calculate.

You apply the Phong model at each surface point, using, as input, the surface point location p, the surface normal direction vector n (ie: the unit length vector that points perpendicularly out of the surface at point p) and all of your light source direction vectors and illuminance colors.

The Phong model is calculated as follows:

Ambientcolor + SUMj ( Icolor ( Diffusecolor normal . Lj + Specularcolor (reflection(Lj,normal) . e)p ) )
where e is the vector from the surface point to the eye (ie: the negative of the w vector of the traced ray), and p is a power exponent. The larger p is, the shinier is each highlight.

reflection(in,normal) is a method to get the outgoing reflection vector of a ray of light, given that you know the surface normal and the vector of the ray of light going into the surface. It is computed by:

reflection(in,normal) = 2 normal (normal . in) - in