A physically-based volumetric cloud and atmospheric scattering system built on Unity URP.
This project features cloud rendering that conforms to Earth’s curvature and simulates realistic sky colors using Rayleigh, Mie, and ozone scattering. The system includes layered cloud density modeling, light cone sampling, and dynamic weather-driven cloud coverage.
-
Full spherical geometry: cloud layer is modeled as a shell between two radii over the Earth sphere.
-
Physically motivated density profile:
- Supports Stratus, Stratocumulus, and Cumulus formations via gradient height curves.
-
Noise-driven shape formation:
- Multi-octave Perlin + Worley base shape
- High-frequency erosion for detailed boundaries
- Curl noise rolling for dynamic displacement
-
Weather control via tiling 2D weather map:
- Per-cell cloud type, coverage, and anvil strength
-
Wind drift and vertical lift shaping
-
Cone-shaped light sampling (with kernel offsets) for volumetric light transmission
-
Energy-aware shading:
- Phase-based Mie scattering
- Altitude-aware sunset coloration (
ApproxAtmospheremodel)
- Physically-based Rayleigh + Mie + Ozone scattering
- Modeled as a spherical shell surrounding the Earth
- Integrated optical depth computation with multi-sample ray integration
This project implements physically-inspired volumetric cloud rendering using raymarching techniques in a real-time graphics context. The following physical principles and equations are foundational to its implementation:
Clouds are modeled as participating media—volumes composed of small water droplets or ice particles that absorb and scatter light. Light interaction in such media is described by the Radiative Transfer Equation (RTE):
-
$L(\mathbf{x}, \omega)$ : Radiance at point$\mathbf{x}$ in direction$\omega$ -
$\sigma_t = \sigma_s + \sigma_a$ : Extinction coefficient (sum of scattering and absorption) -
$p(\omega', \omega)$ : Phase function (probability of scattering from direction$\omega'$ to$\omega$ ) -
$Q$ : Emission term (ignored for non-luminous clouds)
In this project, the implementation assumes single scattering and ignores in-scattering from other directions to maintain real-time performance.
The attenuation of light along a ray through a medium is computed using the Beer-Lambert law:
In practice, this is approximated by accumulating the extinction term during raymarching steps.
For each ray traced from the camera into the volume, a fixed number of samples is taken using raymarching. At each step
Where:
-
$T_i$ : Transmittance from the ray origin to step$i$ -
$\omega_l$ : Light direction -
$\omega_v$ : View direction -
$p$ : Phase function -
$\Delta s$ : Step length
This accumulation approximates the scattered light contribution along the ray.
The Henyey-Greenstein phase function is often used to approximate anisotropic scattering in clouds:
-
$\theta$ : Angle between incoming and outgoing directions -
$g$ : Anisotropy parameter, where$g > 0$ favors forward scattering (typical for clouds:$g \approx 0.8$ )
Cloud density is procedurally defined using 3D fractal noise functions, such as Perlin noise or FBM (Fractal Brownian Motion):
This gives a realistic, dynamic structure to the cloud volume.
This project incorporates a physically-based atmospheric scattering model to simulate realistic sky colors and lighting conditions. The model accounts for Rayleigh scattering, Mie scattering, and ozone absorption, enabling dynamic transitions such as blue skies, red sunsets, and the silver lining of clouds.
Rayleigh scattering describes the scattering of light by particles much smaller than the wavelength of light, predominantly affecting shorter wavelengths (blue light). The scattering coefficient is inversely proportional to the fourth power of the wavelength:
This phenomenon explains why the sky appears blue during the day.
Mie scattering describes the interaction of light with particles comparable in size to the wavelength of light, such as water droplets or aerosols. This type of scattering is highly directional and is responsible for phenomena such as the white glare around the sun or the bright edges of clouds.
Since the exact solution to Mie scattering involves complex series of Maxwell's equations, real-time rendering typically uses an approximation.
We use the Henyey-Greenstein phase function to approximate the angular distribution of scattered light:
Here,
Ozone in the Earth's atmosphere absorbs certain wavelengths of light, particularly in the ultraviolet range, but also affects the visible spectrum. The absorption is characterized by specific coefficients for red, green, and blue wavelengths.
-
Implemented fully as URP
ScriptableRenderPassfeature -
Separated passes for:
- Atmosphere scattering
- Volumetric cloud raymarching
-
All core math done in HLSL
| File/Folder | Description |
|---|---|
CloudShape.hlsl |
Cloud base density, weather sampling, erosion |
CloudShade.hlsl |
Light sampling through cone, shading logic |
AtmosphereScattering.hlsl |
Atmospheric integration (Rayleigh/Mie/Ozone) |
Intersection.hlsl |
Ray-sphere / cloud shell intersection functions |
VolumetricCloudPass.cs |
Main cloud render pass |
AtmospherePass.cs |
Background atmosphere render pass |
- Temporal accumulation / TAA
- Ground/cloud shadow projection
- Full day-night cycle with sun elevation
- Earth surface & ocean curvature rendering