By Reto.Hal9k, Render Programmer
We’ve been running with Cascaded Shadow Maps (CSM) for quite some time now, with a user adjustable cascade count ranging from 1 to 3 cascades. The last cascade (number 4) has been a one time calculated shadow map for the entire scene, to avoid shadows missing in the distance. The last has been an important addition to standard CSM as we have airplanes in the game, and the landscape just looks flat if we omit it. Initially we talked about precalculated shadows/lighting, but we wanted a more dynamic solution to allow weather changes, and didn’t want to increase the download size of the game.
Even though CSM solves a lot of issues with the quality when covering a large area, they have some really heavy performance requirements. Especially when running with 3 cascades, the number of objects visited and revisited during drawing can become very high. In certain scenarios the CPU time for setting up the objects to be rendered would climb up to 16-20 ms on high-end machines, effectively dropping the framerate from 60 fps to 30 fps.
So I started looking around for alternatives to the CSM and fell across an article written in GPU Pro 2 by Pavlo Turchyn about the game Age of Conan. They were fighting the same issues as I was, but had solved the problem by switching to Adaptive Shadow Maps instead.
A debug view of the Adaptive Shadow Map Tiles. The red lines shows the active tiles, and the white lines shows the current camera frustum as seen from the light.
In short, ASM works by dividing the world seen from the light source into tiles, as compared to CSM where it’s the camera frustum that is divided. Each tile is then given an index into a tile map and a shadow map for that tile is calculated and stored in this tile map. For those familar with virtual texturing/mega textures etc.. the algorithm is very much the same. To avoid rendering many small tiles in the distance, the tiles are combined into progressively larger tiles in a quad tree hierachy using the distance from the camera as a guide to the depth of the quad tree. This quad tree is evaluated each frame, and if a new tile has entered the visible range or if the quad tree detail level has changed somewhere, the new tiles are calculated. Typically a single tile every several frames has to be recalculated, giving a huge performance burst compared to CSM.
ASM has one short coming. It doesn’t do dynamic shadows from vehicles or characters. To overcome this problem I maintain a separate shadow map for dynamic objects and combine the ASM with the dynamic during drawing.
The next major release of the game (internally called Avery) will contain the new shadow map system.