In what is most probably my last Vulkan example for 2017 I have added a cascaded shadow mapping example to my open source Vulkan C++ example repository:
One big problem of traditional shadow mapping, esp. with large outdoor scenes is the resolution you get as one single shadow map has to cover the whole camera spectrum.
With cascaded shadow maps the frustum is split up into multiple frustums (along scene depth) with each getting it’s own, full-resolution, depth map. In the shader you compare the fragment’s depth to find the split (cascade) in which the fragment falls to read from the proper depth map cascaded.
For this Vulkan example the cascade is stored as a layered texture with each layer of the depth map representing one part of the split-up frustum:
(From left to right: Layer 0, 1, 2,3 )
Visualizing from which cascade the shader samples:
(Red = layer 0, Green = layer 1, Blue = layer 2, Yellow = layer 3 (not visible in shot))
The number of cascades can be easily tweaked as well as the way the frustum is split up along the z-axis, so you can e.g. easily get a bigger closes-to-camera split frustum if required.
Note that the example does multi-pass for generating the depth map layers. An option would be to move to a layered frame buffer and have a single pass with a geometry shader emit directly to the layers so you only require one render pass for depth map generation. In my tests though this didn’t yield any performance improvements, and depending on the GPU used the single-pass geometry shader setup may actually turn out slower.