From f5c58c81a2eef2b304e364f67047cb92c1152a76 Mon Sep 17 00:00:00 2001 From: pkuzic Date: Sat, 26 Sep 2026 06:00:26 +0100 Subject: [PATCH] MONKEY (visualfix): volumetric fog density follows the rendered clock The dawn/weather density curve read WorldTime, the server clock, which stays at its noon default offline, so a manual or capture time never got the dawn mist. It now reads the rendered minute through grading's rendered_minute (the same rule as ac9a1ef3). Baselines move: volfog-dawn is mistier (MAE 8.5), volfog-night is unchanged (0.07). Co-Authored-By: Claude Opus 5.5 --- LIGHTING.md | 2 +- crates/benilla-app/src/post/grading.rs | 2 +- crates/benilla-app/src/post/mod.rs | 3 ++- crates/benilla-app/src/volumetric_fog.rs | 8 +++++++- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/LIGHTING.md b/LIGHTING.md index 2b40ac08..651e4aa7 100644 --- a/LIGHTING.md +++ b/LIGHTING.md @@ -25,7 +25,7 @@ behind each constant. | Spell and firework lights | fire, holy and fel effects light their surroundings for their lifetime; frost, nature, arcane and shadow do not | `spellLightGain`, env `WOW_SPELL_LIGHT=0` | | Moon shadows | at night the same shadow rig re-aims at the moon and casts a faint shadow; dims only the night sky term, never point lights | `moonShadowStrength` | | Ground-effect spells | Flamestrike, Rain of Fire, Consecration, Flare and fire traps light the ground for their duration; frost and nature areas stay dark | `spellLightGain` | -| Volumetric fog | near-field haze that converges on the zone fog colour (clear within 10 yd, full by 150 yd; mistier at dawn and in bad weather, faint indoors) and sun/moon light shafts through gaps, sampled from the shadow map; own fullscreen pass after the main pass (`benilla-app/src/volumetric_fog.rs`) | Advanced Graphics → Volumetric Fog (Off/Low/High), cvar `volumetricFog`, env `WOW_VOLFOG=0\|1\|2` | +| Volumetric fog | near-field haze that converges on the zone fog colour (clear within 10 yd, full by 150 yd; mistier at dawn and in bad weather, faint indoors; the dawn curve follows the rendered clock, so a manual or capture time sets it; over an ocean a point below sea level is hazed at the sea surface, since water writes no depth) and sun/moon light shafts through gaps, sampled from the shadow map; own fullscreen pass after the main pass (`benilla-app/src/volumetric_fog.rs`) | Advanced Graphics → Volumetric Fog (Off/Low/High), cvar `volumetricFog`, env `WOW_VOLFOG=0\|1\|2` | | Sky dithering | a faint screen-space dither in the FFXGlow combine so smooth sky and fog gradients do not band (MONKEY p0; was env-only) | Advanced Graphics → Sky Dithering, cvar `skyDither` 0/1 (default 0, Graphics preset High = 1), env `WOW_DITHER=1` still forces it on; bridge in `benilla-app/src/monkey_gfx.rs` | | HDR emission and bloom | lit WMO windows, additive models/particles and magma can exceed display white; a soft-capped fullscreen halo is added before the faithful FFX clamp | Advanced Graphics → Bloom (Off/Low/High), cvar `bloom`; Off is the unchanged reference image, suggested High preset value 2 | | Sky quality | Enhanced: the five Light.dbc sky stops through a smooth monotone curve in linear light (no bands at the rings), a soft sun glow tinted by sun and fog colour (fades at night and under cloud), a procedural star field with twinkle and a faint Milky Way over the stock `Stars.m2`. High adds domain-warped cloud detail and sun-lit clouds (self-shadow, silver lining; technique from WarcraftXL, see `THIRD-PARTY.md`). Classic is the reference sky unchanged | Advanced Graphics → Sky Quality, cvar `skyQuality` 0 Classic / 1 Enhanced / 2 High, env `WOW_SKY_QUALITY` | diff --git a/crates/benilla-app/src/post/grading.rs b/crates/benilla-app/src/post/grading.rs index 82048096..c5ead119 100644 --- a/crates/benilla-app/src/post/grading.rs +++ b/crates/benilla-app/src/post/grading.rs @@ -362,7 +362,7 @@ fn update_views( /// MONKEY (reviewfix-a): the server's fractional minute while it is the minute being rendered, /// else the rendered (manual or capture) minute. -fn rendered_minute(time: &WorldTime, rendered: Option<&benilla_world::lighting::GameClock>) -> f32 { +pub(crate) fn rendered_minute(time: &WorldTime, rendered: Option<&benilla_world::lighting::GameClock>) -> f32 { match rendered { Some(c) if time.minute_f.floor() as u32 != c.minute => c.minute as f32, _ => time.minute_f, diff --git a/crates/benilla-app/src/post/mod.rs b/crates/benilla-app/src/post/mod.rs index 2952e5a6..b25cbc26 100644 --- a/crates/benilla-app/src/post/mod.rs +++ b/crates/benilla-app/src/post/mod.rs @@ -1,7 +1,8 @@ //! MONKEY (post): optional world-camera effects ahead of FFXGlow's gamma clamp. mod bloom; -mod grading; +// MONKEY (visualfix): crate-visible for `rendered_minute` (volumetric fog). +pub(crate) mod grading; mod sun_shafts; pub(crate) struct PostPlugin; diff --git a/crates/benilla-app/src/volumetric_fog.rs b/crates/benilla-app/src/volumetric_fog.rs index 374b99f5..56d540e2 100644 --- a/crates/benilla-app/src/volumetric_fog.rs +++ b/crates/benilla-app/src/volumetric_fog.rs @@ -241,6 +241,8 @@ fn update_fog( interior: Res, // MONKEY (lampfog): the resolved point-table view published by global_light's packer. point_lights: Res, + // MONKEY (visualfix): the minute the lighting rendered (manual / capture clock offline). + rendered: Option>, // MONKEY (fog): the Modern fog rows (Option: absent in unit tests). monkey: Option>, mut cameras: Query< @@ -331,7 +333,11 @@ fn update_fog( lamp_positions: lamps.positions, lamp_colors: lamps.colors, color_density: fog.extend( - density(clock.minute_f, weather_amount, interior.0.is_some()) + density( + crate::post::grading::rendered_minute(&clock, rendered.as_deref()), + weather_amount, + interior.0.is_some(), + ) * if tier == 0 { 0.0 } else if tier == 2 {