An experiment designed to teach myself how to create a modern volumetric lighting solution for high-end games.
The scope of this project was designed to allow me to create a system supporting any number of volumetric lights of the three common light types (directional, point, and spot).
The system involves two scripts - one script, as a post processing effect on the camera, keeps track of a global volumetric light buffer and is responsible for compositing the buffer with the screen.
The other script goes on each light which should be volumetric. It contains parameters for scattering, extinction, and Mie scattering. Each light renders its contribution into the global volumetric light buffer by raymarching and accumulating results. Directional lights render a full-screen quad which performs the raymarching, whereas Point and Spot lights render a mesh at their position and orientation which performs the raymarching, seamlessly switching to a fullscreen quad if the camera enters their light volume, to solve the problem of intersecting the geometry.
Additionally, the system uses dithering to reduce stair-stepping, and takes advantage of a temporal filter to reduce the effect of the resulting noise. Each frame the current light buffer is saved off to a separate render target, and a shader uses Unity's velocity buffer to reproject the results of the previous frame and then averages with the current frame before compositing with the screen.