##
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*
Light_{1},
Light_{2},
Light_{3}...
in the scene.
Each light source *j* has a *light direction vector*
L_{j},
and an RGB color vector to describe its *illuminance color*
I_{j}.

If you want to model light sources "at infinity" (a good approximation
for the Sun, for example) then you just set each
L_{j}
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:

Ambient_{color} +
SUM_{j}
(
I_{color}
(
Diffuse_{color}
normal . L_{j}
+
Specular_{color}
(reflection(L_{j},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