Final Report
(NOTE: Click on any of the images for a larger version )
Shadow Maps in the Power Plant
To render dyanmic shadows in the power plant, I integrated my shadow mapping
code, including pespective shadow maps with an extended SWITCH system.
The new SWITCH uses two GPUs to perform occlusion culling for the eye and
two more for occlusion culling at the light. One GPU renders the shadow
map and displays the visible geometry. In the power plant the light and
viewpoint can be moved around at 15 fps, achieving my goal of dynamic lighting
in a walkthru of a large model. It turns out that two rendering passes
does not create a bottleneck in the current system because of other networking
latency issues. We have had a number of strange networking problems that
have proved an impediment to extensive exploration of the full impact of
the shadows in the power plant. In particular, I would have liked to do
a walkthru to show the light and viewpoint moving. I will present some
stills though.
Improving Quality
Rendering the shadow map with standard OpenGL does not look very good.
The shadow is completely black. To alleviate this problem I used register
combiners in conjunction with a vertex program to compute more complex
lighting. Instead of having pure black shadows, I block only the contribution
of the shadowed light source. Additional light sources may be used. In
addition, I provide a shadow lightness parameter that determines
the fraction of light that is actually block. Objects tend to look too
flat if all the light is blocked because there is no shading variations
to reveal surface curvature. Lightening the shadows also keeps them from
being too "harsh".
The power plant does not have consistently oriented triangles. Thus
some of the vertex normals are flipped. To fix this problem, the system
uses two-sided lighting which flips the normals of backfacing triangles.
This can creates some serious problems with shadow maps. Sometimes
objects have triangles consistently defined in the wrong direction and
vertex normals in the right direction. The two-sided lighting flips these
normals effectively lighting the object from the opposite direction. When
a shadow map is applied it shows up in the region where the surface is
lit. The shadowed side of an object usually has pretty bad artifacts near
the sillouhette because it as at a grazing angle to the light direction.
The flipped lighting makes reveals these artifacts accentuates them. Fig.1
shows an example of a single object with this problem.
 |
| Figure 1: An object with flipped lighting and a shadow map applied. |
To get more correct lighting, I flip the normal whenever it does not
face the eye in the vertex program. This can create problems for triangles
near silouhettes of curved objects where the vertex normal should face
away from the eye because it is the average of the triangle face normals,
some of which are facing away from the eye. In practice, these artifacts
are much less objectionable than those caused by flipped lighting. More
importantly, it permits us to use the models as they are. It is not possible
to use a vertex program to do two-sided lighting exactly as is done in
OpenGL because there is no access to winding information. Fig. 2 shows
the power plant with normals flipped in the vertex program.
a) |
b) |
c) |
d) |
| Figure 2: a) No shadows. b) Shadows provided by standard OpenGL.
c) One-sided lighting without normal flipping. d) Shadows provided by programmable
hardware. |
|
Perspective Shadow Maps
Perspective shadow maps can make a great deal of difference for certain
light-camera configurations as can be seen in Fig. 3. On average though,
I get roughly twice the resolution out of perspective shadow maps as I
do out of normal shadow maps. In the worse case they are roughly the same.
a)
|
b)
|
| Figure 3: Shadows of trusses with a) a standard shadow map and
b) a perspective shadow map. |
|
Fig. 4 shows how shadow maps can add a great deal of depth and realism
to the walkthru. Without the shadows everything looks very flat. It is
more difficult to understand the geometric relationships between objects.
For instance, in Fig. 4a it appears that the geometry is floating above
a plane that lies at an indeterminate distance. The shadows eliminate this
illusion.
a) |
b) |
c) |
| Figure 4: A view of intricate structure a) without shadows, b) with
a standard shadow map, and c) with a perspective shadow map. |
|
Evaluation
Though the shadow maps do enhance the walkthru considerably there are still
a number of problems. The aliasing of shadow edges is very bad. Features
are often missed completely due to the limited resolution of the shadow
map. The aliasing problems are most noticeable on surfaces close to the
viewer. In the distance, the resolution is usually adequate. This suggests
that one possible solution would be to use more than one shadow map. We
could render a restricted region close the viewer with one shadow map and
the rest of the scene with another, giving us the higher resolution where
we need it most.
Another solution is to use an object-based method like shadow volumes.
Shadow volumes have recently become popular in games like Doom 3, but they
are not a scalable solution. Consider the light configuration of most walkthrus
shown in Fig. 5. The light is located somewhere overhead. There are also
some occluders overhead that cast shadows on the objects in the view. Most
of the shadow frusta are going to fill a large portion of the view. If
we take the peak fill rate advertised for the GeForce4 of 4.8 billion pixels
per second and divide by 1024x1024 pixels for a full screen we get roughly
4800 screen fills per second. There may 10,000s of shadow polygons generated
in a large model. There is no way that the graphics card will be able to
deliver the amount of fill power to render the shadow polygons at interactive
rates.
 |
| Figure 5: View configuration commonly encountered in walkthrus. |
|
We are going to try another solution. Using the graphics hardware it
is possible to determine the exact visible set of polygons for both the
eye and light. The light polygons, occluders, that do not cast shadows
on the eye polygons, and the eye polygons lying completely in shadow can
also be culled. That leaves us with a much reduced set of light polygons
that potentially cast shadows on the eye polygons. Since the CPUs are lying
idle in the current SWITCH system, we can put them to use to do intersections
of shadow frusta and eye polygons to produce shadow polygons on the objects.
One thing that I have learned from this project is that shadows with
large models is not a trivial problem. There are a number of difficult
issues such as choosing LODs for objects in the light space. Shadows are
cast on objects over a wide range of distances and orientations making
it difficult to use the projected error metric that the system currently
uses. Perspective shadow maps introduce further non-linearities that make
this issue more complicated. It will be exciting to see what solutions
can be brought to bear on this problem in the future. |