Data Structures
We discussed some of the limitations of the simple data structures we have been using in this course. In particular, our structures bind together polylines into objects, but no seperate list is kept of which edges and points are shared among polyhedron faces. Many computer graphics systems maintain such listings to speed up some algorithms, such as the shading algorithms which follow. We also talked about the kinds of "tweenings" which occur in animations and how to design data structures to support those capabilities.
Animations
We discussed the necessity for sketching key frames, which show the visual appearance when significant changes occur, and a storyboard, which shows the order in which changes occur and the timings.
Diffuse Reflection
Most objects exhibit significant diffuse reflection -- reflection which obeys Lambert's law, which says that the surface appears the same from all viewing angles. This simplification is often used because the apparent intensities of illuminated surfaces are easy to calculate.
According to this model, the apparent surface intensity is proportional to the illumination intensity. There are two components to the constant of proportionality - a scalar called the "reflectivity" which tells which fraction of the incident light is reflected back; and, the cosine of the angle betwen the illumination direction and the surface normal. The second component corrects for the fact that the farther the illumination is from the normal direction, the more the light gets spread out across the surface, which lowers the apparent intensity. The cosine is easily calculated - it is the negative of the dot product of the two vectors.
The second part of Lambert's law is that a diffuse object has the same apparent surface intensity at all viewing angles. Thus the illumination direction and reflectivity totally determine the intensity.
Shading
Rendering a "shaded object" means simulating lighting effects, such as Lambert's law. In it's simplest form, that can be achieved using a small variation on z-buffering, described in Class N. After calculating the intersection and backface culling the polygon, the polygon color is multiplied by minus the dot-product of the normal with the illumination direction (if that dot product is negative, which signifies that the polygon points towards the source and can be illuminated, or it is multipled by zero if the product is not negative). In addition, a small amount of "ambient" (constant) light is added to prevent completely shaded regions from being completely black. Here are the key code fragments:
f_amb = 0.25; /* 25% of the total illumination is "ambient" */ ambient = f_amb * (float)WHITE + (1.0 - f_amb) * (float)BLACK; illum = (1.0 - f_amb) * (float)WHITE + f_amb * (float)BLACK; color = (unsigned char)(ambient + 0.4999); /* rounding */ if (dot_vectors(direction, poly_plane.normal) < 0) color += (unsigned char)((float)illum * -dot_vectors(direction, poly_plane.normal) + 0.4999); color *= reflectivity; |
Note the parametric mixing of BLACK and WHITE to produce the gray levels. This is done to allow a simple, global change in the values (in the header file) to switch to printer's definitions (black = 255) instead of the radiometric definition we have been using (black = 0).
Here are the results when the illumination direction is (1, -1, -1). The background was made black to highlight the shading effect.
|
wireframe |
backface culled |
shaded |
Gouraud Shading
More advanced shading models can be used to reduce the evident "faceting' in the above image. That occurs because your eye is sensitive to abrupt changes in gray level or color. Smoothing of the gray level removes the apparent faceting.
This smoothing technique can be used in both z-buffering and scan-line fill algorithms (just substitute "horizontal line" for "scan line").
Begin by calculating the "average" normal at each point in
the polygon. That is found by averaging the values of the normals of each
of the polygons that meet at the point. In this drawing, none of the adjacent
polygons are shown, but the are there and their normals have to be averaged.
Form the dot product of each of the averaged vertex normals with the lighting
direction L. This quantity
is a scalar value calculated for each
vertex. The vertex values are interpolated to find the value at any interior
point P.
Extend P horizontally and find it's two intersections with polygon edges (this is much easier if the polygons are convex).
![]()
These equations are written parametrically because that is the usual
way intersections are found. Use the parameters to interpolate the values
of
at the intersection points.
![]()
Use these values to interpolate the value of
at P.:
![]()
The interpolation parameter v is found using the x values of the two points:
![]()
The value of
calculated at P is used, as in the shading method
described above, to determine the color of the pixel corresponding to P.
Note that this interpolation shading method, called Gouraud shading, requires calculating the average normals at each vertex. The simple data structure we have been using do not easily support this calculation, as we discussed earlier.
Phong Shading
A variation on this shading method,
called Phong shading, interpolates the value of the normal N
in exactly the same manner that
was interpolated in Gouraud shading.
The interpolated value of N is then dotted with L to
produce the value of
at the point P. This means that vectors, not
scalars, are interpolated, tripling the computational load. This is done
for two reasons. First, the results are quite lovely - see this Phong shaded
sphere.
The second advantage of Phone shading is that an additional component is often added to the color:
![]()
The exponent n, which usually has values in the range 4 to 12,
causes a bright spot which looks like a highlight -- it is used to suggest
that the surface is shiny. Often two reflectivities are used, one for the
term
and a second for the
term, to heighten the effect.
![]()
![]() WPI Home Page |
[cs4731] [Classes] |