From c13613e259e7096e44f3e6f55123b0111602c1db Mon Sep 17 00:00:00 2001 From: Cyd Date: Wed, 8 Jul 2026 20:32:38 -0500 Subject: [PATCH] GL fog: per-fragment factor -- terrain/cloud no longer escape the fog Fog was computed per VERTEX; vertices behind the eye clamped to factor zero, and the terrain/cloud triangles are large enough to span the camera, so interpolation dragged the whole ground to unfogged (bright terrain through the pre-drop blackout and the respawn reveal). The eye-space depth now rides the varying (perspective-correct) and the factor is computed per fragment, where clipping guarantees valid depth. Verified offline: pre-drop hold renders solid black + HUD only (matches the period screenshot exactly); the respawn fade shows the authentic near-first reveal from the operator's VHS (ground clear, fog wall at distance, sky still white). Co-Authored-By: Claude Fable 5 --- dpl3-revive/patha/vrview_gl.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/dpl3-revive/patha/vrview_gl.py b/dpl3-revive/patha/vrview_gl.py index ebde7ce..a326003 100644 --- a/dpl3-revive/patha/vrview_gl.py +++ b/dpl3-revive/patha/vrview_gl.py @@ -84,9 +84,12 @@ void main() { if (u_has_col == 1) base *= in_col; // vertex colors modulate v_base = clamp(base, 0.0, 1.0); v_uv = in_uv; - v_fog = (u_fog_on == 1) - ? clamp((z - u_fogrange.x) / (u_fogrange.y - u_fogrange.x), 0.0, 1.0) - : 0.0; + // fog factor moves to the FRAGMENT shader: computing it per vertex + // zeroed it on vertices BEHIND the eye, and the terrain/cloud triangles + // are huge enough to span the camera -- interpolation dragged the whole + // ground to "unfogged" (the pre-drop blackout leak). The eye depth + // itself interpolates perspective-correct, so pass that instead. + v_fog = z; } """ @@ -98,6 +101,8 @@ uniform int u_alpha_cut; uniform vec2 u_uvoff; // board-side SCROLL uniform float u_opacity; // DITHER n -> screen-door uniform vec3 u_fogcol; +uniform int u_fog_on; +uniform vec2 u_fogrange; // near, far in vec3 v_base; in vec2 v_uv; in float v_fog; @@ -120,7 +125,11 @@ void main() { } // alpha only takes effect in the deferred blended pass (opaque pass // renders with BLEND disabled) - f_color = vec4(mix(rgb, u_fogcol, v_fog), clamp(v_alpha, 0.0, 1.0)); + float fogf = (u_fog_on == 1) + ? clamp((v_fog - u_fogrange.x) / (u_fogrange.y - u_fogrange.x), + 0.0, 1.0) + : 0.0; + f_color = vec4(mix(rgb, u_fogcol, fogf), clamp(v_alpha, 0.0, 1.0)); } """