MONKEY (fog): fogModel cvar, Advanced Graphics row, fog-duskwood scenarios, docs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
pkuzic
2026-09-25 09:21:02 +01:00
co-authored by Claude Opus 5.5
parent 06a2e3a504
commit 42b4783660
5 changed files with 82 additions and 7 deletions
+2 -1
View File
@@ -25,6 +25,7 @@ behind each constant.
| Ground-effect spells | Flamestrike, Rain of Fire, Consecration, Flare and fire traps light the ground for their duration; frost and nature areas stay dark | `spellLightGain` |
| Volumetric fog | near-field haze that converges on the zone fog colour (clear within 10 yd, full by 150 yd; mistier at dawn and in bad weather, faint indoors) and sun/moon light shafts through gaps, sampled from the shadow map; own fullscreen pass after the main pass (`benilla-app/src/volumetric_fog.rs`) | Advanced Graphics → Volumetric Fog (Off/Low/High), cvar `volumetricFog`, env `WOW_VOLFOG=0\|1\|2` |
| 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` |
| Modern fog | MONKEY (fog): distance fog in the style of the modern client. Radial distance; exponential from the zone's own start, fitted so 60 % survives mid-span and closed over the last stretch so the fog still ends where the zone authored it; a sun-fog lobe (the fog leans to the sun colour around the sun, fading out through dusk); the far fog shifts toward the sky's 1.8° ring so fogged land, the WDL hull and the sky dome's horizon meet in one colour; volumetric haze takes the same colour and no longer hazes sky pixels. The fog end stays the zone's up to farclip 777 and grows with farclip beyond it. Optional per-`LightParams` fields (height fog, sun/end fog, curve) from our `LightFogBand.dbc` (absent = derived from the 1.12 bands). Interior WMO fog stays classic | Advanced Graphics → Modern Fog, cvar `fogModel` 0 Classic (default, byte-identical) / 1 Modern (Graphics preset High = 1), env `WOW_FOGMODEL=0\|1`; `fog_hook.wgsl`, `benilla-world/src/lighting/fog_model.rs`, `benilla-formats/src/light/fog_band.rs` |
| 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 /
@@ -68,7 +69,7 @@ is its own module, documented in `WATER.md`.
| `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 |
| `fog_d` | fog_model (0 classic; Modern = the scene fog end, yd ≥ 1) | sun_fog_angle (cos) | sun dir octahedral x | y |
| `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 |
@@ -521,6 +521,8 @@
interiorDarkness = "Interior Darkness",
-- MONKEY (p0 skyDither)
skyDither = "Sky Dithering",
-- MONKEY (fog)
fogModel = "Modern Fog",
yards = "%d yd",
tips = {
LIGHTING_QUALITY =
@@ -617,6 +619,13 @@
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 (fog)
FOG_MODEL =
"Softer distance fog in the style of the modern client: it thickens gradually "
.. "instead of in a straight ramp, glows toward the sun by day and shifts to the "
.. "sky's colour in the distance, so the land melts into the horizon. Each zone "
.. "keeps its own fog distance; above the original view-distance limit the fog "
.. "recedes with it.\n\nOff is the original client's fog. Practically free.",
},
},
ruRU = {
@@ -651,6 +660,8 @@
interiorDarkness = "Темнота помещений",
-- MONKEY (p0 skyDither)
skyDither = "Дизеринг неба",
-- MONKEY (fog)
fogModel = "Современный туман",
yards = "%d ярд.",
tips = {
LIGHTING_QUALITY =
@@ -756,6 +767,13 @@
"Добавляет едва заметный шум в итоговое изображение, чтобы плавные переходы цвета "
.. "неба и тумана не распадались на полосы. Выключено — вид оригинального клиента. "
.. "Почти ничего не стоит.",
-- MONKEY (fog)
FOG_MODEL =
"Более мягкий туман в духе современного клиента: он сгущается постепенно, а не "
.. "по прямой, днём светлеет в сторону солнца, а вдали принимает цвет неба, "
.. "так что земля растворяется в горизонте. Дальность тумана в каждой зоне "
.. "прежняя; за пределом дальности обзора оригинала туман отступает вместе с ней."
.. "\n\nВыключено — туман оригинального клиента. Почти ничего не стоит.",
},
},
}
@@ -816,6 +834,8 @@
"RowNightDarkness", "RowInteriorDarkness",
-- MONKEY (p0 skyDither)
"RowSkyDither",
-- MONKEY (fog)
"RowFogModel",
},
-- Player Guild Names is a child of Player Names, as in 1.12 (l.702-708).
Nameplates = {
@@ -2854,6 +2874,18 @@
"BENILLA_TOOLTIP_SKY_DITHER")
</OnLoad></Scripts>
</Frame>
<!-- MONKEY (fog): the distance-fog model. -->
<Frame name="$parentRowFogModel" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowSkyDither" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowSkyDither" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "fogModel",
BENILLA_ADVGFX.fogModel,
"BENILLA_TOOLTIP_FOG_MODEL")
</OnLoad></Scripts>
</Frame>
</Frames>
<!-- The poll (see AdvGfx_OnUpdate): this is the one page whose
settings move from outside it — the Lighting Quality row
@@ -1379,6 +1379,24 @@ pub(super) const ON_DEMAND: &[Scenario] = &[
minute: 0,
ui: None,
},
// MONKEY (fog): Duskwood's short zone fog (Light 15, LightParams 14) from above the canopy west
// of Darkshire toward the town, for the Classic/Modern fog A/B (`WOW_FOGMODEL=0|1`).
Scenario {
name: "fog-duskwood-noon",
map: Some(MAP_AZEROTH),
eye: [-10700.0, -900.0, 160.0],
look: [-10560.0, -1180.0, 60.0],
minute: 720,
ui: None,
},
Scenario {
name: "fog-duskwood-dusk",
map: Some(MAP_AZEROTH),
eye: [-10700.0, -900.0, 160.0],
look: [-10560.0, -1180.0, 60.0],
minute: 1170,
ui: None,
},
];
/// The owner's reported vantage for the lava-glow report: `(-7048.8, -1000.6, 242.0)` facing
+10
View File
@@ -928,6 +928,14 @@ pub(crate) const REGISTERED: &[Registered] = &[
"0",
"benilla's own: faint screen dither against sky and fog banding, 0 Off / 1 On",
),
// MONKEY (fog): the distance-fog model. 0 = the 1.12 linear fog (byte-identical), 1 = Modern
// (exponential, sun/horizon colour, end-fog shift, fog end decoupled from farclip past 777).
// Default 0; the Graphics preset's High sets 1.
ours(
"fogModel",
"0",
"benilla's own: distance fog, 0 Classic (1.12 linear) / 1 Modern (soft, sun-coloured horizon)",
),
ours(
"waterQuality",
"1",
@@ -3712,6 +3720,8 @@ mod tests {
// MONKEY (p0 graphics programme)
|app| {
app.init_resource::<benilla_world::ffx_glow::SkyDither>();
// MONKEY (fog)
app.init_resource::<benilla_world::lighting::FogModelSetting>();
app.add_observer(crate::monkey_gfx::on_cvar);
},
|app| {
+20 -6
View File
@@ -5,17 +5,29 @@
//! | cvar | values | default | Graphics preset High | resource |
//! |---|---|---|---|---|
//! | `skyDither` | 0 Off / 1 On | 0 | 1 | `benilla_world::ffx_glow::SkyDither` |
//! | `fogModel` | 0 Classic / 1 Modern | 0 | 1 | `benilla_world::lighting::FogModelSetting` |
use bevy::prelude::*;
use benilla_world::ffx_glow::SkyDither;
use benilla_world::lighting::FogModelSetting;
/// The programme's cvar observer (registered by [`MonkeyGfxPlugin`]).
pub(crate) fn on_cvar(ev: On<crate::cvars::CvarChanged>, mut dither: ResMut<SkyDither>) {
if ev.key().as_str() == "skydither" {
let want = ev.num() >= 0.5;
if dither.0 != want {
dither.0 = want;
pub(crate) fn on_cvar(
ev: On<crate::cvars::CvarChanged>,
mut dither: ResMut<SkyDither>,
// MONKEY (fog)
mut fog_model: ResMut<FogModelSetting>,
) {
match ev.key().as_str() {
"skydither" => {
let want = ev.num() >= 0.5;
if dither.0 != want {
dither.0 = want;
}
}
// MONKEY (fog): `WOW_FOGMODEL` still wins for the session (captures).
"fogmodel" => fog_model.set_from_cvar(ev.num()),
_ => {}
}
}
@@ -25,6 +37,8 @@ pub(crate) struct MonkeyGfxPlugin;
impl Plugin for MonkeyGfxPlugin {
fn build(&self, app: &mut App) {
app.init_resource::<SkyDither>().add_observer(on_cvar);
app.init_resource::<SkyDither>()
.init_resource::<FogModelSetting>()
.add_observer(on_cvar);
}
}