WIP: feat(vk): ray-traced ambient occlusion, sun shadows, global illumination and reflections #727
No reviewers
Labels
No labels
area/accessibility
area/audio
area/input
area/install
area/menu
area/renderer
area/saves
area/upscaling
beanstalk: approved @ 1697603
beanstalk: approved @ 2c5a62e
beanstalk: approved @ 4fd82b7
beanstalk: approved @ 64d6d09
beanstalk: approved @ 6f91fae
beanstalk: approved @ 70a78f9
beanstalk: approved @ 8d361dc
beanstalk: approved @ 9d8356e
beanstalk: approved @ abf2227
beanstalk: approved @ d82f202
beanstalk: approved @ e5f1e40
beanstalk: approved @ ee8ab5f
ci: approved
good first issue
gpu/amd
gpu/igpu
gpu/intel
gpu/nvidia
help wanted
kind
bug
kind
chore
kind
docs
kind
feature
kind
performance
kind
question
needs measurements
platform/linux
platform/macos
platform/steam-deck
platform/windows
preview
priority
critical
priority
high
priority
low
regression
status
blocked
status
confirmed
status
duplicate
status
invalid
status
needs-info
status
wontfix
testing wanted
ci: approved
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Longshot!727
Loading…
Reference in a new issue
No description provided.
Delete branch "winterelfeas/Longshot:feat/ray-tracing"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Type: feat · Risk: medium · Tested on: Windows 11, RTX 5090 · Needs: AMD (RDNA 2+), Intel Arc, an older NVIDIA RTX card, Linux
Why
The game lights its world with tricks made for a handheld: a screen-space ambient occlusion that only sees what is on screen, sun shadows from low-resolution cascades that fade out in the distance, light baked once per object that never bounces off what is near it, and reflections that show a fixed environment picture instead of the scene. On a PC with a ray tracing GPU, all four can be traced against the real scene instead. This PR adds that, as four options in the Graphics tab, all off by default, so nothing changes for anyone who doesn't turn them on.
No issue asks for it (searched the tracker for ray tracing, reflections, AO and shadows: #601 and #603 are about the game's own character shadows, which this leaves as they are).
What changed
Ray tracing over the game's own frame. The renderer keeps the scene's geometry as Vulkan acceleration structures, built from the game's own vertex and index buffers, and each effect goes in where the game computes the same thing: AO and sun shadows into the game's screen-space light mask, the bounce light and the reflections inside the game's own lighting programs, by a SPIR-V patch of their fragment modules when they are made. The game's renderer is otherwise left as it is; with every row off nothing here runs (
rt::mode()is one load).docs/ray-tracing.mddescribes each part, what it found in the game's frame, the requirements, the cost and the switches.gpu/vk/vk_rt.h. The parts are told of each draw before and after it is recorded (vk_draw.cpp), of each dispatch, and of each present (vk_replay.cpp).vk_rt_scene.cpp,vk_rt_omm.h,shaders/rt_scene_*): bottom levels from the depth pre-pass's draws, skinned characters (re-skinned in a compute pass), terrain patches, and the mesh-shader foliage (in the default native mode by running the compute fallback for capture only, every 4th frame per draw;RX_VK_RT_NATIVE_MESH=0turns that off), and the cascade draws placed by their own vertex stage (the Lost Woods' falling leaves) captured by transform feedback where the device hasVK_EXT_transform_feedback(RX_VK_RT_XFB=0turns that off), and static models the camera has drawn kept as casters while out of view, so interiors keep their roofs (RX_VK_RT_REMEMBER=0turns that off); a top level a frame with instance masks by kind (opaque, cutout, skinned, foliage, out-of-view casters, cascade-only blockers). Alpha-tested cards are cut by opacity micromaps from the game's own alpha where the device hasVK_EXT_opacity_micromap; hit normals by position fetch. The game's pools become build inputs only with ray tracing on (pool_usage()invk_memory.cpp). Device extensions and features are asked for only when a row orRX_VK_RTis on (vk_main.cpp).vk_rt_mask.cpp,shaders/rt_ao_*): after the game's combine writes its light mask (found by what it does, since it is another program in each kind of place), a trace, a temporal pass and a filter write the mask's AO and sun channels. The traced sun shadow takes the place of the game's (RX_VK_RT_SUN_KEEP=1adds it to the game's instead, for debugging), and a gate keeps the game's own where the rays would take away sunlight the game shows. Every caster's sun shadow is traced, in both mesh modes: the world, the characters and the plants; past 60 m the traced shadow hands over to the game's (fully by 120 m). The gate is a safety net for a broken structure only.vk_rt_gi.cpp,rt_gi_spirv.h,shaders/rt_gi_*): one diffuse bounce at half resolution, one ray a pixel, from the previous frame's lit colour, accumulated and filtered, added in the lit programs' ambient term.vk_rt_refl.cpp,rt_refl_spirv.h,shaders/rt_refl_*): the lit programs' specular environment lookup replaced by a traced reflection along the same vector, on water first, and on smooth metal and glass by their roughness; a march against the previous frame's colour, then the structure for what is off screen.vk_progcache.cpp,vk_shader.h): the GI and reflection patches are applied when a module is made, so the cache's records are the game's own, unchanged, and its stamp does not move.par_threads()turns parallel replay off while ray tracing is on: its parts record in the stream's order (the frame's captures, the structure's builds), and the log says so.vk_menu.cpp,vk_menu.h): a Ray tracing section at the end of the Graphics tab, four Off/On rows, read once at the start (restart rows, outside the quality presets).RX_VK_RT=<bits>goes over them.tests/test_menu_sections.pyand the README's table know the rows;tests/test_recorder_sync.pyknows the structure builds (with a control case); the program cache, import and fallback pipeline fixtures stand in for the new hooks;gpu/vk/tests/rt_*_spirv_test.cpppatch modules forspirv-val.Measurements
Verdict: pending. The in-game A/B (main against this PR with the rows off and with all four on, two interleaved runs each after a warm-up) will be run once on the PC below when the four parts are done; its numbers, log lines and screenshots will follow in a comment and here. Until then this PR stays WIP.
Hardware: Windows 11 Home (26200), RTX 5090 32 GB, driver 621.01, Ryzen 7 9800X3D, 64 GB
Scene: Kokiri Forest by day, child Link standing at the save's spot; headless (
longshot_ctl.py launch, offscreen presents at 1920x1080), sound off, the test profile's settings, below normal priorityMethod: the log's
vk: N presents, X fpslines, 90 s after 30 s standing, each run's median; two interleaved runs per side after a warm-up run (RX_VK_LOAD=create,RX_VK_PRECOMPILE=0); the median of the runsBaseline: main @
e090cc4, this PR's base before its rebase onto5274fb7, and the PR's renderer at 49260a6 (the same ray tracing code as the rebased branch; main's 4 new commits change none of it): measured before the rebase.How to reproduce:
python -I scripts/longshot_ctl.py launch <game> --profile test --save <a save in Kokiri Forest> --env RX_VK_RT=0(then=15), and read the fps linese090cc4GPU time of each part, from
docs/ray-tracing.md(RTX 5090, 4K scene with DLAA,RX_VK_PASS_TIMING=1), measured on the parts' branches before they were joined here:RX_VK_MESH_SHADERS=compute)RX_VK_MESH_SHADERS=computeitself (for leaf and grass shadows)Quality, on those branches: the structure agrees with the game's depth on 90-99% of the screen across eight areas; with the sun gate the rays keep 98-100% of the game's sunlit screen in Kokiri Forest and 92-96% in the gorge; GI adds 11% to Kokiri Forest's picture and 17-30% inside the Deku Tree, never darkening; at night (22:00) the traced shadows follow the moon's cascades and GI adds 12-22% with nothing darker; reflections reach ten water surfaces, the armour and the Market's shop windows.
Flags and settings
Four new menu rows (ini keys from their names) and the
RX_VK_RTswitch family; all off as shipped.RX_VK_MESH_SHADERS=computeRX_VK_RT=<bits>RX_VK_RT_*:RX_VK_RT_AO_FALLOFF,RX_VK_RT_AO_FAR,RX_VK_RT_AO_MARCH_RADIUS,RX_VK_RT_AO_MARCH_WEIGHT,RX_VK_RT_AO_MASK,RX_VK_RT_AO_POWER,RX_VK_RT_AO_QUARTER,RX_VK_RT_AO_RADIUS,RX_VK_RT_AO_RAYS,RX_VK_RT_AO_STEPS,RX_VK_RT_AO_STRENGTH,RX_VK_RT_AO_THICKNESS,RX_VK_RT_ARENA_MB,RX_VK_RT_BACK,RX_VK_RT_BIAS,RX_VK_RT_BLAS_MB,RX_VK_RT_BUILD_TRIS,RX_VK_RT_CASCADES,RX_VK_RT_CASCADE_MESH,RX_VK_RT_CHANNELS,RX_VK_RT_CLAMP,RX_VK_RT_CONTACT,RX_VK_RT_CONTACT_STEPS,RX_VK_RT_CONTACT_THICKNESS,RX_VK_RT_CUT,RX_VK_RT_CUTOUT,RX_VK_RT_CUTOUT_COVER,RX_VK_RT_CUT_LEVEL,RX_VK_RT_DEBUG,RX_VK_RT_DEBUG_FILE,RX_VK_RT_DEBUG_GAIN,RX_VK_RT_DEBUG_MASK,RX_VK_RT_DEBUG_POINT,RX_VK_RT_DEBUG_VIEW,RX_VK_RT_FETCH,RX_VK_RT_FILTER,RX_VK_RT_FORCE,RX_VK_RT_GI_ADD,RX_VK_RT_GI_AREA,RX_VK_RT_GI_CACHE,RX_VK_RT_GI_CLAMP,RX_VK_RT_GI_CTL,RX_VK_RT_GI_FALLBACK,RX_VK_RT_GI_FILTER,RX_VK_RT_GI_FORGET,RX_VK_RT_GI_HISTORY,RX_VK_RT_GI_LENGTH,RX_VK_RT_GI_NEAR,RX_VK_RT_GI_OCCLUDE,RX_VK_RT_GI_PROBE,RX_VK_RT_GI_RAYS,RX_VK_RT_GI_REGION,RX_VK_RT_GI_REPLACE,RX_VK_RT_GI_STEPS,RX_VK_RT_GI_STRENGTH,RX_VK_RT_GI_THICKNESS,RX_VK_RT_GI_TRACE,RX_VK_RT_GI_WAY,RX_VK_RT_GROUND_MATERIAL,RX_VK_RT_HISTORY,RX_VK_RT_HISTORY_TOL,RX_VK_RT_HOLES,RX_VK_RT_HYBRID,RX_VK_RT_KEEP,RX_VK_RT_LEAF_MIN,RX_VK_RT_LEAF_MIN_FAR,RX_VK_RT_LIFT,RX_VK_RT_MARCH,RX_VK_RT_MESH,RX_VK_RT_MESH_EVERY,RX_VK_RT_MESH_MB,RX_VK_RT_MESH_TEST,RX_VK_RT_OMM,RX_VK_RT_OMM_ALPHA,RX_VK_RT_OMM_LEVEL,RX_VK_RT_PALETTE_COPY,RX_VK_RT_PROBE,RX_VK_RT_REFL_AMBIENT,RX_VK_RT_REFL_CLAMP,RX_VK_RT_REFL_CONE,RX_VK_RT_REFL_CTL,RX_VK_RT_REFL_DITHER,RX_VK_RT_REFL_LENGTH,RX_VK_RT_REFL_MARCH_ALL,RX_VK_RT_REFL_MASK,RX_VK_RT_REFL_METAL_RAYS,RX_VK_RT_REFL_METAL_ROUGH,RX_VK_RT_REFL_PROBE,RX_VK_RT_REFL_RAYS,RX_VK_RT_REFL_RES,RX_VK_RT_REFL_ROUGH,RX_VK_RT_REFL_STEPS,RX_VK_RT_REFL_STRENGTH,RX_VK_RT_REFL_STRIDE,RX_VK_RT_REFL_SUN,RX_VK_RT_REFL_THICKNESS,RX_VK_RT_SCENE_EARLY,RX_VK_RT_SCENE_LOG,RX_VK_RT_SCENE_SPV,RX_VK_RT_SCRATCH_MB,RX_VK_RT_SHADOW_BIAS,RX_VK_RT_SHADOW_DIST,RX_VK_RT_SHADOW_MASK,RX_VK_RT_SHADOW_RAYS,RX_VK_RT_SHADOW_SLOPE,RX_VK_RT_SUN_CUTOUT,RX_VK_RT_SUN_GATE,RX_VK_RT_SUN_GATE_FAR,RX_VK_RT_SUN_LOG,RX_VK_RT_SUN_SOFT,RX_VK_RT_TERRAIN_MASK,RX_VK_RT_TUNEdocs/ray-tracing.md; the head of each part's.cppfile)Documented in
docs/ray-tracing.md, indocs/development.md("The GPU") and in the README's option table.Screenshots
The same spot and frame, the feature off (left) and on (right), 4K on an RTX 5090, one part on at a time, from the parts' development builds (this PR's code; the sun shadow ones also carry the static shadow map's casters, still in testing). AO and reflections follow.
Sun shadows (
RX_VK_RT=2against 0): each clover leaf, grass blade and fence slat casts its own cut shadow where the game's maps give soft patches.GI (
RX_VK_RT=4against 0): light bounced from lamps, doorways and lava into what the game leaves near black.Testing
Tested:
python -I -B tests/run_all.pyon Windows, on this branch rebased onto mainaa95d35(after v3.0.0-rc.4) (llvm-mingw and the Vulkan SDK on PATH): 540 passed, 18 failed, 35 skipped. The same 18 fail on mainaa95d35on this PC (540 passed, 18 failed): test_appimage_player_build, test_cpm_discovery, test_cpp_preflight, test_crash_dialog, test_env_on, test_lift_cleanup_error, test_linux_preflight, test_make_game_cache, test_make_game_prepare, test_missing_nup, test_oot_state_tap, test_readback_late, test_tested_configurations, test_vk_pgo, test_vram_budget_row, test_walk_key, test_fpx_sticky, test_spawn_emit (missing tools here, Linux-only paths and CRLF output). test_dev_packs and test_finish_output failed once each under load on both sides and pass alone.make_game.py, before the rebase onto5274fb7) on Windows 11, RTX 5090, 621.01: Kokiri Forest with the rows off and with all four on loads and plays, no device lost; the A/B comes at the end (Measurements).scripts/check_guide_screenshots.py --review-sources:settings-graphics.pngnow also namesvk_menu.cppandvk_menu.h(main already names four other files for it). The new section is at the end of the Graphics tab, below Anisotropic filtering, far below what the image shows, so the image still matches; the review record is left for the documentation maintainer with main's four.Not tested:
VK_EXT_opacity_micromap(every part has a path without micromaps; none of them ran).Must be tested:
vk: rt:lines saying the scene is kept as acceleration structures (Test Farm: @Beanstalk ray tracing rows on, Kokiri Forest and Lake Hylia, RDNA 2 or newer)vk: rt:lines and the picture)Risks
What could break: with the rows on: a device lost or a hang on a driver this was not run on; wrong shading where the patched lighting programs meet a program the patch did not expect (it only patches programs it recognises, and leaves the rest as they are); memory (about 365 MB of images for AO and sun shadows at 4K, plus the structures). With the rows off: nothing should change; the hooks are behind
rt::on(), one load. Parallel replay is off while ray tracing is on, which costs CPU time on PCs that use it.Turning it off: the four rows (off by default), or
RX_VK_RT=0for a run.Compatibility: saves unchanged.
longshot_options.inigains four keys, written only when the menu saves. The shader and program caches are unchanged (the patch is applied when a module is made, after the cache); with GI or reflections on, the driver's pipeline cache builds the lit programs again on the first run. The vk ABI (MKWVK_API_VERSION) is unchanged. The builder's tools are unchanged.Checklist
Everyone
type(scope): description) of the status line's type.main.python -I -B tests/run_all.pypasses (any failure that also fails onmainis named).third_party/untouched (a new folder with aPROVENANCE.mdinstead).When it applies
Assisted-by:/Co-Authored-By:trailers.docs/tested/for each new measured run (format indocs/tested-configurations.md). (pending: with the measurements at the end)tests/that reads changed source updated in this PR, not weakened.🤖 Generated with Claude Code
New commit
1ffa9e4: the traced sun shadow is now added to the game's instead of replacing it (RX_VK_RT_SUN_KEEP=1, the default;=0is the previous behaviour).Why: the rays alone miss casters the game's shadow maps have. With native mesh shaders the plants can't be captured into the acceleration structure, so 15 % of the Kokiri spawn's picture was game shadow the rays left lit (5.8 % with
RX_VK_MESH_SHADERS=compute). The static map's channel now takes the darker of the game's value and the traced one under the sun gate; the cascades' channel stays the game's.Measured on the same frames (4K dumps, RTX 5090), share of the picture, lost shadow / lost sun, before -> after: native Kokiri 1.7 -> 0 % / 1.9 %; compute Kokiri 5.8 -> 0 % / 7.3 -> 7.7 %; compute gorge exit 1.1 -> 0 % / 1.8 -> 2.1 %; native gorge 0 % / 0.9 % and Lake Hylia 0 % / 8.9 % unchanged (the far cliffs past the cascades' reach: being worked on). Also checked:
RX_VK_RT_OMM=0runs the plain (no micromap) ray-query shader with no errors.Checks after the commit:
tests/run_all.py540 passed, 18 failed, the same 18 as main on this PC.docs/ray-tracing.mdupdated.New commit
801b951: the traced sun shadow takes the place of the game's by default again. Adding it on top of the game's (RX_VK_RT_SUN_KEEP=1) is now only a debug switch, to see what the rays miss.The goal is ray-traced sun shadows for every caster. What's missing for that in the default (native) mesh mode is the plants: their geometry comes from mesh shaders and isn't captured into the acceleration structure yet, so their shadows still come from the game's cascades (with
RX_VK_MESH_SHADERS=computethey are traced). Capturing them in the native mode is what's being worked on next.New commit
6228330: the mesh-shader plants (grass, ferns, flowers, tree leaves) are now in the ray tracing structure in the default native mesh mode, not only withRX_VK_MESH_SHADERS=compute.How: after a native task/mesh draw of the depth pre-pass or a sun cascade whose bottom level is due (every 4th frame per draw,
RX_VK_RT_MESH_EVERY),draw()runs once more with the program's compute fallback variant, for capture only: its task and mesh stages write the records the bottom level is built from, nothing is drawn, and the cards are cut by opacity micromaps as in compute mode.RX_VK_RT_NATIVE_MESH=0turns it off. The capture helpers sit beforewrites_memory()invk_draw.cpp, andtests/test_draw_side_effects.pystubs the two calls the readiness block makes.Kokiri Forest, native, RTX 5090: leaves and grass in the structure, 23 mesh draws a frame, about a quarter captured each frame, none left out; no device lost, no validation line. A first uncapped sample with the capture: median 320 fps, 1.8 ms GPU; the comparison against native without capture and compute mode is running. The first native run in an area compiles the fallback variants (a slow first minute).
Next: the sun shadow pass uses the captured plants in the native mode too, so every sun shadow is traced. Checks after the commit:
tests/run_all.py540 passed, 18 failed, the same 18 as main on this PC.New commit
3f68dfd: GI's passes cost 0.94 ms at 4K on the RTX 5090 (were 1.4 ms), with no visible loss in the irradiance pictures compared.What changed: one ray a half-size pixel and a 3 x 3 a-trous filter by default (
RX_VK_RT_GI_RAYS=2andRX_VK_RT_GI_KERNEL=5give the old settings), and a hit's own sun ray is traced only where neither the screen nor the world-space cache knows the hit. Timing from the pass report: filter 0.39 -> 0.16 ms, rays 1.0 -> 0.51 ms.Stability was measured too (
RX_VK_RT_GI_STABLE=1logs it): the GI term changes about 6 % a frame with the camera still and 10-12 % while turning, which is below the game's own lit colour (10-16 %, partly its TAA jitter). More rays, a longer history or more filter steps barely moved it, so it is not ray noise;RX_VK_RT_GI_HOLDandRX_VK_RT_GI_FEEDBACKare history switches for testing that.Checks after the commit:
tests/run_all.py540 passed, 18 failed, the same 18 as main on this PC.docs/ray-tracing.mdupdated.New commit
0b32254, two small ones: GI gets an area row for Death Mountain Trail (its light-mask program is its own), and a place with no row now takes the switches' values instead of the previous area's; the scene's status line counts the sun cascades' draws left out of the structure, by reason, and names their programs once. GI was also checked at Death Mountain Trail, Zora's Domain and the Market.Checks after the commit:
tests/run_all.py540 passed, 18 failed, the same 18 as main on this PC.Rebased onto current main (
aa95d35, after v3.0.0-rc.4); force-pushed. One conflict:tests/test_menu_sections.py, where #735 removed the VRAM budget row next to the new Ray tracing rows; resolved by keeping both changes. The renderer builds, andtests/run_all.pygives 540 passed, 18 failed on both mainaa95d35and this branch, the same 18.0b32254dd7b4e2584ed3New commit
aa8853a, reflections:RX_VK_RT_REFL_SHARE, default 2). For the material-F0 class each pixel traces 2 rays and the 2 x 2 quad averages them, so rough plate armour (Kakariko's guard) is smooth and as steady frame to frame as the game's own, where 1 ray a pixel left blotches. A device without quad operations in fragment shaders gets no reflections, and the log says so.The SPIR-V linker check passes (20 modules, 0 invalid). Checks after the commit:
tests/run_all.py540 passed, 18 failed, the same 18 as mainaa95d35on this PC.docs/ray-tracing.mdupdated.New commit
fb96265: the traced sun shadow now replaces the game's for every caster, in the default native mesh mode too.6228330), as in compute mode, so leaf and grass shadows are traced by default.RX_VK_RT_SUN_FADE).Native mode, one frame per view at 4K, share of the picture (lost shadow: the game shadows, the rays don't / shadow the game lacks):
The gate fired in none of the five. What is left is not a missing caster: scattered bits at Kokiri (leaf surfaces drawn at another level of detail, thin edges), and at Lake Hylia a band along shadow edges where the game's blurred static map reaches further than the traced edge. The Graphics menu's help, the README and docs/ray-tracing.md no longer say leaf shadows need the compute mesh mode. Not checked yet: the night (moon) and held items.
Checks after the commit: the renderer builds,
tests/run_all.py540 passed, 18 failed, the same 18 as mainaa95d35on this PC.Pushed
34cfe3f: every caster the game's sun cascades draw is now in the ray tracing structure in the areas checked (Kokiri Forest, the Hyrule Field gorge, Lake Hylia, the Lost Woods, inside the Deku Tree).VK_EXT_transform_feedback, then turned into world triangles every 4th frame. The status line's count of cascade draws left out there went from 5.5 a frame to none; the same particle captured from two cascades lands at the same world position.RX_VK_RT_XFB=0turns it off, and a device without the extension goes on without it.clock=<hour>(a test aid for night runs, through the Cheats page's clock action). At 22:00 the traced sun shadows follow the moon's cascades and GI brightens by 12-22% with nothing darker.tests/test_fallback_pipeline_state.py's fixture declares the new variablebuild_graphicsreads.Checks:
tests/run_all.pyon Windows, the same failures as mainaa95d35(machine-specific) plus the two that fail under load here (test_dev_packs,test_finish_output); the renderer builds with 0 failures. Still WIP: the measurements are taken once at the end.Pushed
51e66ed: a fix to the sun gate for interiors.RX_VK_RT_SUN_TILT,RX_VK_RT_SUN_TURN), used to show that the remaining band at Lake Hylia is the game's cascade edge, not a wrong direction.Checks: the same as the last push (main's failures plus the two that fail under load here); the renderer builds with 0 failures.
Pushed
da83010: interiors keep their roofs in the structure, and the caster count is honest on a first visit.RX_VK_RT_REMEMBER=0turns it off. The gate fix of the last push stays as the safety net.Checks: as before (main's failures plus the two that fail under load here); the renderer builds with 0 failures.
Pushed
dd2361band 1d7f2ce: the particles cast on an area's first visit.program_cache_savenow hands each translated program's SPIR-V tort::scene_program_translated, which keeps the vertex stages of the programs that would be captured (at most 512) and makes the capturing module at the first capture. Lost Woods withRX_VK_NO_PROGRAM_CACHE=1(every program translated in the run): 4 of 4 stages made from memory, no cascade draw left out.Known open, being worked on: static-map shadows whose casters are out of the camera's view (a mound by Link's house in Kokiri, a cliff over Kakariko's terraces) are lost with the traced shadow in the static map's place; the fix is capturing the static shadow map's casters into the structure.
Checks: as before (main's failures plus the two that fail under load here); the renderer builds with 0 failures.
Screenshots, same spot and frame, the feature off (left) and on (right), 4K on an RTX 5090, one part on at a time, from the parts' development builds (this PR's code; the sun shadow ones also carry the static shadow map's casters, still in testing). AO and reflections follow.
Sun shadows (
RX_VK_RT=2against 0): each clover leaf, grass blade and fence slat casts its own cut shadow where the game's maps give soft patches.GI (
RX_VK_RT=4against 0): light bounced from lamps, doorways and lava into what the game leaves near black.View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.