An example for a point (spot) light source is shown in the
following images. The upper row shows the light source view for a uniform
shadow map (left), its depth buffer (center) and the resulting view (right)
with strong aliasing artifacts. The lower row shows the same for our non-uniform
shadow map.
uniform shadow map view
|
uniform shadow map depth
|
uniform shadow map result
|
perspective shadow map view
|
perspective shadow map depth
|
perspective shadow map result
|
Recipe for Computing the Perspective Shadow Map Matrix
The shadow map is rendered just as the normal view, with one modelview
/ projection matrix pair. You can get that pair as follows: if MV and
P are the matrices for the current camera, then the transformation world
space -> post perspective space is the matrix M=P*MV. This transformation
M maps a visible scene point in world space to the unit cube [-1,1]^3. You
first have to transform your light source with the same matrix M. If it is
a parallel light from (x,y,z) just plug in (x,y,z,0); in general, this point
at infinity will end up in a finite point in post-perspetive space. So you
have a light source point in post-perspective space and the visible scene
is in the unit cube. You then have to setup a normal shadow map for this
setting, i.e. a (point) light source, illuminating the unit cube. If the
light source is at L you can achieve this with (OpenGL, sorry) gluLookAt(L[0],L[1],L[2],0,0,0,0,0,1),
i.e. you put the camera into the light source and look at the origin (center
of the unit cube). Choosing z as up-Vector is rather arbitrary. Then you have
to compute the perspective opening angle such that the entire cube is visible.
This gives you a light modelview matrix MVL and a light projection matrix
PL. Thus the entire matrix becomes PL*MVL*P*MV. You can now use PL*MVL*P as
new Projection matrix and keep MV as modelview matrix. That's it.
Gallery