Tile-based Omnidirectional Shadows
Though rendering efficiently a massive amount of dynamic local light sources is actually solved by techniques as Tiled Forward/ Deferred Shading or Clustered Forward/ Deferred Shading, generating in real-time appropriate shadows is still an ongoing topic. Since I'm using shadow maps both for direct and indirect lighting, I looked for a rendering system that could generate such shadow maps for a high number of dynamic light sources in a reasonable time frame and within a limited amount of texture memory.
Below you can see two screenshots with the Crytek Sponza scene illuminated by 128 medium-sized moving point light sources, each casting individual soft shadows. The left image shows a reference technique that creates for each point light a cube map-based shadow map, whereby all cube maps are stored within a single cube map array. The right image shows the proposed technique.
Though the quality of the shadows in both images are nearly equal, the proposed technique runs more than three times faster as the reference method. With an Intel Core i7-4810MQ 2.8 GHZ CPU, a Nvidia GeForce GTX 880 Mobile GPU and a screen resolution of 1280x720 the proposed solution runs at 28.44 FPS while the reference technique only achieves 8.89 FPS.
In the proposed technique the shadow maps of all light sources are rendered in a single draw call and efficiently packed as tiles into a single 2D texture atlas with the help of a hierarchical quad-tree. For this the concepts of Programmable Draw Dispatch (as proposed by Riccio and Lilley) and Tetrahedron Shadow Mapping (as proposed by Liao) are combined with a novel usage of the programmable clipping unit that is present in current graphics hardware. You can find a detailed description of this technique in my article within the GPU Pro 6 book.
This time the demo application uses OpenGL and requires a recent graphics driver that at least supports OpenGL 4.4. Thanks to Nikita Kindt now the application can be also build and run on Linux. You can download the demo including the entire source code here: