Volumetric Fog Update
In the previous volumetric fog devlog, I implemented the first version of the system: a froxel-based volumetric pipeline capable of representing participating media, directional lighting, shadows, scattering and transmittance.
This update focuses on expanding that foundation into something much more useful for an actual game.
The main additions are:
Distance Fog
Point Volumetric Lights
Spot Volumetric Lights
Light-volume rejection
Exponential Height Fog
Distance Fog
The first addition was distance-based fog control. The original system described the participating medium globally, but I wanted better artistic control over where the fog becomes noticeable.
Distance fog introduces a configurable range defined by a start and end distance from the camera. The density contribution gradually increases across that interval until reaching a configurable maximum opacity.
This makes it possible to keep nearby geometry relatively clear while progressively obscuring distant parts of the scene. It also provides control over the fog color independently from the volumetric lighting.

This is particularly useful for limiting visibility, reinforcing scene depth and hiding distant geometry without having to increase the global volumetric density.
Point Volumetric Lights
The initial implementation only supported the main directional light. The next step was allowing point lights to contribute to volumetric scattering.
For every froxel, the lighting pass now evaluates nearby volumetric point lights using their position, range, color and intensity. The contribution is distance attenuated, so the effect naturally fades as the froxel approaches the edge of the light's influence.
This immediately made local effects such as torches, fires and lamps interact much more convincingly with the fog.

Lights also received two dedicated controls:
Affect Volumetric Fog determines whether the light participates in the volumetric pass at all.
Volumetric Intensity allows its contribution to the fog to be adjusted independently from its normal surface lighting.
This is useful because a light intensity that works well on surfaces does not necessarily produce the desired volumetric appearance.
Spot Volumetric Lights
After point lights, I added support for spot lights. Their volumetric evaluation follows the same general idea, but their influence must additionally be restricted by the spotlight cone.
For each froxel, the system evaluates:
distance to the light
light range
direction relative to the spotlight
inner and outer cone attenuation
volumetric intensity
This allows effects such as flashlights, lamps and other directed light sources to produce visible cones inside the medium.

One useful result of the froxel representation is that both point and spot lights can use the same volumetric lighting pipeline. Only their local light evaluation differs.
Light-Volume Rejection
Adding local lights introduced an obvious problem. Without any rejection, every point and spot light would be evaluated for every froxel in the volume, even when the light could not possibly affect it.
Before implementing a more complex volumetric light-culling system, I added a cheaper first step. Point lights reject froxels outside their radius. Spot lights reject froxels outside their range or cone.
Conceptually:
if (outsideLightVolume)
skipLight();
This is deliberately simple, but it prevents unnecessary lighting calculations for large portions of the volume. A proper clustered or tiled volumetric light-culling system is still possible later, but for the current number of lights this approach gives a much better cost/complexity trade-off.
Exponential Height Fog
Uniform fog works well for some environments, but real scenes often need the medium to concentrate near the ground. For that reason I added Exponential Height Fog.
Instead of applying the same density everywhere, density now depends on the world-space height of each froxel.
The controls are:
Density
Base Height
Height Falloff
The density decreases exponentially as the froxel moves away from the configured height region. This produces much more natural-looking low fog and gives considerably more control over the vertical shape of the medium.
Because this happens during medium injection, all volumetric lights automatically interact with the resulting density distribution.
Current State
The original froxel pipeline remains unchanged conceptually:

The difference is that the medium and lighting stages now have significantly more information to work with. What started as a basic global fog implementation can now represent several different types of atmospheric effects while responding to both global and local lighting.
What's Next
There are still several features I would like to explore:
Ambient Volumetric Lighting
Fog for Transparencies / Particles
Local Fog Volumes
More advanced optimizations such as volumetric light culling and spatial filtering are also possible if profiling shows they are necessary. For now, however, this is the version of the system I am shipping.



Comments