From 7dff91a92353377428aa0b739bcbe7517dfe3947 Mon Sep 17 00:00:00 2001 From: pkuzic Date: Fri, 25 Sep 2026 02:52:47 +0100 Subject: [PATCH 1/4] MONKEY (ao): depth-only half-res SSAO pass before the water copy, cvar ambientOcclusion + Advanced Graphics row Co-Authored-By: Claude Opus 5.5 --- LIGHTING.md | 1 + crates/benilla-app/assets/ui/OptionsFrame.xml | 36 ++ crates/benilla-app/src/capture/scenarios.rs | 15 + crates/benilla-app/src/cvars.rs | 5 + crates/benilla-app/src/game_plugins.rs | 2 + crates/benilla-app/src/lib.rs | 2 + crates/benilla-app/src/shaders/ssao.wgsl | 174 +++++++ crates/benilla-app/src/ssao.rs | 484 ++++++++++++++++++ .../src/ui_script/options_tests.rs | 40 +- crates/benilla-app/src/video.rs | 6 + crates/benilla-world/src/liquid/mod.rs | 3 +- .../benilla-world/src/liquid/scene_depth.rs | 3 +- 12 files changed, 768 insertions(+), 3 deletions(-) create mode 100644 crates/benilla-app/src/shaders/ssao.wgsl create mode 100644 crates/benilla-app/src/ssao.rs diff --git a/LIGHTING.md b/LIGHTING.md index 2122d3df..6dd43bc3 100644 --- a/LIGHTING.md +++ b/LIGHTING.md @@ -24,6 +24,7 @@ behind each constant. | Moon shadows | at night the same shadow rig re-aims at the moon and casts a faint shadow; dims only the night sky term, never point lights | `moonShadowStrength` | | 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` | +| Ambient occlusion | soft contact shadows under props, in wall-floor corners and around feet; depth-only SSAO at half resolution (depth-reconstructed normals, 6/12 spiral taps, 4x4 depth-aware blur, bilateral upsample) multiplied into the opaque scene after the opaque pass and before the water copy, so water, particles and UI are untouched; fades out 35-80 yd, spares sky and bright pixels (`benilla-app/src/ssao.rs`, `benilla-app/src/shaders/ssao.wgsl`) | Advanced Graphics → Ambient Occlusion (Off/Low/High; default Off, High preset 2), cvar `ambientOcclusion`, env `WOW_AO=0\|1\|2`, `WOW_AO_DEBUG=1` shows the AO term alone | | 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 / diff --git a/crates/benilla-app/assets/ui/OptionsFrame.xml b/crates/benilla-app/assets/ui/OptionsFrame.xml index 71e19e82..4e660703 100644 --- a/crates/benilla-app/assets/ui/OptionsFrame.xml +++ b/crates/benilla-app/assets/ui/OptionsFrame.xml @@ -519,6 +519,8 @@ spellLights = "Spell Lights", nightDarkness = "Night Darkness", interiorDarkness = "Interior Darkness", + -- MONKEY (ao): localised contact-shadow row. + ambientOcclusion = "Ambient Occlusion", yards = "%d yd", tips = { LIGHTING_QUALITY = @@ -611,6 +613,13 @@ "Scales interior fixture light and room ambient, including the light from " .. "lamps and candles. Lower values make both dimmer.\n\n" .. "1.0 leaves these inputs unchanged. Free at any setting.", + -- MONKEY (ao): what the contact shadows touch and what they spare. + AMBIENT_OCCLUSION = + "Soft contact shadows where surfaces meet: under props and furniture, in the corners " + .. "between walls and floors, and around characters' feet. Low uses fewer samples; " + .. "High is smoother and reaches a little further.\n\n" + .. "Fades out with distance and spares the sky, water, lit windows and flames. " + .. "Off leaves the image unchanged.", }, }, ruRU = { @@ -643,6 +652,8 @@ spellLights = "Свет от заклинаний", nightDarkness = "Темнота ночи", interiorDarkness = "Темнота помещений", + -- MONKEY (ao): Russian contact-shadow row. + ambientOcclusion = "Затенение окружения", yards = "%d ярд.", tips = { LIGHTING_QUALITY = @@ -743,6 +754,13 @@ "Масштабирует свет светильников и фоновое освещение помещений, включая " .. "свет ламп и свечей. Меньшие значения ослабляют и то и другое.\n\n" .. "1.0 оставляет эти составляющие без изменений. Ничего не стоит при любом значении.", + -- MONKEY (ao): Russian contact-shadow explanation. + AMBIENT_OCCLUSION = + "Мягкие контактные тени там, где поверхности соприкасаются: под предметами и мебелью, " + .. "в углах между стенами и полом, у ног персонажей. «Низкое» использует меньше выборок; " + .. "«Высокое» — более плавное и захватывает чуть больше.\n\n" + .. "Ослабевает с расстоянием и не затрагивает небо, воду, освещённые окна и пламя. " + .. "«Выкл» оставляет изображение без изменений.", }, }, } @@ -801,6 +819,8 @@ "RowInteriorLight", "RowInteriorShadows", "RowExteriorShadows", "RowTorchSoft", "RowFireLight", "RowFireFlicker", "RowSpellLights", "RowLavaGlow", "RowNightDarkness", "RowInteriorDarkness", + -- MONKEY (ao): appended so the other rows keep their indices. + "RowAmbientOcclusion", }, -- Player Guild Names is a child of Player Names, as in 1.12 (l.702-708). Nameplates = { @@ -2827,6 +2847,22 @@ OptionsSliderRow_Setup(self, 0.2, 1.5, 0.05, "darkness") + + + + + + + + OptionsRow_OnLoad(self, "ambientOcclusion", BENILLA_ADVGFX.ambientOcclusion, + "BENILLA_TOOLTIP_AMBIENT_OCCLUSION") + OptionsDropdownRow_Setup(self, { + { text = BENILLA_ADVGFX.fogOff, value = "0" }, + { text = BENILLA_ADVGFX.qLow, value = "1" }, + { text = BENILLA_ADVGFX.qHigh, value = "2" }, + }) + +