Atmosphere, clouds, and volumetric light
Trace scattering tables, interleaved cloud ray marching, froxel lighting, temporal reprojection, and atmospheric composition.
Asterune evaluates planetary atmosphere, cloud layers, and local participating media through separate GPU resources. Atmosphere lookup tables describe light travel through a spherical medium. Clouds ray-march a density field. Volumetric fog samples a camera-aligned grid of scattering and extinction. Surface and sky shaders compose those results with scene light before image reconstruction.
These passes retain their own temporal state. Scene temporal anti-aliasing (TAA) does not replace cloud reprojection or fog accumulation. A changing camera can therefore affect several independent histories in the same frame.
Scattering and transmittance tables
The physical atmosphere represents Rayleigh scattering, Mie scattering and absorption, ozone absorption, planetary radii, and ground albedo. Rayleigh and Mie densities decrease exponentially with altitude. Ozone uses a bounded profile around its center altitude. The renderer converts world distances using 0.00028 km per stud before evaluating this planetary medium.
Extinction combines scattering and absorption. Along a segment of length d,
transmittance follows exp(-extinction * d). The integrator adds light scattered
into the ray, attenuated by the transmittance accumulated before that segment.
Sun and moon illumination use their own directions, visibility, and phase terms.
Rayleigh scattering favors its symmetric angular distribution; the Mie phase
concentrates light according to its asymmetry parameter.
Four floating-point lookup tables separate work by how often its inputs change:
| Table | Dimensions | Stored result |
|---|---|---|
| Transmittance | 256 × 64 | RGB light transmission by radius and ray direction |
| Multiple scattering | 32 × 32 | Approximate higher-order illumination by radius and light angle |
| Sky view | 192 × 108 | In-scattered sky radiance for the camera and lighting state |
| Aerial perspective | 64 × 32 × 32 | Cumulative RGB scattering and scalar transmittance by direction and distance |
The medium key contains planetary parameters and scattering or absorption coefficients. A changed key rebuilds transmittance and multiple scattering. Sky-view and aerial tables rebuild for each active main frame, so moving the camera or light does not require treating the medium itself as a different substance.
The transmittance build integrates 40 samples along each table ray. Multiple scattering evaluates 64 sphere directions with 20 samples each, reduces them within a workgroup, and approximates repeated scattering with a geometric-series factor. Sky view uses a 48-sample march. Aerial perspective advances through its distance slices with 4 integration samples per slice and stores the cumulative result at each boundary.
Cloud density and light transport
Cloud density comes from reusable 3D noise rather than independently generated geometry. A 128-cubed base texture combines Perlin and Worley noise at several frequencies. A 32-cubed detail texture supplies smaller-scale erosion. Broad weather samples warp coverage and group formations; finer octaves refine the shape only where they can affect cloud presence.
The density function combines this horizontal coverage with a vertical layer profile. Base noise forms the larger volume, while detail noise erodes its boundary differently near the base and top. Wind shifts the sample position. Evolution advances a retained phase, so changing the evolution rate changes its pace without abruptly selecting a different phase of the noise field.
A cloud ray first intersects the spherical cloud layer and clips its span to the available reach. The marcher chooses sample count from span length and the quality budget, with at least 8 steps. Long spans concentrate samples near their start. Each occupied sample updates transmittance and adds scattered light; transmittance below 0.01 ends the march.
Direct lighting makes a second, shorter march toward the sun or moon. That light-depth estimate uses 6 samples with increasing spacing. The scattering response combines directional single scattering with fitted diffuse terms for light scattered repeatedly inside the cloud. Ambient sky and illuminated ground also contribute. The returned cloud record includes radiance, transmittance, the first occupied distance, and a contribution-weighted mean distance.
Shared panorama and cloud shadows
The cloud panorama is a 512 × 256 image used by environment capture and views that do not own the main camera's cloud history. After initialization, each update marches one of 4 interleaved pixel patterns. Other pixels retain their previous values. A newly marched pixel blends 35% current data into its retained panorama value.
Panorama and cloud-shadow updates run no more often than once per 16,667 μs while clouds remain active. The main camera's cloud view has a separate update path and does not inherit that panorama cadence.
Cloud shadows use a 512 × 512 map. Each texel marches 16 samples through the cloud layer along sunlight and stores optical depth for the full layer and upper portions. Surface and volumetric lighting can sample that map rather than repeating the cloud-light march at every receiver.
Main-view interleaving and reprojection
The main cloud view uses full- or half-resolution texels, depending on its quality setting. Its array textures hold radiance and transmittance in one layer, plus front distance, mean distance, scene reach, and accumulated march count in another. Scene depth limits how far a cloud ray needs to travel. At half resolution, reach uses the farthest visible depth represented by the texel's covered pixels, preserving sky gaps around foreground geometry.
A valid sequence marches one texel from each 2 × 2 pattern per frame, rotating through all 4 patterns. Invalid history marches every texel. The resolve gathers fresh neighboring samples to estimate missing texels and establish color bounds. It prefers neighbors whose scene reach resembles the current texel's reach.
Reprojection places a representative point along the ray at the cloud's mean
distance. Camera translation and the previous ray-to-clip matrix map that point
into the preceding view. History is accepted only from bilinear taps whose
saved scene reach matches within 0.1 * max(old_reach, new_reach) + 0.01 km.
This rejects an old texel that previously stopped at a nearby cable instead of
seeing the cloud behind it.
Accepted history is clamped to the fresh neighborhood's range, expanded by 25% of that range plus 0.002 per channel. A freshly marched texel blends at least 30% current data. Its accumulation count stops at 3 marches. A texel that was only estimated from neighbors retains a lower count so a later direct march can replace that estimate.
A changed viewport rectangle, a camera displacement of at least 2 km, or an interrupted sequence invalidates cloud reprojection. Secondary interface views suspend the main cloud-view pass and use the shared panorama, preserving the main camera's history.
Froxel scattering and local volumes
Volumetric light uses a 160 × 90 × 64 grid of Rgba16Float froxels: 3D cells
aligned with camera rays. Slice boundaries follow
reach * (slice / slice_count)^2, concentrating depth resolution near the
camera. A frame-dependent jitter selects a sample location within each slice.
The injection pass evaluates scattering RGB and scalar extinction at that location. Contributions include atmospheric haze, local fog volumes, volumetric lights, and particle emission. Fog volumes transform the sample into local coordinates and evaluate box, spherical, or cylindrical bounds, with optional edge fade and height falloff. If more than 32 volumes are submitted, the renderer retains the nearest 32 to the camera.
Sun visibility combines scene shadows with cloud shadows. Local volumes also attenuate sunlight through their own density. Uniform box volumes use an analytic ray-box path length. Other shapes use 6 density samples with increasing step lengths. Local lights use their shadow visibility, attenuation, cone, and phase response inside the medium.
With at most 16 volumetric lights, froxels iterate a compact list of those light indices. Larger sets traverse the existing light tree and reject lights that do not contribute volumetrically. This avoids iterating every scene light for every froxel when only a small subset illuminates the medium.
Fog history and front-to-back integration
The injection pass reprojects froxel positions into the previous camera grid. An in-bounds history lookup contributes 85% of the injected result; fresh scattering and extinction contribute the remainder. Movement farther than one quarter of the configured reach resets retention. Disabling the active medium also clears its previous-camera state.
This blends local scattering and extinction before ray integration. A second
compute pass walks each column from front to back. For extinction sigma and
segment length d, it computes T = exp(-sigma * d) and adds
previous_transmittance * scattering * (1 - T) / sigma. For very small optical
depth, the segment length replaces that division to avoid numerical instability.
The output stores cumulative radiance and remaining transmittance at every
slice boundary.
Surface shading samples the integrated grid at the surface's direction and
distance, then applies color * transmittance + radiance. The inverse of the
squared slice mapping selects depth. A short fade within the first slice
prevents a finite near-camera sample from applying full fog at zero distance.
Particle emission uses a separate 40 × 23 × 16 accumulation grid. The scheduled fog pass reads that field before the particle simulation pass clears and writes the next field. Particle-to-fog emission therefore passes through retained GPU state across frames rather than creating independent local lights for every particle.
Composition and view ownership
Physical composition applies local haze and volumetric fog, then planetary aerial perspective, then clouds along the visible ray. When froxel haze covers the near portion of the ray, the analytic haze path removes that near extinction from its own contribution. This prevents the same near haze from attenuating surface color twice.
The physical atmosphere path requires the physical environment and is disabled when a custom environment replaces it. Cloud and fog work also depend on their resolved quality settings. A fog pass requires an enabled volumetric path and at least one haze, lamp, particle-glow, or volume contribution.
Atmosphere tables, panorama clouds, and cloud shadows are shared work across a stereo frame. Main-view cloud and froxel histories belong to their camera. Secondary views suspend those camera-dependent passes rather than replacing the main history with another camera's samples. Scene TAA later reconstructs the composed result using its own history validation.