diff --git a/LIGHTING.md b/LIGHTING.md index f09f04d2..c7de7b00 100644 --- a/LIGHTING.md +++ b/LIGHTING.md @@ -29,6 +29,7 @@ behind each constant. | 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` | +| Foliage wind | one weather-fed gust/veer field drives grass and classified tree/bush foliage; grass also parts around the player and nearby units | Advanced Graphics → Foliage Wind, cvar `foliageWind` 0 Off / 1 Grass / 2 Grass + Trees (High = 2), capture override `WOW_FOLIAGE_WIND`; field and benders in `benilla-world/src/wind/` | | Night and interior level | global dimming of the night sky term and of interior ambient | `nightGain`, `interiorGain`, `interiorBakeFloor` | Players reach all of it from **Options -> Advanced Graphics** (a Lighting Quality preset Off / Low / Medium / High plus the individual rows; Off is the original client look). The dev build has a panel for all of it: **Ctrl+Shift+D → Lighting & shadows**, with Dim / Default / @@ -61,6 +62,9 @@ is its own module, documented in `WATER.md`. - **Census**: `cargo test -p benilla-world --lib lighting::daylight::census -- --ignored --nocapture` (`WOW_CENSUS_WMO`, `WOW_CENSUS_PLACE=map,tx,ty,uid`) prints, per interior room of a city WMO, whether a daylight fixture, a bleed fixture or neither reaches it, and the sky-room count. +- **Wind**: `wind/mod.rs` resolves the WXL-derived shared field and nearest-unit benders; + `clutter.rs` authors blade weights/phases; `static_gx` classifies and marks alpha-tested leaf + batches. `wind_hook.wgsl` owns the displacement shared by clutter, retained trees and fade twins. - **Tools**: `benilla-extract wmolights [--verts ]`, `wmolamps`, `m2firescan` print the inputs the system works from (groups, batch classes, portals, claims, flame emitters). @@ -89,6 +93,8 @@ is its own module, documented in `WATER.md`. (`benilla-world/src/lighting/monkey_frame.rs`); `global_light::pack_monkey_frame` packs it after the point table and fills `time_of_day` / `night` itself. All zero = no visual change. - World lights use upstream's `WorldPointLight`, never Bevy's `PointLight`. +- Foliage wind is vertex-only. Tree and leaf shadow meshes stay static; the small mismatch is the + accepted first-stage cost/complexity tradeoff. - WGSL only fails at pipeline creation, so a shader edit is verified by running a world scene, not by `cargo check`. - Exterior point lights are selected per draw unit (12 slots, ranked against the chunk's box); the diff --git a/THIRD-PARTY.md b/THIRD-PARTY.md index 91aa78fd..5e7d9a14 100644 --- a/THIRD-PARTY.md +++ b/THIRD-PARTY.md @@ -37,6 +37,10 @@ where they stand. Do not remove either. | `crates/benilla-world/src/shaders/cloud.wgsl` | `wxl-retail-clouds` | `Clouds.cpp` | The 3-tap march toward the sun (self-shadow, ambient floor) and the one-tap silver lining | | `crates/benilla-world/src/clouds/layer.rs` (`update_cloud_fx`) | `wxl-retail-clouds` | `Clouds.cpp` | March direction = the sun projected on the sheet, strength folded by its flatness (noon clouds evenly lit) | -Planned (not yet in the tree): breaker index from `sea/Shore.hpp`, `shaders/Wave.hlsli`; grass wind from `wxl-experimental-wind` -(`field/Wind.*`, `grass/GrassWind.*`). +| `crates/benilla-world/src/wind/mod.rs` | `wxl-experimental-wind` | `field/Wind.hpp`, `field/Wind.cpp` | Stateless three-sine gust and veer field, default profile, and weather gain (ported) | +| `crates/benilla-assets/src/shaders/wind_hook.wgsl` | `wxl-experimental-wind` | `grass/GrassWind.hpp`, `grass/GrassWind.cpp` | Two-wave grass sway, gust response, lean, blade phase/variance, distance fade and radial parting (ported; extended to eight benders) | +| `crates/benilla-assets/src/shaders/wow_model.wgsl` (MONKEY wind hook) | `wxl-experimental-wind` | `grass/GrassWind.cpp` | Grass vertex displacement call seam (technique) | +| `crates/benilla-world/src/clutter.rs` (MONKEY wind attributes) | `wxl-experimental-wind` | `grass/GrassWind.cpp` | Per-blade bend weight and per-tuft phase inputs (technique; height replaces WXL's unverified texture-V weight) | + +Planned (not yet in the tree): breaker index from `sea/Shore.hpp`, `shaders/Wave.hlsli`. The lane that ports one adds its row here. diff --git a/crates/benilla-app/assets/ui/OptionsFrame.xml b/crates/benilla-app/assets/ui/OptionsFrame.xml index fc95db89..e515d034 100644 --- a/crates/benilla-app/assets/ui/OptionsFrame.xml +++ b/crates/benilla-app/assets/ui/OptionsFrame.xml @@ -528,12 +528,16 @@ interiorDarkness = "Interior Darkness", -- MONKEY (p0 skyDither) skyDither = "Sky Dithering", + -- MONKEY (wind) + foliageWind = "Foliage Wind", + windGrass = "Grass", + windTrees = "Grass + Trees", yards = "%d yd", tips = { LIGHTING_QUALITY = "Sets character, world, indoor torch and outdoor torch shadows; dynamic " .. "interior lighting; moon shadows; volumetric fog; water quality; lava glow; fire and spell brightness; fire flicker; " - .. "and night and interior darkness. Low, Medium and High also set shadow " + .. "foliage wind; and night and interior darkness. Low, Medium and High also set shadow " .. "resolution; Medium and High also set resident and moving torch shadow counts.\n\n" .. "Off restores the original client's look: Classic water, no volumetric fog, lava glow or synthesised fire lights, " .. "night gain 1.0 and interior gain 1.0. All other settings, including " @@ -644,6 +648,11 @@ SKY_DITHER = "Adds a faint noise to the final image so smooth sky and fog gradients do not " .. "break into visible bands. Off is the original client's look. Practically free.", + -- MONKEY (wind) + FOLIAGE_WIND = + "Grass bends in two travelling wind waves and parts around nearby characters. " + .. "Grass + Trees also gives classified tree and bush foliage a gentle sway.\n\n" + .. "Off makes no vertex displacement and restores the unchanged image. Tree shadows stay static.", }, }, ruRU = { @@ -685,6 +694,10 @@ interiorDarkness = "Темнота помещений", -- MONKEY (p0 skyDither) skyDither = "Дизеринг неба", + -- MONKEY (wind) + foliageWind = "Ветер листвы", + windGrass = "Трава", + windTrees = "Трава + деревья", yards = "%d ярд.", tips = { LIGHTING_QUALITY = @@ -811,6 +824,11 @@ "Добавляет едва заметный шум в итоговое изображение, чтобы плавные переходы цвета " .. "неба и тумана не распадались на полосы. Выключено — вид оригинального клиента. " .. "Почти ничего не стоит.", + -- MONKEY (wind) + FOLIAGE_WIND = + "Трава гнётся двумя бегущими волнами ветра и расступается вокруг персонажей. " + .. "Трава + деревья также добавляет мягкое качание листвы деревьев и кустов.\n\n" + .. "Выключено не смещает вершины и восстанавливает исходный вид. Тени деревьев остаются неподвижными.", }, }, } @@ -877,6 +895,8 @@ "RowNightDarkness", "RowInteriorDarkness", -- MONKEY (p0 skyDither) "RowSkyDither", + -- MONKEY (wind): appended for conflict-free lane merges. + "RowFoliageWind", }, -- Player Guild Names is a child of Player Names, as in 1.12 (l.702-708). Nameplates = { @@ -2985,6 +3005,23 @@ "BENILLA_TOOLTIP_SKY_DITHER") + + + + + + + + OptionsRow_OnLoad(self, "foliageWind", + BENILLA_ADVGFX.foliageWind, + "BENILLA_TOOLTIP_FOLIAGE_WIND") + OptionsDropdownRow_Setup(self, { + { text = BENILLA_ADVGFX.qOff, value = "0" }, + { text = BENILLA_ADVGFX.windGrass, value = "1" }, + { text = BENILLA_ADVGFX.windTrees, value = "2" }, + }) + +