MONKEY (leftovers): LightSkybox flags 0x8/0x10 plumbing; 0x10 suppresses the Modern sun-fog lobe

SKYBOX_FORCE_SUN_SHAFTS (0x8) and SKYBOX_NO_SUN_FOG (0x10) constants, CameraSkybox::flag_weight
(heaviest main layer carrying a flag). update_fog_model scales sun_fog_strength by 1 - weight of a
0x10 sky. LIGHTING.md documents both flags (0x8 consumer lands in the next commit).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
pkuzic
2026-09-26 15:55:15 +01:00
co-authored by Claude Opus 5.5
parent f5c58c81a2
commit 218ff0cfc0
6 changed files with 48 additions and 3 deletions
+1 -1
View File
@@ -35,7 +35,7 @@ behind each constant.
| Ambient occlusion | soft contact shadows under props, in wall-floor corners and around feet; depth-only SSAO at half resolution (depth-reconstructed normals, 6/12 spiral taps, 4x4 depth-aware blur, bilateral upsample) multiplied into the opaque scene after the opaque pass and before the water copy, so water, particles and UI are untouched; fades out 45-90 yd (Low) / 60-120 yd (High), spares sky and bright pixels; on alpha-tested foliage (a dense window of two-sided depth spikes) the blur widens its depth tolerance and the AO drops 40 %, which removes the leaf grain while planes, silhouettes and contact creases keep full AO (`benilla-app/src/ssao.rs`, `benilla-app/src/shaders/ssao.wgsl`) | Advanced Graphics → Ambient Occlusion (Off/Low/High; default Off, High preset 2), cvar `ambientOcclusion`, env `WOW_AO=0\|1\|2`, `WOW_AO_DEBUG=1..5` diagnostic views (factor, protection, distance, raw occlusion, foliage mask), `WOW_AO_GAIN`/`_RADIUS`/`_BIAS`/`_STRENGTH` tuning |
| Lamp fog | MONKEY (lampfog): the fog fullscreen pass selects the nearest resolved exterior and interior point-table sources and analytically integrates their softened inverse-square light over the camera-to-scene-depth ray. A near-field haze floor makes lamps visible inside the ordinary volumetric haze's 10 yd clear zone; it is zero by day, stronger in rain/fog, and deliberately unshadowed. The table colour already includes intensity, flame flicker and `fireLightGain`. Halo output uses destination headroom and stays below 1.0, so a later bloom pass cannot blow it out | Advanced Graphics → Lamp Fog, cvar `lampFog` 0 Off (default, unchanged) / 1 Low (16 lamps) / 2 High (32 lamps; Graphics preset High = 2), env `WOW_LAMPFOG=0\|1\|2`; `benilla-app/src/volumetric_fog.rs` |
| City window daylight | MONKEY (fix-daylight/integration): a district WMO's oversized window batch (e.g. the Cathedral of Light's stained-glass walls) is split into window-sized daylight apertures, so the nave takes daylight pane by pane. Applies to WMOs loaded after a change | Advanced Graphics → City Window Daylight, cvar `daylightWindowSplit` 0/1 (default 1, the merged behaviour); `benilla-world/src/lighting/daylight.rs` (`set_window_split`), bridge `benilla-app/src/dynamic_interior.rs` |
| Zone skyboxes | the painted sky a zone's `LightParams` names (clear-weather slot, storm slot lerped by the storm blend) for the living, fading in by the Light sphere falloff with the modern client's crossfade (ghost > WMO > zone); extended `LightSkybox.dbc` flags `0x1` day cycle, `0x2` keep sun/moon/stars/clouds, `0x4` fog-colour horizon cone, plus a celestial second model; every skybox now plays its bones, texture transforms, colour and alpha tracks (`benilla-world/src/skybox.rs`, `skybox_anim.rs`, `benilla-formats/src/light/skybox.rs`) | Advanced Graphics → Zone Skyboxes, cvar `zoneSkyboxes` (0 Off default, 1 On; High = 1), env `WOW_ZONE_SKYBOXES=0\|1` |
| Zone skyboxes | the painted sky a zone's `LightParams` names (clear-weather slot, storm slot lerped by the storm blend) for the living, fading in by the Light sphere falloff with the modern client's crossfade (ghost > WMO > zone); extended `LightSkybox.dbc` flags `0x1` day cycle, `0x2` keep sun/moon/stars/clouds, `0x4` fog-colour horizon cone, `0x8` forces the screen-space sun shafts through a low or just-set sun (the sky's weight lifts their daylight fade; `post/sun_shafts.rs`), `0x10` fades the Modern fog's sun-colour lobe out by the sky's weight (`lighting/fog_model.rs`), plus a celestial second model; every skybox now plays its bones, texture transforms, colour and alpha tracks (`benilla-world/src/skybox.rs`, `skybox_anim.rs`, `benilla-formats/src/light/skybox.rs`) | Advanced Graphics → Zone Skyboxes, cvar `zoneSkyboxes` (0 Off default, 1 On; High = 1), env `WOW_ZONE_SKYBOXES=0\|1` |
| Night and interior level | global dimming of the night sky term and of interior ambient | `nightGain`, `interiorGain`, `interiorBakeFloor` |
`zoneSkyboxes = 0` disables only the added living-player zone slot. WMO and ghost skyboxes are
+5 -1
View File
@@ -135,7 +135,11 @@ pub use light::{Atmosphere, LightCatalog, Submersion, ZERO_KEY_COLOR, ZERO_KEY_S
// MONKEY (fog): `LightFogBand.dbc`.
pub use light::{FogBand, FogBandCatalog, FOG_BANDS_PER_PARAM};
// MONKEY (skybox): the skybox row and the zone walk's entries.
pub use light::{SkyboxDef, ZoneSkybox, SKYBOX_FOG_BLEND, SKYBOX_FULL_DAY, SKYBOX_KEEP_CELESTIAL};
// MONKEY (leftovers): + the 0x8 / 0x10 flags.
pub use light::{
SkyboxDef, ZoneSkybox, SKYBOX_FOG_BLEND, SKYBOX_FORCE_SUN_SHAFTS, SKYBOX_FULL_DAY,
SKYBOX_KEEP_CELESTIAL, SKYBOX_NO_SUN_FOG,
};
mod loading_screen;
pub use loading_screen::{load_loading_screens, LoadingScreenCatalog};
mod liquid;
+5 -1
View File
@@ -19,7 +19,11 @@ mod tables;
pub use atmosphere::Atmosphere;
pub use fog_band::{FogBand, FogBandCatalog, FOG_BANDS_PER_PARAM};
pub use skybox::{SkyboxDef, ZoneSkybox, SKYBOX_FOG_BLEND, SKYBOX_FULL_DAY, SKYBOX_KEEP_CELESTIAL};
// MONKEY (leftovers): + the 0x8 / 0x10 flags.
pub use skybox::{
SkyboxDef, ZoneSkybox, SKYBOX_FOG_BLEND, SKYBOX_FORCE_SUN_SHAFTS, SKYBOX_FULL_DAY,
SKYBOX_KEEP_CELESTIAL, SKYBOX_NO_SUN_FOG,
};
use atmosphere::{
FB_CLOUD_DENSITY, FB_FOG_END, FB_FOG_START_MULT, IB_AMBIENT, IB_CLOUD_GBASE, IB_CLOUD_SLOPE,
IB_CLOUD_SUN, IB_DIFFUSE, IB_FOG_COLOR, IB_OCEAN_DEEP, IB_OCEAN_SHALLOW, IB_RIVER_DEEP,
@@ -26,6 +26,10 @@ pub const SKYBOX_FULL_DAY: u32 = 0x1;
pub const SKYBOX_KEEP_CELESTIAL: u32 = 0x2;
/// Flag `0x4`: an alpha cone in the final fog colour draws over the model's horizon.
pub const SKYBOX_FOG_BLEND: u32 = 0x4;
/// MONKEY (leftovers): flag `0x8`: sun shafts run under this sky even where they would fade.
pub const SKYBOX_FORCE_SUN_SHAFTS: u32 = 0x8;
/// MONKEY (leftovers): flag `0x10`: the fog's sun-colour lobe is off under this sky.
pub const SKYBOX_NO_SUN_FOG: u32 = 0x10;
/// One `LightSkybox.dbc` row.
#[derive(Clone, Debug, PartialEq, Eq)]
@@ -204,6 +204,8 @@ pub(super) fn update_fog_model(
eye_liquid: crate::liquid::EyeLiquid,
viewer: Res<crate::view::Viewer>,
weather: Option<Res<crate::weather::WeatherState>>,
// MONKEY (leftovers): LightSkybox flag 0x10 (last frame's backdrop; the skybox resolves later).
sky: Option<Res<crate::skybox::CameraSkybox>>,
mut frame: ResMut<MonkeyFrame>,
) {
let derived = derived_band(&lighting);
@@ -233,6 +235,9 @@ pub(super) fn update_fog_model(
};
let mut next = *frame;
fill_frame(&mut next, setting.0, &lighting, &band);
// MONKEY (leftovers): a `0x10` skybox fades the sun-fog lobe out by its weight.
let no_sun = sky.map_or(0.0, |s| s.flag_weight(benilla_formats::SKYBOX_NO_SUN_FOG));
next.sun_fog_strength *= 1.0 - no_sun.clamp(0.0, 1.0);
if *frame != next {
*frame = next;
}
+28
View File
@@ -92,6 +92,15 @@ impl CameraSkybox {
})
}
/// MONKEY (leftovers): the heaviest main layer's weight among those carrying `flag`, 0 if none.
pub fn flag_weight(&self, flag: u32) -> f32 {
self.0
.iter()
.filter(|l| !l.celestial && l.flags & flag != 0)
.map(|l| l.weight)
.fold(0.0, f32::max)
}
fn layer(&self, path: &str) -> Option<&SkyboxLayer> {
self.0.iter().find(|l| l.path == path)
}
@@ -1084,4 +1093,23 @@ mod tests {
});
assert_eq!(sky.primary().map(|l| l.path.as_str()), Some("b"));
}
/// MONKEY (leftovers): a flag's weight is its heaviest main carrier; celestial layers and
/// layers without the flag do not count.
#[test]
fn flag_weight_is_the_heaviest_main_carrier() {
let with = |path, w, flags| SkyboxLayer {
flags,
..layer(path, w)
};
let mut sky = CameraSkybox(vec![with("a", 0.3, 0x8), with("b", 0.7, 0x1), with("c", 0.5, 0x18)]);
sky.0.push(SkyboxLayer {
celestial: true,
..with("d", 1.0, 0x18)
});
assert_eq!(sky.flag_weight(benilla_formats::SKYBOX_FORCE_SUN_SHAFTS), 0.5);
assert_eq!(sky.flag_weight(benilla_formats::SKYBOX_NO_SUN_FOG), 0.5);
assert_eq!(sky.flag_weight(benilla_formats::SKYBOX_FOG_BLEND), 0.0);
assert_eq!(CameraSkybox::default().flag_weight(0x8), 0.0);
}
}