render: stand the static sun shadows down in venues with no sane world lighting capture
This commit is contained in:
parent
c9e501e298
commit
186c7de6f4
4 changed files with 29 additions and 2 deletions
|
|
@ -4853,6 +4853,7 @@ void OnDrawDone(uint8_t* base, uint32_t func, uint32_t r4, uint32_t r5, uint32_t
|
||||||
std::memcpy(g_shadow_rows, rows, sizeof(rows));
|
std::memcpy(g_shadow_rows, rows, sizeof(rows));
|
||||||
g_shadow_have = true;
|
g_shadow_have = true;
|
||||||
g_shadow_frame_done = true;
|
g_shadow_frame_done = true;
|
||||||
|
g_shadow_rows_frame = g_guest_frame;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// tree / proxyworld frame rows (see FrameScene::family_rows): their PS
|
// tree / proxyworld frame rows (see FrameScene::family_rows): their PS
|
||||||
|
|
@ -9815,6 +9816,10 @@ void BuildFrameScene(uint8_t* base, const SubmitRecord* records, size_t count) {
|
||||||
if (g_shadow_have) {
|
if (g_shadow_have) {
|
||||||
std::memcpy(scene.shadow_rows, g_shadow_rows, sizeof(g_shadow_rows));
|
std::memcpy(scene.shadow_rows, g_shadow_rows, sizeof(g_shadow_rows));
|
||||||
scene.shadow_valid = true;
|
scene.shadow_valid = true;
|
||||||
|
// Same freshness pattern as the char CSM biases below: outdoor scenes
|
||||||
|
// re-capture every frame, so anything past a couple of seconds means the
|
||||||
|
// current venue's environment shader never produces a sane bank.
|
||||||
|
scene.shadow_fresh = g_guest_frame - g_shadow_rows_frame <= 120;
|
||||||
}
|
}
|
||||||
// Character CSM receive biases (see the header comment): frame-coherent,
|
// Character CSM receive biases (see the header comment): frame-coherent,
|
||||||
// served while fresh enough that a few capture-less frames don't flap the
|
// served while fresh enough that a few capture-less frames don't flap the
|
||||||
|
|
|
||||||
|
|
@ -321,6 +321,13 @@ struct FrameScene {
|
||||||
// c5.x = depth bias, c8 = shadow color + floor; c6 = sun dir, c7 = camera,
|
// c5.x = depth bias, c8 = shadow color + floor; c6 = sun dir, c7 = camera,
|
||||||
// captured for validation only).
|
// captured for validation only).
|
||||||
bool shadow_valid = false;
|
bool shadow_valid = false;
|
||||||
|
// True while the rows above were captured within the last ~2 s of guest
|
||||||
|
// frames. shadow_valid alone latches forever, so interior venues whose
|
||||||
|
// environment banks never pass the capture sanity gate (park-editor
|
||||||
|
// warehouses: near-zero sun, exposure ~0.001) serve stale outdoor rows;
|
||||||
|
// sun-derived features (the native static sun-shadow map) must stand down
|
||||||
|
// there instead of shading a sunless interior with an outdoor sun.
|
||||||
|
bool shadow_fresh = false;
|
||||||
// Extended to c0..c11: c10.x = scene exposure (2.5), c11.y = the material
|
// Extended to c0..c11: c10.x = scene exposure (2.5), c11.y = the material
|
||||||
// multiplier (1.0), consumed by the exact world-shading tone chain.
|
// multiplier (1.0), consumed by the exact world-shading tone chain.
|
||||||
float shadow_rows[48] = {};
|
float shadow_rows[48] = {};
|
||||||
|
|
|
||||||
|
|
@ -7970,8 +7970,17 @@ bool RenderScene(const NativeGuestOutputRenderContext& context, void* /*user_dat
|
||||||
REXCVAR_GET(skate3_native_render_scene_shadow_pcss_min_texel));
|
REXCVAR_GET(skate3_native_render_scene_shadow_pcss_min_texel));
|
||||||
}
|
}
|
||||||
// Native static sun-shadow rows (nsm_x/y/z + params, cb[144..163]);
|
// Native static sun-shadow rows (nsm_x/y/z + params, cb[144..163]);
|
||||||
// nsm_p.x = 0 disables the term in every branch.
|
// nsm_p.x = 0 disables the term in every branch (the scene receive, the
|
||||||
if (g_r.static_sun_valid) {
|
// character branch and the volumetric shafts all read this slice).
|
||||||
|
// Gated on FRESH world rows, not just shadow_valid: interior venues
|
||||||
|
// (park-editor warehouses) never produce a sane environment bank, so the
|
||||||
|
// sun direction here would be a stale outdoor capture. The map then
|
||||||
|
// shades the whole interior as roof-shadowed, and with no game shadow
|
||||||
|
// pass this frame sh_color is zero, so the exact env families clamp
|
||||||
|
// min(lm^2, s + sh_color) to pure black - the missing walls/floor.
|
||||||
|
// The game itself never sun-shadows static world geometry indoors;
|
||||||
|
// standing the map down restores its exact lm^2 shading.
|
||||||
|
if (g_r.static_sun_valid && scene.shadow_fresh) {
|
||||||
std::memcpy(cb + 144, g_r.nsm_rows, sizeof(g_r.nsm_rows));
|
std::memcpy(cb + 144, g_r.nsm_rows, sizeof(g_r.nsm_rows));
|
||||||
cb[156] = std::clamp(
|
cb[156] = std::clamp(
|
||||||
float(REXCVAR_GET(skate3_native_render_scene_shadow_static_strength)),
|
float(REXCVAR_GET(skate3_native_render_scene_shadow_static_strength)),
|
||||||
|
|
|
||||||
|
|
@ -291,6 +291,12 @@ inline float g_outline_color[4] = {0.21569f, 0.64706f, 1.0f, 1.0f};
|
||||||
inline float g_shadow_rows[48] = {};
|
inline float g_shadow_rows[48] = {};
|
||||||
inline bool g_shadow_have = false;
|
inline bool g_shadow_have = false;
|
||||||
inline bool g_shadow_frame_done = false;
|
inline bool g_shadow_frame_done = false;
|
||||||
|
// Guest frame of the last SANE capture. Interior venues (the park-editor
|
||||||
|
// warehouses) run a different environment shader whose bank never passes the
|
||||||
|
// sanity gate (near-zero sun, exposure ~0.001), so the rows latch stale
|
||||||
|
// outdoor state there; consumers that must not act on stale sun state key
|
||||||
|
// off this freshness stamp (see FrameScene::shadow_fresh).
|
||||||
|
inline uint64_t g_shadow_rows_frame = 0;
|
||||||
// Frame-global rows of the tree / proxyworld shader families (see
|
// Frame-global rows of the tree / proxyworld shader families (see
|
||||||
// FrameScene::family_rows), captured from their PS banks when a draw with
|
// FrameScene::family_rows), captured from their PS banks when a draw with
|
||||||
// the matching debug path runs. Guest render thread only.
|
// the matching debug path runs. Guest render thread only.
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue