fix #427: sky drawn without fog like retail; world fog range is the keyframe's authored MinWorldFog/MaxWorldFog

Two April stand-ins, neither registered, met at the horizon from altitude as
a hard line between the dome's rim and the fog-coloured clear:

1. sky.frag fogged every non-additive sky layer with a 0.2 floor. Retail's
   GameSky::Draw @0x00506FF0 disables fixed-function fog around the whole
   sky draw unless an AdminEnvirons fog override is active (SetFFFogEnable(
   LScape::m_override_enabled ? 1 : 0)); additive layers stay unfogged via
   SetFFFogAlphaDisabled(1) at D3DPolyRender::SetSurface 0x59c882. The sky
   pass now sets ApplyFog only for (override active && !additive), with no
   floor.
2. WorldRenderFrameBuilder overwrote the authored fog range with one derived
   from the streaming window (538..2189 m always). Retail sets FOGSTART/
   FOGEND straight from the keyframe's MinWorldFog/MaxWorldFog
   (SkyDesc::GetWorldFog @0x00500CE0 -> SetFFFogProperties @0x005A2F70) with
   no draw-distance scaling; zfar is a constant 4000 m. The builder now
   leaves SceneLightingUbo.Build's values alone; ACDREAM_FOG_START_MULT /
   _END_MULT are deleted from RuntimeOptions.

Guards: SkyFogRuleTests (source-level, the sky renderer has no hermetic
harness); sky.frag.spv re-pinned in VulkanShaderManifestTests with the
reason. Research note 2026-04-23-sky-fog.md carries a correction banner.
App hermetic 6,070/0, Core 4,707/0 (Release). Owner look gate owed: night
and rain fog are now retail's shorter authored ranges.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-08-23 13:42:42 +02:00
parent 517d17b4b3
commit cc42edc8e3
11 changed files with 180 additions and 62 deletions

View file

@ -24,6 +24,42 @@ What does NOT go here:
- Every session: scan OPEN issues at start; promote/close anything we touched during the session before ending.
- Promoting to a Phase: mark as `DONE (promoted to Phase X)` + commit SHA where the Phase entry landed.
## #427 — Hard line below the horizon from altitude: the sky dome was fogged with a 0.2 floor and the world fog range came from the streaming window, not the keyframe
**Status:** ✅ FIXED 2026-08-23 (owner report, Candeth Keep/Holtburg heights: "a cut off where the sky ends and the world background void begins").
**Component:** rendering / sky + world fog (retail parity)
**Root causes (two April-2026 stand-ins, neither registered):**
1. `sky.frag` fogged every non-additive sky layer and clamped the blend with
`SKY_FOG_FLOOR = 0.2` ("mechanism unknown, workaround until pinned",
`97fc1b51`). The dome's rim (a sphere cut 500 m below the camera, radius
1050 m) was therefore 20 % texture / 80 % fog against a frame cleared to
100 % fog — a visible seam wherever terrain doesn't cover the rim (altitude,
water, map edge). Retail: `GameSky::Draw @0x00506FF0` draws the sky with
fixed-function fog DISABLED (`SetFFFogEnable(LScape::m_override_enabled ?
1 : 0)` around the sky draw) — fog touches the dome only under an
AdminEnvirons override; additive layers are never fogged
(`SetFFFogAlphaDisabled(1)` at `D3DPolyRender::SetSurface 0x59c882`).
2. `WorldRenderFrameBuilder` overwrote the UBO's authored fog range with
0.7 × near radius .. 0.95 × far radius (538..2189 m) at every hour and
weather (`ACDREAM_FOG_START_MULT`/`_END_MULT`). Retail sets
`D3DRS_FOGSTART/FOGEND` straight from the keyframe's `MinWorldFog/
MaxWorldFog` (`SkyDesc::GetWorldFog @0x00500CE0` → `LScape::UseTime` →
`RenderDeviceD3D::SetFFFogProperties @0x005A2F70`, no draw-distance
scaling; `Render::zfar` is a constant 4000 m). Authored Sunny: day
1502400 m, dawn/dusk 90800, night 0400; Rainy day 1501500.
**Fix:** sky pass `ApplyFog = environOverrideActive && !additive`, no floor;
the frame builder leaves `SceneLightingUbo.Build`'s authored `FogParams.xy`
alone; the two env multipliers are deleted from `RuntimeOptions`. Guard:
`SkyFogRuleTests` (source-level; the sky renderer has no hermetic harness);
`sky.frag.spv` re-pinned in `VulkanShaderManifestTests` with the reason.
**Visible consequence (owner gate owed):** night and rain fog are now
retail's much shorter ranges; the dome's horizon tint is the authored
texture alone. The streaming window (≥ 2.1 km from the player) still sits
at/beyond every authored fog end except Sunny day's 2400 m, where the far
edge lands ~96 % fogged.
## #426 — Every solid-colour (untextured) polygon on every object client-wide was invisible: mesh extraction misread NO_POS_UVS as "no positive face"
**Status:** ✅ FIXED 2026-08-23 (found on the Holtburg windmill axle, GfxObj

View file

@ -1,3 +1,13 @@
> **CORRECTION 2026-08-23 (#427).** This note assumed retail fogs its sky
> meshes ("the sky dome mesh is at a distance where fog contribution
> dominates"). It does not: `GameSky::Draw @0x00506FF0` disables fixed-
> function fog around the entire sky draw unless an AdminEnvirons fog
> override is active. The dome's horizon colour is the authored texture plus
> the keyframe tint. The `SKY_FOG_FLOOR = 0.2` clamp that this assumption
> produced was removed the same day. Q3's terrain-fog conclusions (authored
> `MinWorldFog/MaxWorldFog` applied directly, no scaling) stand and are now
> what the client does.
# Sky Fog — How Retail Applies Fog to Sky Meshes (Decompile Trace)
**Date:** 2026-04-23