Realtime Shadows and Lighting Project Screenshots
One of the 'ugly' results of this algorithm, is the way in which polygons
on the shadowing object are always entirely shadowed or entirely lit
(except in the case of self-shadowing). This results in the ugly jagged
shadow edges on low resolution models, such as the torus seen here.
Even on fairly high resolution models, however, the shadow line
'jumps' as the object moves. This could be fixed by computing
an approximate smooth silhouette based on interpolated normals.
Here is the same scene, side-by-side with the view from the light source.
The light source's view is slightly washed out, an inadvertent result of
scaling the modelview matrix in order to get a better look at the torus.
The shadowed portions of the image are not visible from the point of view
of the light.
Here is the same scene from a different angle, with the torus
rotated a bit. Note the self-shadowing on the torus.
Here is the same shadow code, with a torus instead of a sierpinski
triangle. Additionally, the entire scene was placed in a room,
and the block on the floor was added to the shadowing objects list
Notice the dots on the block: they are the result of generating
the shadow volume polygons triangle by triangle, instead of as one single
silhouette. In some instances, the triangles don't match perfectly when
projected, resulting in single pixel 'holes' in the shadow.
Here are finally the correct shadows. By capturing the vertices in
an un-transformed state, I could throw out polygons that were
facing away from the light, speeding up the algorithm and
getting rid of the cancellation.
In the case of the tetrahedrons
shown here, calculating a silhouette would probably not
save that many operations; as the many holes would offset
any gains from merging adjacent faces. It would
cut down the drawing by a constant factor, though,
so it may be worth it.
Another picture of the shadow volume algorithm. A nice thing about
it is that the speed of the shadowing step is entirely dependent on the
complexity of the shadowing object. A complex shadowed object
does not add any complexity, except at the initial drawing pass
(which you cannot escape anyways). However, polygon placement
on the screen, relative to the light source may have some effect;
when alot of the shadow volume is visible on the screen, the
algorithm may become fill-rate limited, as it may be drawing many
shadow volume faces over the same area of the screen.
Here, I am drawing any object that is behind a shadow volume face,
not necessarily inside of one. This is about as far as I could go,
without having to re-arrange the shadow-volume generation, as I
was capturing vertices after they had been projected, which,
of course, destroys the information about whether the polygon
is facing the light or facing away from it. Thus I couldn't get
rid of the cancellation shown below. But I could do the above.
Here, the shadow volumes are actually being draw correctly,
except that the light-facing polygons of the shadowing object
cancel out the non-light-facing polygons, so all you get
are little black dots where there is an edge error along
the shadow volume faces.
A vertex-projected shadow volume. I tried to use OpenGL's feedback
mode to transform and clip the vertices for me, but when I go to
draw the already-projected vertices in orthographic projection, the
z-buffer is messed up somehow. There must be some depth-extents that
work, or else I'll have to do the vertex transformations myself...
Here's a brute-force implementation of finding the shadow volumes.
Actually, to be correct it needs to project from the actual edge of the
object, instead of the light source, so it's a little more complex than
this, but not much.
Here is one of the more complex (and mislabeled..) objects that I plan to
use for testing algorithms. It quickly hits the upper limit of object
complexity most algorithms can handle..
I got OpenGL working on my computer nicely. This here is a color cube.
It has nothing to do with the project other than it is in OpenGL.
Back to the main page