From c32d0077fc7f4be04f522270d5e0e22a717d8b94 Mon Sep 17 00:00:00 2001 From: pkuzic Date: Thu, 10 Sep 2026 22:50:17 +0100 Subject: [PATCH] =?UTF-8?q?MONKEY:=20lighting=20round=202=20=E2=80=94=20se?= =?UTF-8?q?ams,=20flicker,=20outdoor=20torch=20shadows,=20perf=20knobs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Seams - An exterior-class MOBA batch inside an interior group (the inn's cellar stair) took the night sky; its authored day weight is now scaled by the sun, so it joins the room law after dark. Exterior-class SHELL groups keep the sky law (moving them to the room law painted facades black at dusk). - Containment claims cross portals larger than 28 yd² (floor splits, gallery voids) at full weight, so a floor cut by a group boundary lights continuously. interiorDebug 4 colours WMO fragments by lane. wmolights prints group names, lane, portal areas. Fire - Flame lights flicker: band-limited sines + smoothed noise per fixture, candle fast/light to bonfire slow/deep, seeded by position, mean exactly 1; lamps never; authored fixtures only when warm. Cvar fireFlicker. Outdoor torch shadows (step a) - At night exterior fire lights become cube-map casters (half the map budget), WMO exteriors and models receive them with a world-distance fade; held torches never cast; a fire's own model is excluded from its map; daylight is bit-identical. Cvar exteriorShadows. Performance - Torch lane: static-scene fingerprint walk gated on a residency/part census (was 4 full walks per frame), entity caster rebuilt at interiorShadowEntityRate Hz (30) and gathered only within each fixture's reach, receiver shadow taps skipped at zero contribution, table and claim uploads and the torch bind group skipped when unchanged. Live bank sized to 8 dynamic slots (VRAM 192 -> 144 MiB). - Sun lanes: live cvars shadowMapSize (default 2048, was 4096), shadowFilter, characterShadowRate / worldShadowRate (30 Hz proxy rebuilds), shadowCasterReach. - Measured (inn, 1080p): debug 45 -> 61 FPS, release 83 FPS with everything on. Co-Authored-By: Claude Fable 5.1 --- crates/benilla-app/src/character_shadow.rs | 28 +- crates/benilla-app/src/cvars.rs | 128 +++- crates/benilla-app/src/dynamic_interior.rs | 4 + crates/benilla-app/src/entities.rs | 3 + crates/benilla-app/src/entities/attach/mod.rs | 8 +- .../benilla-app/src/entities/carried_light.rs | 79 ++- .../src/entities/equipment/spawn.rs | 4 +- crates/benilla-app/src/entities/wmo_props.rs | 18 +- crates/benilla-app/src/portrait/glue_booth.rs | 1 + crates/benilla-app/src/shadow_core.rs | 267 ++++++- crates/benilla-app/src/torch_shadow.rs | 670 ++++++++++++++++-- crates/benilla-app/src/video.rs | 82 ++- crates/benilla-app/src/world_shadow.rs | 24 +- crates/benilla-assets/src/m2.rs | 24 +- .../src/shaders/shadow_hook.wgsl | 22 +- .../benilla-assets/src/shaders/wow_model.wgsl | 212 +++++- .../src/bin/benilla-extract/scan/lighting.rs | 73 +- crates/benilla-formats/src/room_claim.rs | 195 ++++- crates/benilla-world/src/lighting/flicker.rs | 447 ++++++++++++ .../src/lighting/global_light.rs | 151 +++- crates/benilla-world/src/lighting/mod.rs | 7 +- .../benilla-world/src/shaders/static_gx.wgsl | 383 +++++++++- crates/benilla-world/src/static_gx/bake.rs | 2 + crates/benilla-world/src/static_gx/mod.rs | 18 +- crates/benilla-world/src/static_gx/render.rs | 133 +++- .../src/static_gx/torch_depth.rs | 266 ++++++- .../src/terrain_stream/spawn/assemble.rs | 14 +- .../src/terrain_stream/spawn/fx.rs | 25 + .../src/terrain_stream/spawn/mod.rs | 3 + 29 files changed, 3084 insertions(+), 207 deletions(-) create mode 100644 crates/benilla-world/src/lighting/flicker.rs diff --git a/crates/benilla-app/src/character_shadow.rs b/crates/benilla-app/src/character_shadow.rs index 56a8209a..149dda4a 100644 --- a/crates/benilla-app/src/character_shadow.rs +++ b/crates/benilla-app/src/character_shadow.rs @@ -17,7 +17,7 @@ use benilla_world::rig_palette::{RigPalettes, RigPart, RigSkin}; use crate::shadow_core::{ collect_entity_geometry, empty_shadow_mesh, restore_mesh_buffers, shadow_trace, - spawn_solid_caster, take_mesh_buffers, ShadowDemand, ShadowFrame, ShadowSet, + spawn_solid_caster, take_mesh_buffers, RebuildRate, ShadowDemand, ShadowFrame, ShadowSet, }; use crate::video::VideoConfig; @@ -37,11 +37,15 @@ struct CharacterLane { mesh: Option>, /// [`shadow_trace`]'s change detector: (tris, admitted, rejected). traced: (u32, u32, u32), + /// MONKEY (sun shadow perf): the `characterShadowRate` cadence gate — see the rebuild comment + /// in [`collect_character_shadows`]. + rate: RebuildRate, } #[allow(clippy::too_many_arguments)] fn collect_character_shadows( video: Res, + time: Res