Venus Twilight Belt Formula in GLSL Shaders
This article explains how to calculate the twilight belt illumination of Venus in atmospheric GLSL shaders. Due to its thick carbon dioxide atmosphere and reflective sulfuric acid cloud layers, Venus exhibits an extended twilight zone that wraps around its dark limb beyond the geometric terminator. Real-time rendering engines simulate this phenomenon by modifying standard diffuse lighting through extended terminator offsets, exponential twilight falloff functions, and Henyey-Greenstein forward-scattering phase approximations.
The Physical Mechanism
Standard Lambertian shading evaluates light using \(I = \max(\mathbf{N} \cdot \mathbf{L}, 0.0)\), cutting off abruptly at the geometric terminator where the solar zenith angle (\(\theta\)) equals \(90^\circ\) (\(\mathbf{N} \cdot \mathbf{L} = 0.0\)).
On Venus, intense atmospheric refraction and multiple scattering within the upper aerosol deck extend diffuse light into the nightside up to a solar zenith angle of approximately \(98^\circ\) to \(102^\circ\). This creates the visible twilight belt and crescent cusp extensions.
The Mathematical Formula
To compute this twilight illumination analytically in a fragment shader, the angle of solar depression past the terminator is mapped to an exponential scattering falloff modulated by directional forward scattering.
1. Solar Zenith Angle and Twilight Depression
First, evaluate the cosine of the solar zenith angle:
\[\mu = \mathbf{N} \cdot \mathbf{L}\]
The angle \(\theta\) in radians is:
\[\theta = \arccos(\text{clamp}(\mu, -1.0, 1.0))\]
The twilight depression angle past the geometric terminator (\(\theta_{\text{term}} = \frac{\pi}{2}\)) is:
\[\Delta\theta = \max\left(0.0, \theta - \frac{\pi}{2}\right)\]
2. Twilight Transmittance Function
Atmospheric optical depth causes the twilight belt to decay exponentially as the sun dips lower below the local horizon:
\[T_{\text{twilight}} = \exp\left(-\frac{\Delta\theta}{\sigma}\right)\]
Where:
- \(\Delta\theta\) is the depression angle past the terminator.
- \(\sigma\) is the twilight scale factor (calibrated to Venus's atmospheric scale height and cloud optical depth, typically between \(0.03\) and \(0.08\) radians).
3. Forward Phase Function (Henyey-Greenstein)
Because Venusian twilight is heavily dominated by forward scattering of sunlight through the upper hazes toward the observer, the intensity is scaled by a phase function:
\[P(\phi, g) = \frac{1 - g^2}{4\pi (1 + g^2 - 2g \cos\phi)^{1.5}}\]
Where:
- \(\cos\phi = \mathbf{V} \cdot \mathbf{L}\) (the cosine of the angle between the view vector and the light vector).
- \(g\) is the asymmetry parameter (\(g \approx 0.7\) to \(0.85\) for Venusian sulfuric acid aerosols).
4. Combined Twilight Intensity
The total twilight belt illumination \(I_{\text{twilight}}\) is calculated as:
\[I_{\text{twilight}} = I_{\text{sun}} \cdot T_{\text{twilight}} \cdot P(\mathbf{V} \cdot \mathbf{L}, g) \cdot W(\mu)\]
Where \(W(\mu)\) is a smooth transition weight that blends the daytime diffuse illumination into the twilight belt without producing hard edges.
GLSL Shader Implementation
Below is the GLSL function implementing this formulation:
// Calculates the Venus twilight belt intensity
// N: Normalized surface normal
// L: Normalized light direction (towards Sun)
// V: Normalized view direction (towards camera)
vec3 calculateVenusTwilight(vec3 N, vec3 L, vec3 V, vec3 sunColor) {
const float PI = 3.14159265359;
const float HALF_PI = 1.57079632679;
// Venus atmospheric constants
const float twilightScale = 0.052; // Angular falloff rate (~3 degrees)
const float maxTwilightAngle = 0.174; // Max twilight depth (~10 degrees)
const float g = 0.80; // Aerosol forward-scattering asymmetry factor
float NdotL = dot(N, L);
float VdotL = dot(V, L);
// Compute solar zenith angle
float zenithAngle = acos(clamp(NdotL, -1.0, 1.0));
// Angular distance past the terminator
float depression = max(0.0, zenithAngle - HALF_PI);
// Cut off evaluation beyond the active twilight belt limit
if (depression > maxTwilightAngle) {
return vec3(0.0);
}
// Exponential attenuation through atmospheric path
float attenuation = exp(-depression / twilightScale);
// Henyey-Greenstein phase function for forward haze scattering
float g2 = g * g;
float phase = (1.0 - g2) / (4.0 * PI * pow(1.0 + g2 - 2.0 * g * VdotL, 1.5));
// Smooth transition near the terminator boundary
float blend = smoothstep(HALF_PI + maxTwilightAngle, HALF_PI, zenithAngle);
return sunColor * attenuation * phase * blend;
}This formula isolates the illumination occurring strictly in the twilight region and can be added directly to the daytime multi-scattering terms to produce a physically representative illumination model of the Venusian atmosphere.