The volumetric pass marched 800 m in a fixed number of steps whatever the wall: it now stops at the
wall with steps in proportion (at least 8) - 0.57 -> 0.33 ms at 30 m by the pass timers. SSGI skipped
only past 900 m; it now also skips past 0.85 of a wall, where the fog is solid (u_ao_far). applyFog
samples the fog's colour only where its weight is above zero. A card layer whose casters inside the
wall are 80% or more of it (a kilometre's wall) casts from its static list and is not refiltered and
re-uploaded every 4 m of camera motion. Fog off: the frame unchanged (0 pixels over 8).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The DEM (R16 with mips, 44 MB) was read only by terrain_generate and kept for the map's life; a
world swap loads its own again. The height-field sun shadow was one RGBA32F for three values and an
unused fourth: the lowest lit height stays 32-bit (a receiver 3000 m up compares against it to a
quarter metre), the occluder distance and the cloud mask go beside it in RG16F (64 -> 32 MB), baked
in a pass of their own (TS_AUX): a pipeline takes one colour format for all its targets, and drawn
together into R32F + RG16F the writes went nowhere and nothing was lit.
-75 MB at every fog level, off included (2008 -> 1933 MB at the overlook); the fog-off frame is
unchanged (0 pixels over 8).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Whatever is cut at the wall is now cut inside full fog: at 0.3-1.0 the last metres before the cut
were 80-95% fogged against fully fogged ground behind, which drew a line of tufts at 70 m and a
dark band of blade tips at 30 m. The blades thin out while the fog is still coming in.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every lit program blends toward the horizon colour (the prefiltered sky with the sun's inscatter,
so it carries the day's grade); the sky's horizon band is pulled to the same colour, wider the
closer the wall. The far plane, scatter and stream cull reach and the shadow cascades are clamped
to the wall; the reflection pass shares the shaders and the cull. 0 is off: every branch is gated
on u_fog_wall > 0 and r3d_reach hands back the far it was given. R3D_FOG_WALL=<m> for a shot.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- grass_cull.comp decides each candidate blade once a frame (place, ground, density, water,
slope, frustum, colour field) and writes survivors into three bands by distance, one indirect
draw each; grass_inst.vert only bends and places the vertices. OpenGL keeps grass.vert's
per-vertex path; R3D_GRASS_GPU=0 compares
- compute programs take sampled textures after their buffers (gpu_compute_tex / gpu_dispatch_tex),
and every dispatch now records a compute-to-draw memory barrier
- the blades as a sward: 4 m cells, bands with five, three and one-quad blades, spacing doubling
every 18 m to 70 m, never narrower than a pixel; lit facing the sun and leaning to the sky,
shadow looked up above the ground (it read the terrain as its caster), a colour ramp that
leaves only the sheath dark, clumps, dry patches and a tussock shade worked out per blade
- scatter layers flagged grass are skipped while the blades draw (and under R3D_NOGRASS);
R3D_BLADES, R3D_NOBLADES win over the game's setting; R3D_GRASS_S0/D0 for measuring
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>