Graphics Gems GLSL - Simulating Fog and Haze
Atmospheric effects like fog and haze are essential for creating depth, mood, and realism in 3D scenes. The technique from Graphics Gems I uses exponential density decay to simulate how light scatters through the atmosphere, creating the characteristic "fade to white" effect of distant objects.
Interactive Demo
Move your mouse to rotate the camera and explore the foggy landscape. Scroll to adjust fog density:
Mathematical Foundation
Fog and haze simulation is based on exponential density decay:
Exponential Fog Density
The density of fog increases exponentially with distance:
Where:
- : Distance from camera
- : Base fog density coefficient
- : Controls how quickly fog accumulates (typically 1.0-2.0)
The exponential form ensures smooth transitions and physically realistic scattering behavior.
Height-Based Haze
Haze often accumulates near the ground:
Where:
- : 3D position
- : Reference height (fog level)
- : Height-based density coefficient
This creates realistic ground fog that's denser at lower elevations, simulating the natural behavior of atmospheric particles settling near the ground.
Implementation
Applying Fog to Objects
// Calculate fog factor based on distance
float fogFactor = fogDensity(distance, 0.05, 1.2);
// Blend object color with fog color
vec3 fogColor = vec3(0.7, 0.8, 0.9); // Sky color
vec3 finalColor = mix(objectColor, fogColor, fogFactor);
Atmospheric Perspective
Distant objects appear more foggy and less saturated:
Where is the atmospheric fog factor and controls the blending strength (typically 0.6).
Visual Effects
God Rays (Volumetric Lighting)
Add volumetric light rays by checking if the view direction aligns with the light:
float lightDot = dot(viewDir, lightDir);
if (lightDot > 0.9) {
float rayIntensity = pow(lightDot, 8.0) * 0.3;
color += lightColor * rayIntensity;
}
Layered Fog
Combine distance-based and height-based fog for realistic effects:
float distFog = fogDensity(t, 0.05, 1.2);
float heightFogDensity = heightFog(p, 2.0, 0.1);
float totalFog = mix(distFog, heightFogDensity, 0.5);
Applications
- Landscapes: Create depth and atmosphere in outdoor scenes
- Horror games: Use dense fog to limit visibility and create tension
- Flight simulators: Realistic atmospheric scattering at altitude
- Post-processing: Apply fog as a screen-space effect
Performance
Fog calculations are extremely efficient:
- Single exponential function per pixel
- No additional geometry required
- Works perfectly in fragment shaders
- Can be applied as post-processing effect
References
- Graphics Gems I (1990) - "Simulating Fog and Haze"
- Atmospheric Scattering on GPU Gems 3
Related Articles
- Graphics Gems GLSL - Shadow Attenuation for Transparent Objects - Related volumetric effects
- Graphics Gems GLSL Series Index - Return to series index