From dfc9121eb1a8d365cb0102aafd7a767eeffcca4f Mon Sep 17 00:00:00 2001 From: pkuzic Date: Fri, 25 Sep 2026 07:52:05 +0100 Subject: [PATCH 1/3] MONKEY (p0): graphics-programme baseline capture scenarios Appended at the end of ON_DEMAND: elwynn-noon/dusk/night, elwynn-rain (run with WOW_WEATHER=1,0.8), westfall-farm, redridge-lake, duskwood-road, burning-steppes, blasted-lands-portal, hyjal-mount (Kalimdor, Light.dbc sphere 270 / params 269), stormwind-cathedral-interior, ironforge-forge. Positions checked against the Light.dbc spheres with benilla-extract lightslots (Westfall 17, Duskwood 14, Burning Steppes 23, Blasted Lands 21, Hyjal 269). Co-Authored-By: Claude Opus 5.5 --- crates/benilla-app/src/capture/scenarios.rs | 75 +++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/crates/benilla-app/src/capture/scenarios.rs b/crates/benilla-app/src/capture/scenarios.rs index d970a9fd..c3544d5a 100644 --- a/crates/benilla-app/src/capture/scenarios.rs +++ b/crates/benilla-app/src/capture/scenarios.rs @@ -1379,8 +1379,83 @@ pub(super) const ON_DEMAND: &[Scenario] = &[ minute: 0, ui: None, }, + // ---- MONKEY (p0 baseline): the graphics programme's baseline set ---- + // Every lane diffs its work against captures of these (plus the water-*, volfog-* and canal + // scenes above). Raw WoW coords, map per scenario; noon = 720, dusk = 1170, night = 0. + // Elwynn from the Goldshire road toward the lake and the forest: sky, fog and trees. + Scenario { + name: "elwynn-noon", map: Some(MAP_AZEROTH), + eye: GFX_ELWYNN_EYE, look: GFX_ELWYNN_LOOK, minute: 720, ui: None, + }, + Scenario { + name: "elwynn-dusk", map: Some(MAP_AZEROTH), + eye: GFX_ELWYNN_EYE, look: GFX_ELWYNN_LOOK, minute: 1170, ui: None, + }, + Scenario { + name: "elwynn-night", map: Some(MAP_AZEROTH), + eye: GFX_ELWYNN_EYE, look: GFX_ELWYNN_LOOK, minute: 0, ui: None, + }, + // The same Elwynn view for rain. Capture has no weather field: run it with + // `WOW_WEATHER=1,0.8` (kind 1 rain, grade 0.8; `weather::parse_env_script`). + Scenario { + name: "elwynn-rain", map: Some(MAP_AZEROTH), + eye: GFX_ELWYNN_EYE, look: GFX_ELWYNN_LOOK, minute: 720, ui: None, + }, + // Westfall: a farmstead, fields and the dry palette. + Scenario { + name: "westfall-farm", map: Some(MAP_AZEROTH), + eye: [-10080.0, 1000.0, 58.0], look: [-10140.0, 1070.0, 38.0], minute: 720, ui: None, + }, + // Redridge: Lake Everstill from above Lakeshire, a wider frame than `water-lake`. + Scenario { + name: "redridge-lake", map: Some(MAP_AZEROTH), + eye: [-9250.0, -2200.0, 110.0], look: [-9450.0, -2600.0, 55.0], minute: 720, ui: None, + }, + // Duskwood: the road into Darkshire, the zone's short dark fog. + Scenario { + name: "duskwood-road", map: Some(MAP_AZEROTH), + eye: [-10560.0, -1000.0, 50.0], look: [-10570.0, -1200.0, 32.0], minute: 720, ui: None, + }, + // Burning Steppes: the ash plain and the sky a skybox would replace. + Scenario { + name: "burning-steppes", map: Some(MAP_AZEROTH), + eye: [-7700.0, -2100.0, 200.0], look: [-7900.0, -1700.0, 150.0], minute: 720, ui: None, + }, + // Blasted Lands: the Dark Portal from the north. + Scenario { + name: "blasted-lands-portal", map: Some(MAP_AZEROTH), + eye: [-11700.0, -3200.0, 20.0], look: [-11900.0, -3208.0, 0.0], minute: 720, ui: None, + }, + // Mount Hyjal (Kalimdor), inside Light.dbc sphere 270. + Scenario { + name: "hyjal-mount", map: Some(MAP_KALIMDOR), + eye: GFX_HYJAL_EYE, look: GFX_HYJAL_LOOK, minute: 720, ui: None, + }, + // Stormwind: the Cathedral of Light's nave (interior WMO lighting). + Scenario { + name: "stormwind-cathedral-interior", map: Some(MAP_AZEROTH), + eye: GFX_CATHEDRAL_EYE, look: GFX_CATHEDRAL_LOOK, minute: 720, ui: None, + }, + // Ironforge: the Great Forge (lava, fire light, a huge interior). + Scenario { + name: "ironforge-forge", map: Some(MAP_AZEROTH), + eye: GFX_FORGE_EYE, look: GFX_FORGE_LOOK, minute: 720, ui: None, + }, ]; +/// MONKEY (p0 baseline): the Elwynn programme view, east of Goldshire looking south-west. +pub(super) const GFX_ELWYNN_EYE: [f32; 3] = [-9380.0, -30.0, 80.0]; +pub(super) const GFX_ELWYNN_LOOK: [f32; 3] = [-9600.0, -200.0, 62.0]; +/// MONKEY (p0 baseline): Mount Hyjal, Light.dbc sphere 270's centre (world yards). +pub(super) const GFX_HYJAL_EYE: [f32; 3] = [4636.0, -4461.0, 900.0]; +pub(super) const GFX_HYJAL_LOOK: [f32; 3] = [4836.0, -4361.0, 870.0]; +/// MONKEY (p0 baseline): the Cathedral of Light nave, standing over the floor. +pub(super) const GFX_CATHEDRAL_EYE: [f32; 3] = [-8530.0, 845.0, 112.0]; +pub(super) const GFX_CATHEDRAL_LOOK: [f32; 3] = [-8500.0, 880.0, 110.0]; +/// MONKEY (p0 baseline): the Great Forge ring. +pub(super) const GFX_FORGE_EYE: [f32; 3] = [-4870.0, -1010.0, 512.0]; +pub(super) const GFX_FORGE_LOOK: [f32; 3] = [-4920.0, -960.0, 502.0]; + /// The owner's reported vantage for the lava-glow report: `(-7048.8, -1000.6, 242.0)` facing /// 1.53 rad, Searing Gorge, map 0. The eye takes the standard [`VISTA_EYE_HEIGHT`]-ish lift off /// the pin (a `.go` lands at the feet) and the look runs 60 yd down the reported facing, From 05d6b1adf33b78d783edf25ef32deb295f2079de Mon Sep 17 00:00:00 2001 From: pkuzic Date: Fri, 25 Sep 2026 08:37:39 +0100 Subject: [PATCH 2/3] MONKEY (p0): WGSL fixes found by the world-scene run naga_oil refuses a composable-module identifier that naga's namer would rewrite (a trailing digit gets a '_'), which failed every pipeline that imports monkey_frame / enhanced_water (models, WMOs, liquid invisible). MonkeyFrame rows are renamed fog_a..fog_d, wind_a/b, wet_a (same order and layout), and enhanced_water's padding member _sh_c16 becomes _sh_quad. Co-Authored-By: Claude Opus 5.5 --- LIGHTING.md | 14 +++++++------- .../src/shaders/enhanced_water.wgsl | 2 +- crates/benilla-assets/src/shaders/fog_hook.wgsl | 6 +++--- .../benilla-assets/src/shaders/monkey_frame.wgsl | 16 +++++++++------- .../benilla-world/src/lighting/monkey_frame.rs | 16 ++++++++-------- 5 files changed, 28 insertions(+), 26 deletions(-) diff --git a/LIGHTING.md b/LIGHTING.md index bb879614..6a3a2d69 100644 --- a/LIGHTING.md +++ b/LIGHTING.md @@ -65,13 +65,13 @@ is its own module, documented in `WATER.md`. | row | x | y | z | w | |---|---|---|---|---| - | `fog0` | height_fog_density | height_fog_height | height_fog_falloff | curve_blend | - | `fog1` | sun_fog r | g | b | sun_fog_strength | - | `fog2` | end_fog r | g | b | end_fog_distance | - | `fog3` | fog_model (0 classic, 1 modern) | sun_fog_angle | 0 | 0 | - | `wind0` | dir_x | dir_y | speed | gust | - | `wind1` | time_s | sway_strength | grass_strength | tree_strength | - | `wet0` | rain_rate | wetness | ripple_time_s | snow | + | `fog_a` | height_fog_density | height_fog_height | height_fog_falloff | curve_blend | + | `fog_b` | sun_fog r | g | b | sun_fog_strength | + | `fog_c` | end_fog r | g | b | end_fog_distance | + | `fog_d` | fog_model (0 classic, 1 modern) | sun_fog_angle | 0 | 0 | + | `wind_a` | dir_x | dir_y | speed | gust | + | `wind_b` | time_s | sway_strength | grass_strength | tree_strength | + | `wet_a` | rain_rate | wetness | ripple_time_s | snow | | `misc` | bender_count | time_of_day 0..1 | night 0..1 | 0 | | `benders[8]` | world x | world y | world z | radius | diff --git a/crates/benilla-assets/src/shaders/enhanced_water.wgsl b/crates/benilla-assets/src/shaders/enhanced_water.wgsl index 80d54670..4d7d2789 100644 --- a/crates/benilla-assets/src/shaders/enhanced_water.wgsl +++ b/crates/benilla-assets/src/shaders/enhanced_water.wgsl @@ -53,7 +53,7 @@ struct WaterLight { fog_color: vec4, // 4 fog_params: vec4, // 5 _sh: array, 6>, // 6-11 - _sh_c16: vec4, // 12 + _sh_quad: vec4, // 12 (MONKEY p0: was `_sh_c16`; a composable module member may not end in a digit once the struct embeds an imported type) water_river: array, 2>, // 13-14 water_ocean: array, 2>, // 15-16 _grade: vec4, // 17 diff --git a/crates/benilla-assets/src/shaders/fog_hook.wgsl b/crates/benilla-assets/src/shaders/fog_hook.wgsl index e931ccf9..6730fbd8 100644 --- a/crates/benilla-assets/src/shaders/fog_hook.wgsl +++ b/crates/benilla-assets/src/shaders/fog_hook.wgsl @@ -13,7 +13,7 @@ // `mix(fog_rgb, rgb, factor)`. The expressions below are the ones the receivers carried, in the // same order, so the classic result is bit-identical. // -// Extension point for the FOG lane: `fog_sample` branches on `mf.fog3.x` (`MonkeyFrame.fog_model`, +// Extension point for the FOG lane: `fog_sample` branches on `mf.fog_d.x` (`MonkeyFrame.fog_model`, // 0 classic / 1 modern). The modern arm currently returns the classic result. #import benilla::monkey_frame::MonkeyFrame @@ -39,9 +39,9 @@ fn fog_sample( mf: MonkeyFrame, ) -> vec4 { let classic = vec4(fog_rgb, fog_linear(eye_z, span)); - if (mf.fog3.x > 0.5) { + if (mf.fog_d.x > 0.5) { // FOG lane: the modern model (height / sun / end-colour / curve fog) goes here, reading - // mf.fog0..fog3. Until it lands, the modern arm is the classic law. + // mf.fog_a..fog_d. Until it lands, the modern arm is the classic law. return classic; } return classic; diff --git a/crates/benilla-assets/src/shaders/monkey_frame.wgsl b/crates/benilla-assets/src/shaders/monkey_frame.wgsl index ea1780b3..97cbeba8 100644 --- a/crates/benilla-assets/src/shaders/monkey_frame.wgsl +++ b/crates/benilla-assets/src/shaders/monkey_frame.wgsl @@ -8,14 +8,16 @@ // // Coordinates are Bevy world space (Y up, 1 unit = 1 yd), the space of the receivers' // `world_position`: WoW `(x, y, z)` is Bevy `(-y, z, -x)` (`benilla_assets::coords::wow_to_bevy`). +// Member names carry no trailing digit: naga_oil refuses a composable-module identifier that +// naga's namer would rewrite (`fog0` -> `fog0_`), so the rows are `fog_a..fog_d`, `wind_a/b`, `wet_a`. struct MonkeyFrame { - fog0: vec4, // height_fog_density, height_fog_height (world Y, yd), height_fog_falloff, curve_blend - fog1: vec4, // sun_fog_rgb (gamma 0..1), sun_fog_strength - fog2: vec4, // end_fog_rgb (gamma 0..1), end_fog_distance (yd) - fog3: vec4, // fog_model (0 classic, 1 modern), sun_fog_angle (cos), 0, 0 - wind0: vec4, // dir_x, dir_y (unit, world XZ: .x = world x, .y = world z), speed (yd/s), gust 0..1 - wind1: vec4, // time_s, sway_strength, grass_strength, tree_strength - wet0: vec4, // rain_rate 0..1, wetness 0..1, ripple_time_s, snow 0..1 + fog_a: vec4, // height_fog_density, height_fog_height (world Y, yd), height_fog_falloff, curve_blend + fog_b: vec4, // sun_fog_rgb (gamma 0..1), sun_fog_strength + fog_c: vec4, // end_fog_rgb (gamma 0..1), end_fog_distance (yd) + fog_d: vec4, // fog_model (0 classic, 1 modern), sun_fog_angle (cos), 0, 0 + wind_a: vec4, // dir_x, dir_y (unit, world XZ: .x = world x, .y = world z), speed (yd/s), gust 0..1 + wind_b: vec4, // time_s, sway_strength, grass_strength, tree_strength + wet_a: vec4, // rain_rate 0..1, wetness 0..1, ripple_time_s, snow 0..1 misc: vec4, // bender_count, time_of_day 0..1 (packer), night 0..1 (packer), 0 benders: array, 8>, // world xyz (Bevy space) + radius (yd); the first bender_count are live } diff --git a/crates/benilla-world/src/lighting/monkey_frame.rs b/crates/benilla-world/src/lighting/monkey_frame.rs index 3ca56f7d..c583ec98 100644 --- a/crates/benilla-world/src/lighting/monkey_frame.rs +++ b/crates/benilla-world/src/lighting/monkey_frame.rs @@ -14,13 +14,13 @@ //! //! | row | xyz / x,y,z | w | //! |---|---|---| -//! | 0 `fog0` | height_fog_density, height_fog_height, height_fog_falloff | curve_blend | -//! | 1 `fog1` | sun_fog_rgb | sun_fog_strength | -//! | 2 `fog2` | end_fog_rgb | end_fog_distance | -//! | 3 `fog3` | fog_model (0 classic, 1 modern), sun_fog_angle, 0 | 0 | -//! | 4 `wind0` | dir_x, dir_y, speed | gust | -//! | 5 `wind1` | time_s, sway_strength, grass_strength | tree_strength | -//! | 6 `wet0` | rain_rate, wetness, ripple_time_s | snow | +//! | 0 `fog_a` | height_fog_density, height_fog_height, height_fog_falloff | curve_blend | +//! | 1 `fog_b` | sun_fog_rgb | sun_fog_strength | +//! | 2 `fog_c` | end_fog_rgb | end_fog_distance | +//! | 3 `fog_d` | fog_model (0 classic, 1 modern), sun_fog_angle, 0 | 0 | +//! | 4 `wind_a` | dir_x, dir_y, speed | gust | +//! | 5 `wind_b` | time_s, sway_strength, grass_strength | tree_strength | +//! | 6 `wet_a` | rain_rate, wetness, ripple_time_s | snow | //! | 7 `misc` | bender_count, time_of_day 0..1, night 0..1 | 0 | //! | 8-15 `benders` | world x, y, z | radius | //! @@ -38,7 +38,7 @@ pub const MONKEY_FRAME_ROWS: usize = 16; /// How many benders (grass/foliage pushers: the player and nearby units) the block carries. pub const MAX_BENDERS: usize = 8; -/// The fog model selector, `fog3.x`. +/// The fog model selector, `fog_d.x`. #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] pub enum FogModel { /// Today's linear 1.12 fog, byte-identical. From 9e06afa11a449eca13fbc7e40f9568dc8f253229 Mon Sep 17 00:00:00 2001 From: pkuzic Date: Fri, 25 Sep 2026 11:20:37 +0100 Subject: [PATCH 3/3] MONKEY (p0): reframe the Elwynn, Redridge, Hyjal and Ironforge baseline scenes Framed with the vista instrument: Elwynn above the canopy (the old eye stood inside a tree), Redridge from the known-good Lakeshire dock eye with a wider look, Hyjal above the terrain (the Light.dbc sphere centre z is underground), Ironforge over a floor face inside the city (the old eye was outside the WMO). Co-Authored-By: Claude Opus 5.5 --- crates/benilla-app/src/capture/scenarios.rs | 24 ++++++++++++--------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/crates/benilla-app/src/capture/scenarios.rs b/crates/benilla-app/src/capture/scenarios.rs index c3544d5a..f452f9af 100644 --- a/crates/benilla-app/src/capture/scenarios.rs +++ b/crates/benilla-app/src/capture/scenarios.rs @@ -1409,7 +1409,7 @@ pub(super) const ON_DEMAND: &[Scenario] = &[ // Redridge: Lake Everstill from above Lakeshire, a wider frame than `water-lake`. Scenario { name: "redridge-lake", map: Some(MAP_AZEROTH), - eye: [-9250.0, -2200.0, 110.0], look: [-9450.0, -2600.0, 55.0], minute: 720, ui: None, + eye: [-9350.0, -2340.0, 82.0], look: [-9500.0, -2650.0, 50.0], minute: 720, ui: None, }, // Duskwood: the road into Darkshire, the zone's short dark fog. Scenario { @@ -1443,18 +1443,22 @@ pub(super) const ON_DEMAND: &[Scenario] = &[ }, ]; -/// MONKEY (p0 baseline): the Elwynn programme view, east of Goldshire looking south-west. -pub(super) const GFX_ELWYNN_EYE: [f32; 3] = [-9380.0, -30.0, 80.0]; -pub(super) const GFX_ELWYNN_LOOK: [f32; 3] = [-9600.0, -200.0, 62.0]; -/// MONKEY (p0 baseline): Mount Hyjal, Light.dbc sphere 270's centre (world yards). -pub(super) const GFX_HYJAL_EYE: [f32; 3] = [4636.0, -4461.0, 900.0]; -pub(super) const GFX_HYJAL_LOOK: [f32; 3] = [4836.0, -4361.0, 870.0]; +/// MONKEY (p0 baseline): the Elwynn programme view, above the canopy east of Goldshire looking +/// south-west over the forest to the river and the hills (framed with the `vista` instrument). +pub(super) const GFX_ELWYNN_EYE: [f32; 3] = [-9400.0, -100.0, 122.0]; +pub(super) const GFX_ELWYNN_LOOK: [f32; 3] = [-9477.6, -160.6, 104.6]; +/// MONKEY (p0 baseline): Mount Hyjal, over Light.dbc sphere 270's centre (world yards; the +/// sphere's own z 873 is below the terrain), pitched a little up: its params-269 fog (end 278 yd, +/// orange) fills the frame today, which is the subject the skybox and fog lanes change. +pub(super) const GFX_HYJAL_EYE: [f32; 3] = [4636.0, -4461.0, 1152.0]; +pub(super) const GFX_HYJAL_LOOK: [f32; 3] = [4724.2, -4416.0, 1165.9]; /// MONKEY (p0 baseline): the Cathedral of Light nave, standing over the floor. pub(super) const GFX_CATHEDRAL_EYE: [f32; 3] = [-8530.0, 845.0, 112.0]; pub(super) const GFX_CATHEDRAL_LOOK: [f32; 3] = [-8500.0, 880.0, 110.0]; -/// MONKEY (p0 baseline): the Great Forge ring. -pub(super) const GFX_FORGE_EYE: [f32; 3] = [-4870.0, -1010.0, 512.0]; -pub(super) const GFX_FORGE_LOOK: [f32; 3] = [-4920.0, -960.0, 502.0]; +/// MONKEY (p0 baseline): Ironforge's interior by the Great Forge ring (a lit WMO interior; the +/// camera must stand over a floor face or the portal cull hides the city). +pub(super) const GFX_FORGE_EYE: [f32; 3] = [-4880.0, -1000.0, 506.0]; +pub(super) const GFX_FORGE_LOOK: [f32; 3] = [-4950.4, -929.6, 497.3]; /// The owner's reported vantage for the lava-glow report: `(-7048.8, -1000.6, 242.0)` facing /// 1.53 rad, Searing Gorge, map 0. The eye takes the standard [`VISTA_EYE_HEIGHT`]-ish lift off