Sunday, October 21, 2012

Cascaded Shadow Maps

So I've done quite a bit more work on shadowing. Clearly as the previous post illustrated, ordinary shadow maps weren't good enough for large terrain. After a bit of looking around, it seemed that Cascaded Shadow Maps were the ideal, and commonly used solution. Project Vanquish even had an implementation, and it worked right off the bat (well, there were a few minor changes I made, but very minor indeed).

The main problem here is that to cover a large area the shadow map is stretched across that large area.  So one texel of the shadow map will cover multiple screen pixels, leading to all sorts of artifacts. 

 So, enter CSMs.  To quote from the article linked above:

The basic concept of CSMs is easy to understand. Different areas of the camera frustum require shadow maps with different resolutions. Objects nearest the eye require a higher resolution than do more distant objects. In fact, when the eye moves very close to the geometry, the pixels nearest the eye can require so much resolution that even a 4096 × 4096 shadow map is insufficient.
The basic idea of CSMs is to partition the frustum into multiple frusta. A shadow map is rendered for each subfrustum; the pixel shader then samples from the map that most closely matches the required resolution (Figure 2).

Basically cascaded shadow maps take your single shadow map and break it up into regions. For the area closer to the camera, more detail, i.e. a larger chunk of the shadow map is used. It is easy to see with some image (taken from the above link to the Microsoft DirectX site).  First are what would be regular shadow maps of varying resolution (and hence memory use):

Regular shadow maps of varying resolution.
A cascaded shadow map, on the other hand, breaks the map down into sectors, with as close to a 1 map point to pixel mapping as possible, and less resolution as you get further away.
Cascaded shadow map.

Of course, this is significantly more complicated.  But, as I said before, Neil Knight's Project Vanquish, which I've been using as a base, contains a nice implementation.

This worked pretty well, but there were still artifacts ('shadow acne' seems to be the most common term to describe this).  Also, PCF filtering seemed a bit slow.  Percentage Closer Filtering boils down to sampling a X by X region and blending instead of just taking a single texel.  4x4, 5x5, 7x7 are all common levels.  Needless to say this is a lot of extra texture taps.  Plus it was still giving aliasing.

So, in order to try and deal with this, I started working on Variance shadow mapping, which is a fairly new technique, it seems.  I'll go into that on the next post.

No comments:

Post a Comment