Interior rooms light per fragment from their authored fixtures instead of the MOCV bake (direct + fill + ambient, soft rolloff; live cvars interiorLight/interiorAmbient/interiorFill/interiorExposure/interiorShadows/ interiorDebug), TRANS/EXT batches blend to the day/night reference at the portal seam, and fixtures admit camera-independently (90 yd). Torch shadows are a from-scratch depth-map renderer (Bevy point shadows are dead under ClusterConfig::None): a shared Depth32Float 512^2 x 24-layer Image + depth-only pipeline + ViewNode rendering the static caster and a per-frame entity caster into 6 cube faces for the nearest <=4 fixtures (reverse-Z, GreaterEqual compare, 4-tap PCF, far fade). WMO surfaces receive through static_gx group 3; entities receive on the wow_model path through WowModelExt bindings 91/92/93 (depth array, comparison sampler, 1616-byte torch table) with a 0.15 yd normal offset against CPU-vs-GPU skinning self-shadow. The entity lane is gated on is_interior OR the new MATTE_INDOOR tag bit (exterior payload bit 14, written by the classifier's Matte law), so a unit whose verdict flickers Bake<->Matte at one spot keeps its room lighting. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
38 lines
1.5 KiB
Rust
38 lines
1.5 KiB
Rust
//! MONKEY (dynamic interiors): the app-side half of the fixture-lit WMO interior lane — a
|
|
//! plug-and-play bridge from the `interiorLight` / `interiorAmbient` / `interiorFill` /
|
|
//! `interiorExposure` cvars ([`VideoConfig`]) to benilla-world's [`DynamicInteriors`] resource,
|
|
//! which `global_light` packs for `static_gx.wgsl`'s `interior_room_light` (WMO interior surfaces
|
|
//! AND interior props light from the room's live fixtures instead of the MOCV bake / the baked prop
|
|
//! probe). Independent of the shadow lanes: removing this plugin leaves the resource at its
|
|
//! shipped defaults; `interiorLight 0` restores the faithful baked interior path.
|
|
//!
|
|
//! The knobs are LIVE — `/script SetCVar("interiorExposure", 2)` in chat retunes the room without
|
|
//! a rebuild, which is how the defaults were found.
|
|
use benilla_world::lighting::DynamicInteriors;
|
|
use bevy::prelude::*;
|
|
|
|
use crate::video::VideoConfig;
|
|
|
|
pub(crate) struct DynamicInteriorPlugin;
|
|
|
|
impl Plugin for DynamicInteriorPlugin {
|
|
fn build(&self, app: &mut App) {
|
|
app.add_systems(Update, bridge);
|
|
}
|
|
}
|
|
|
|
/// Publish the cvars to benilla-world when they change. Guarded so the resource's change ticks
|
|
/// stay quiet on idle frames.
|
|
fn bridge(video: Res<VideoConfig>, mut out: ResMut<DynamicInteriors>) {
|
|
let want = DynamicInteriors {
|
|
enabled: video.interior_light,
|
|
ambient: video.interior_ambient,
|
|
fill: video.interior_fill,
|
|
exposure: video.interior_exposure,
|
|
debug: video.interior_debug,
|
|
};
|
|
if *out != want {
|
|
*out = want;
|
|
}
|
|
}
|