This implementation is mostly based of Kenny Mitchell’s Chapter, “Volumetric Light Scattering as a Post-Process“, in GPU Gems 3, which is available free on Nvidia’s website. It is implemented in my own Renderer application with C++ using OpenGL and SDL2.
High level overview
The implementation is a two step process which involves creating a silhouette image and applying radial blur to it before adding it to the screen. It is possible to do it in one step where all the calculations is done in one shader. However this results in a slower process since a lot more computations is needed within the sampling loop.
SHADER PASS 1
In the first shader pass a silhouette image of the world is created. It uses the depthbuffer for the silhouettes, and a directional light for the position and color of the sun. An algorithm is used on each pixel to determine if the pixel hits either the sun, the sun’s halo, a silhouette, or nothing. If the pixel misses all, an ambient color is stored.
OutColor = (ambientColor + haloColor * haloSmoothHit + sunColor * sunSmoothHit) * depthMiss
To make sure the sun is visible even if the light scattering is low, a SunHit variable is stored in the alfa value of the silhouette image. This value will later be used in the second shader pass to apply the suns in the result.
SHADER PASS 2
The second shader pass uses a radial blur algorithm from the center in the sun to create the ‘god rays’ effect. I’ve done few performance improvements by removing some unused variables from Mitchell’s implementation, and moved out some unnecessary computations outside of the loop. The radial blur sampling is the bottleneck of this implementation and I’ve done several attempts (successful or not) to reduce to execution time.