CS40: Computer Graphics, Lab 9
Lighting and Shading
By Jeff Kaufman
In this lab I extended the graphics library I started in
lab 2 by adding support for lighting and
shading.
Gouraud Shading
In the Gouraud method of shading polygons you do color
calculations only at the verticies and then interpolate
those colors over the polygon in the scanline fill algorithm.
Color Calculations
The Phong reflection model is used to determine colors. It
involves summing the contributions of each light in the scene.
Lights can be ambient, points, or spots. Ambient light has no
position, only intensity and color, and makes things look more
realistic by approximating the light due to reflections off
objects.
Point lights have a position and the light due to each
point is considered in body and surface components.
The body component does not depend on the viewer because it
represents light that goes into the object a small ways, bounces
around unpredictably, and comes out again just as likely to be
going towards the viewer as any other point. The intensity of
the body reflection depends only on the surface normal and
the direction from the surface to the light source. When these
vectors are paralell the reflection is at its highest and when
they are orthogonal it drops to zero. In the Phong model we
approximate this relationship with the cosine function which we
can get from taking the dot product of the normal and the
unit vector in the direction of the light source. The product of
this scalar, the body color of the object, and the color of the
point light gives us the body component.
Reflection_body = Color_body * Color_light * (surfaceToLight
. surfaceNormal)
The surface component corresponds to the portion of the light that
will bounce off the surface of the object and go towards the
viewer. If the object is completely matte this will be zero but
many real objects, especially plastics and metals, show small
highlights. Because many objects have a clear layer above their
pigment and we're modeling the light that bounces off this layer
we need to have a separate color to prepresent the surface
reflection color. For plastics this will likely be white while
for metals it will be the color of the metal. Having a separate
color also allows us to vary the intensity of the reflection by
decreasing the color values.
To calculate the surface reflection we first find the vector half
way between the vector from the surface to the viewer and the
vector from the surface to the light source. The closer this
vector is to the surface normal the brighter the reflection should
be. We use the cosine function again to approximate this, but
this time we raise the result to a power that represents how
tight the highlights should be. This should depend on the
surface, and nominally models roughness, but doesn't do a good job
of making surfaces look more rough or smooth.
Reflection_surface = Color_surface * Color_light * (
normalize(surfaceToLight+surfaceToViewer) . surfaceNormal)^roughness
Spot lights are a simple modification of point lights to give them
a direction and a dispersion angle. The color value is multiplied
by the negative dot product of the direction from the surface to
the light and the light's direction, raised to a power. This
power represents the tightness of the spot.
Color = Color * (-light.direction . surfaceToLight)^tightness
The image and movie below show a spotlight moving across a phong
shaded cube.
Color Interpolation
Once we have colors for the normals we can color the rest of the
polygon. Just like we interpolated inverse Z values we can
interpolate the color values. It's a matter of interpolating
along the edges of the polygon and then across between the edge
colors. Below we have a rotating triangle where the verticies
have all been set to promary colors colors and those colors are
being interpolated across the triangle.
We can also do this with other shapes, such as octogons (shown
below), but this doesn't work properly for conceptual reasons.
At most four verticies determine what range of colors a scan line
will take on, so if you have many verticies most will be ignored
horizontally. This actually looks interesting (very shiny) but to
properly support larger polygons I would need a different algorithm.
We also have a problem because we divided our coordinates out by Z
to make a perspective projection. We can fix this by
interpolating Color/Z instead of Color and then multiplying by Z
(which we've been interpolating) later to get the real colors.
Phong Shading
Calculating color values and interpolating works ok, but it does
not deal well with cases where light should be acting substantiall
differently on part of the polygon. We can instead do
calculations at each pixel. This is slower, but can look much
nicer. Our color calculations need to know both the world
coordinates of the point and the normal at that point so we need
to interpolate these. Interpolating them is just like
interpolating colors.
Below are two images of a cube with an offest point light just in front of it,
one rendered with Gouraud shading and one with Phong, showing how
Gouraud shading can be quite inaccurate. The linked movies show the light
moving from left to right across the cube.
We can also do pretty stuff with spheres and multiple lights:
Test Image
Something is still funny in my renderer. The image on the left
uses the estimated normals that the origonal test code used,
giving sharp lines, while the image on the right uses the normals
specified by the model, looking much smoother. The coloring and
shading, the whole point of this lab, are wrong though.
Extentions
I implented phong shading and spotlights, both of which worked
well, as well as making several animations.
Jeff Kaufman : 2006
cbr at sccs
dot swarthmore dot spam edu. Remove spam.
main page