The Phong Approximation
# The Phong Approximation

Phong shading was invented by a Mr. Wu Tong Phong. It improves somewhat on the Gourad
approximation for shading polygons. The basic principle is to calculate the surface normal at
each vertex of a polygon, and interpolate the vector over the surface polygon. Then, for each
pixel, calculate the brightness of the pixel based on this normal vector.

This is a very slow process indeed, and one which cannot yet be considered a realtime option
for home computers. Many programs which claim to be able to perform realtime Phong shading are
infact using fake phong shading. This is very nearly as good, and is very much faster.

This is a very popular method for shading polygons, especially in non-realtime rendering packages
like 3D Studio. However, although it looks much nicer than Gouraud shading, it is still not
physically accurate.

To gain a good understanding, you should also read the article entitled 'A Physical Model of
Light'.

Phong shading is just an extension of the Physical Model of Light in the previous article.
Every single pixel has it's brightness carefully calculated using the interpolated normal vector.

This involves:

2 square roots

2 divides

4 multiplies

not to mention numerous adds, per pixel! And these are all non-integer calculations too.
Compare this with one add per pixel for Gouraud shading, and you can see why this is so slow.

## Right, enough of this. How to do Phong Shading.

Phong shading is based on the fact that the amount of light refected from a surface is
proportional to the cosine of the angle between the surface normal and the direction of the
light. The angle you are viewing the surface from makes no difference.
In reality, very few materials exhibit this ideal property. Microscopically rough surfaces, such
as corsely sanded wood may come close. Most surfaces also exhibit specular reflection to some
extent. Phong shading does not deal with this. It also does not handle the fact that brightness
is inversely proportional to the inverse square of the distance from the light.

So, we have a polygon. Each of it's vertices has been given a normal vector (v1, v2, v3). These
vectors are interpolated across the polygon in much the same way the shade was in Gouraud shading.
In Gouraud shading, there was only one value to interpolate, shade, in Phong shading, there are
three, Vx, Vy and Vz (the three components of a vector).

So, let's take a pixel on this polygon, the red one. It's normal vector, **n** has been
calculated. Light is striking the polygon along a vector **l**. The fraction of light from the
light source reflecting off this pixel is the dot product of **n** and **l**. Simple.

Now, the dot product function returns values in the range 1 to -1. 1 is full brightness. There
is no such thing as negative light, so values less then 0 should be taken as 0. If you multiply
this value by the brightness of the light, then you have the brightness of that pixel.

I am not going to bother to demonstrate this algorithm or give any pseudo code. Those who are
smart enough to implement this really don't need my help. People who really want Phong shading
in their programs should read the next article on Fake Phong shading.