Feature Preview: Volumetric Fog
Hello again and welcome to the Flax Facts!
Recently we’re doing many feature previews (profiler, game cooker) and that’s because there are tons of new stuff going on here.
So every time something new shows up, we’re very excited to show it to you.
Today we’re gonna talk about the very cool visual effect which is: volumetric fog. What is it? How it looks like and how to use it? Let’s begin!
Foggy environment with realistic light shafts
Volumetric fog is a visual effect that renders realistic looking fog (as shown in a picture above). The presented technique is based on two presentations:
- Volumetric fog: Unified, compute shader based solution to atmospheric scattering – Bart Wronski at Siggraph 2014 (link)
- Physically Based and Unified Volumetric Rendering in Frostbite – Sebastien Hillaire at Siggraph 2015 (link)
The algorithm itself uses 3D textures as an intermediate data storage and whole logic is performed by Compute shaders with UAVs on GPU.
This results in efficiency and ability to render volumetric fog fully async during e.g. lighting pass.
What is even more, effect outputs a single 3D texture with fog color and fog density for every mapped world position in 3D space so it can be used not only by the deferred renderer (using fullscreen apply or similar) but also inside forward rendering shaders which gives more opportunities to take advantage of it.
Now let’s break down the algorithm and put some more light on it (as shown in a picture below).
All 3D textures used by the algorithm are aligned to the viewport (XY device coordinates) and cover a significant amount of the view depth (Z coordinate). Each voxel (voxel is kind of 3d pixel) is used to store data per world space position. This gives many opportunities to efficiently iterate over the view ray (like final integration pass does) and sample the fog using hardware filtering when applying it. Also, edge artifacts are reduced and any aliasing flickering is barely visible due to temporal filtering. The only downside is that 3D has to have low resolution (e.g. 150x80x64) consequently it’s better to use with objects that have significant size and solid shape. However, because it’s a global effect I think it can be used in almost every game that uses fog or light shafts!
Volumetric fog rendering algorithm can be divided into several steps:
- Initialize volume properties
- Lights Injection
- Light Scattering
- Final Integration
Next step is to calculate lighting contribution per volume cell. To do this algorithm renders (in additive mode) every light into the 3D texture (using geometry shader) and stores light color multiplied by the visibility, intensity and the in-scattering phase function. It’s also possible to sample per-light shadow map so the final effect looks even better.
Finally with calculated light and fog properties per volume cell light scattering and extinction can be evaluated. Then the compute shader can run through the 3d texture and perform final integration along the view ray. The resulting texture is ready to use and apply to the scene.
One of the biggest challenges was to implement proper temporal filter along with jittering. This was required to get rid of all the aliasing artifacts.
That’s because the effect is running in quite low resolution so sampling cascaded shadow map for the sun with only on-tap per cell introduced many visual artifacts (due to under-sampling).
The best results were achieved by using temporal Halton sequence to offset samples inside the voxels and then by performing temporal blending using history buffer (7% blend current frame with the previous). For the fast-moving camera when many samples don’t hit the history super-sampling was implemented in order to smooth the results out.
Lastly speaking about the effect performance it does quite good. On my laptop (GeForce 840M – Witcher 3 runs in 21FPS in low quality on it) it takes around 1.1ms depending on the amount of lights and quality settings. However, this effect excludes the post-fx light shafts and of course, be possibly more optimised in the future.
As you can see this fog looks stunning. I’m pretty happy with the final results and looking forward to release the engine so more people could use it.
At this point, I can say that visual features in the Flax Engine are in the very good condition (including some hot next-gen stuff too).
Also, Editor with included tools does a great job.
Now it’s time to prepare some sample games and projects with features examples and kick off the documentation writing process.
And as always, see you soon! 🙂