render: accumulate the static world-shadow map incrementally (SDK bump)

This commit is contained in:
mchughalex 2026-07-21 13:24:29 +01:00
parent ceb98c34ec
commit c0ba909c86
3 changed files with 26 additions and 1 deletions

View file

@ -6801,6 +6801,7 @@ bool RenderShadowAtlas(const NativeGuestOutputRenderContext& context,
cmd->ClearRenderTarget(g_r.world_shadow, ws_clear);
std::memcpy(g_r.world_shadow_rows, scene.dynobj_ws,
sizeof(g_r.world_shadow_rows));
g_r.world_shadow_drawn.clear();
if (!g_r.world_shadow_primed) {
REXLOG_INFO(
"native-scene: world-shadow map primed (dynobj c5/c6/c7 rows)");
@ -6843,6 +6844,21 @@ bool RenderShadowAtlas(const NativeGuestOutputRenderContext& context,
if (mit == g_r.meshes.end()) {
continue;
}
// Accumulate each item exactly once per map generation: MIN-blend
// re-draws are idempotent, so anything already in the map is pure
// redundant work (the whole static item list re-rendered every 4th
// frame paced this pass). Keyed on mesh + content fingerprint +
// world transform; an in-place content swap or a moved instance
// reads as new and lands on the next accumulation frame.
uint64_t ws_key = 1469598103934665603ull ^ item.mesh;
ws_key = (ws_key ^ mit->second.fingerprint) * 1099511628211ull;
const uint8_t* wb = reinterpret_cast<const uint8_t*>(item.world);
for (size_t bi = 0; bi < sizeof(item.world); ++bi) {
ws_key = (ws_key ^ wb[bi]) * 1099511628211ull;
}
if (!g_r.world_shadow_drawn.insert(ws_key).second) {
continue;
}
float constants[52] = {};
std::memcpy(constants, item.world, sizeof(item.world));
float* mvp = constants + 16;

View file

@ -8,6 +8,8 @@
#include "skate3_native_scene_state.h"
#include <unordered_set>
#if (defined(REX_HAS_D3D12) && REX_HAS_D3D12) || (defined(REX_HAS_VULKAN) && REX_HAS_VULKAN)
#include <rex/graphics/native_guest_renderer.h>
@ -915,6 +917,13 @@ struct RendererState {
bool world_shadow_primed = false;
float world_shadow_rows[12] = {};
static constexpr uint32_t kWorldShadowSize = 512;
// Items already accumulated into the current map (mesh + world-transform
// hash): MIN-blend re-draws of the same geometry are idempotent, so each
// static item needs to land exactly once per map generation. The periodic
// accumulation pass then only draws newly streamed/decoded items (normally
// zero) instead of the whole static item list. Reset on re-prime (clear).
// Render thread only.
std::unordered_set<uint64_t> world_shadow_drawn;
static constexpr uint32_t kUiRegionSize = 1u << 20;
static constexpr uint32_t kUiRegions = 8;
nrhi::Buffer* ui_ring = nullptr;

@ -1 +1 @@
Subproject commit 17caf72bddd25a91500436e4df5a32a00a259d73
Subproject commit 41dd2d5cb4a2648f667365a7984a520959e644a6