render3d: r3d_fog_wall(dist) - fog that closes to the sky's horizon colour from 0.3 dist to dist, and nothing drawn past dist + 8 m

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>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-29 15:07:40 +03:00
parent 160ce96e4f
commit b9f9cb8495
67 changed files with 335 additions and 227 deletions

View file

@ -285,6 +285,13 @@ vec3 shade(vec3 wpos, vec3 n, vec3 albedo, float rough, float metal, float ao, f
// is that air.
uniform float u_fog_inscatter; // how hard the air scatters the sun forward
uniform float u_fog_desat; // how fast distance takes a surface's own colour away
uniform float u_fog_wall; // r3d_fog_wall: > 0, the distance past which nothing is seen
// the colour the fog wall hides things in: the sky at the horizon under this view, and the sun
// scattered through it, so what is far melts into the sky behind it (the sky's band meets it)
vec3 fogWallCol(vec3 dir) {
vec3 c = skyPrefiltered(vec3(dir.x, max(dir.y, 0.02), dir.z), 0.6);
return c + u_sun_color * u_fog_inscatter * pow(max(dot(dir, u_sun_dir), 0.0), 8.0);
}
vec3 applyFog(vec3 col, vec3 wpos, float dist) {
vec3 dir = normalize(wpos - u_cam_pos);
float hf = u_fog_height_falloff;
@ -306,5 +313,11 @@ vec3 applyFog(vec3 col, vec3 wpos, float dist) {
// hour rather than only at the one where the sky was already grey.
float l = dot(col, vec3(0.2126, 0.7152, 0.0722));
col = mix(col, vec3(l), clamp(f * u_fog_desat, 0.0, 1.0));
return mix(col, fogCol, f);
col = mix(col, fogCol, f);
// the fog wall: from three tenths of its distance to all of it, everything goes to the sky's colour
if (u_fog_wall > 0.0) {
float w = smoothstep(0.3 * u_fog_wall, u_fog_wall, dist);
col = mix(col, fogWallCol(dir), w);
}
return col;
}

View file

@ -112,5 +112,11 @@ void main() {
float below = smoothstep(0.0, -0.08, dir.y);
vec3 fogCol = skyPrefiltered(vec3(dir.x, 0.02, dir.z), 0.6);
col = mix(col, fogCol, below);
// under a fog wall the horizon band is the fog's own colour, higher the thicker the fog, so what
// the wall hides meets the sky with no seam; the sky overhead stays
if (u_fog_wall > 0.0) {
float band = clamp(90.0 / u_fog_wall, 0.06, 0.75);
col = mix(col, fogWallCol(dir), 1.0 - smoothstep(-0.02, band, dir.y));
}
o_color = vec4(sane(col), 1.0);
}

File diff suppressed because it is too large Load diff