```

1) Intensity and Color Tables:

First you need to choose an intensity scale: for example 0 to 1 lets say.
The sum of intensities should not exceed this.
Now we might decide to have 50% ambient and 50% point source light.
So set Ia = .5 and Ip = .5.  Or possibly Ia = .2 and Ip = .8.  Make
these adjustable so you can play with them to get some real point-source
effect.  In particular the cases Ia = 1 or Ip = 1 should look very different.

By definition each of Ka, Kd, Ks should be between 0 and 1.
Choose Ka and Kd to be near 1. Perhaps .9.
Then vary Ks to see the effect of the specular reflection.

Assume you have passed the polygons from the teapot through depth sort and
obtained the final list of polygons (or you can just sort them in the
z direction and display in order which gives a decent picture without doing
ant depth sort - later you can debug the depth sort).

Now you can compute the observed intensity I for each polygon.

Finally you need to relate that to your color table.
I will be a number in the range 0 to 1 at this point.
Write a routine color(I) to return the color table entry for an intensity
of I, 0<=I<=1.
Then color each polygon with color(I) from the color table.
Of course all the work then falls on color(i).

color(I):
The relevant text material is section 13.1.
Assume you have 240 shades of red in your color table and these are
the colors 10, 11, ..., 249 which for simplicity have been set with
the RGB values (i-10,0,0) - i.e. (0,0,0) up to (239,0,0).
This assumes that RGB colors can be established for your system with
each of R,G,B in the range 0<=R<=255.
If using X, the RGB colors are given as (R,G,B) with R, G, B in the
range 0<=R<=65535, rather than 0<=R<=255, so you might multiply
the R value I suggested by 256.

case a) linear intensity:
Here we setup the color table so that perhaps we have 240 shades of red
and these are perhaps the colors 11, 12, ..., 250 and were set to have
the RGB values (i-10,0,0) - i.e. (1,0,0) up to (240,0,0).

In this case we would look up the nearest color to I in this table:
color(I) = round(11 + 239*I).

case b) corrected intensity:
Choose a lowest intensity, say I0 = .02, and highest intensity 1.
Then for any constant r>1, the eye will consider the intensities
I(j) = r**j * I0
to be equally spaced.

Now we must decide what r should be - or equivalently, the number of
intensities.  The eye can distinguish only about 64 intensities. So
we need to choose r so that I(64) = 1.0. However there is no harm in
pretending that we can distinguish 240 colors.  So I will assume that:
I(239) = r**239 * .02 = 1
or
r = (1./.02)**(1./239.)

Now we setup the color table with the 240 colors I(0) to I(239), by
setting color 11+i to have RGB values (round(255*I(i)),0,0), 0<=i<=239.
Note that many of these colors will be the same due to the rounding.
The rounding as needed as each of R,G,B must be an integer.

Now suppose we want an intensity effect of I for the eye on a scale
of 0 to 1 - or to be precise, I0 to 1.  Then we need to pick out the
intensity I(j) which is closest to I, and then we draw the polygon in
color j.  This is most easily done with the formula:
j = round(log (I/I0))
r
where the log is the log to base r.  If you don't like logs to base r,
then just precompute the numbers I(j) and store in an array of length
240.  Then when given an intensity I, simply search through the array
until you find the intensities such that I(p) <= I <= I(p+1).  Take
j to be whichever of the two is closer - p or p+1.

2) Some useful Approximations:

You can assume that the light source is far enough away that L is constant
if you like.  However R involves reflection and depends on the angle between
L and the polygon normal, so it still varies from polygon to polygon.
If the viewer is at infinity too, then you can assume V is constant.

3) What coordinate system should shading be performed in?

The calculations for shading should be done in world coords as the shearing
operations can mess them up.  You can compute the needed normal for every
polygon when the polygon is first created, along with L.N etc.  These
can be stored in the polygon.  When depth sort subdivides a polygon, these
values just get copied.   However no transformations are applied to the