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 nonuniform
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 postperspetive space. So you
have a light source point in postperspective 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 upVector 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