render3d: under a fog wall the volumetric air is marched only to it, SSGI stops where it is solid, and card casters that fill the wall stop rebuilding

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>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-29 17:00:27 +03:00
parent 5b3cfac48e
commit 329439cf61
32 changed files with 36 additions and 14 deletions

View file

@ -2,6 +2,7 @@
// frame's lit colour; half resolution, denoised over time by the TAA history it feeds
in vec2 v_uv;
out vec4 o_color;
uniform float u_ao_far;
uniform sampler2D u_depth;
uniform sampler2D u_prev_color; // last frame's anti-aliased HDR colour
uniform mat4 u_inv_proj;
@ -18,7 +19,8 @@ vec3 viewPos(vec2 uv) {
}
void main() {
vec3 P = viewPos(v_uv);
if (-P.z > 900.0) { o_color = vec4(0.0, 0.0, 0.0, 1.0); return; }
// past 900 m, or where a fog wall has already hidden everything (u_ao_far, post.ludic)
if (-P.z > (u_ao_far > 0.0 ? u_ao_far : 900.0)) { o_color = vec4(0.0, 0.0, 0.0, 1.0); return; }
vec3 Pr = viewPos(v_uv + vec2(u_texel.x, 0.0)), Pl = viewPos(v_uv - vec2(u_texel.x, 0.0));
vec3 Pu = viewPos(v_uv + vec2(0.0, u_texel.y)), Pd = viewPos(v_uv - vec2(0.0, u_texel.y));
vec3 dx = (abs(Pr.z - P.z) < abs(P.z - Pl.z)) ? Pr - P : P - Pl;