Skeletal pixels now bypass the internal temporal accumulato

This commit is contained in:
Justin Marshall
2026-05-24 15:52:51 -07:00
parent 4ccdb56258
commit 26dd7e649e
2 changed files with 21 additions and 3 deletions
+16 -2
View File
@@ -5399,6 +5399,10 @@ float3 EstimateRayTracedSpecularReflection(
R"(
float3 ApplyRealisticOutputCurve(float3 color)
{
color.r = ((color.r == color.r) && abs(color.r) < 65504.0) ? color.r : 0.0;
color.g = ((color.g == color.g) && abs(color.g) < 65504.0) ? color.g : 0.0;
color.b = ((color.b == color.b) && abs(color.b) < 65504.0) ? color.b : 0.0;
// Final photographic shoulder only: it does not change light radius or
// attenuation, but it prevents intense local lights/specular/bloom from
// clipping into a flat white patch. Values below 1.0 are left untouched.
@@ -5935,6 +5939,18 @@ void TemporalAccumCS(uint3 dispatchThreadId : SV_DispatchThreadID)
float4 history = gHistoryTex.Load(int3(pixel, 0));
float historyCount = (gFrameIndex == 0u) ? 0.0 : clamp(history.a, 0.0, 63.0);
// This temporal accumulator has no reprojection/object history validation.
// Animated characters can inherit the previous frame's wall/background color
// at the same screen pixel, which shows up as grey path-trace-only dirt even
// though the current G-buffer is clean. Keep skeletal pixels current-frame
// and let the following geometry-aware spatial pass do the filtering.
if (isSkeletal)
{
gTemporalOutTex[pixel] = raw;
gHistoryOutTex[pixel] = float4(raw.rgb, 0.0);
return;
}
if (historyCount <= 0.0)
{
gTemporalOutTex[pixel] = raw;
@@ -5952,8 +5968,6 @@ void TemporalAccumCS(uint3 dispatchThreadId : SV_DispatchThreadID)
// current-frame weight so the accumulator does not leave obvious trails.
float currentWeight = max(1.0 / (historyCount + 1.0), 0.035);
currentWeight = max(currentWeight, saturate(relChange * 0.24));
if (isSkeletal)
currentWeight = max(currentWeight, 0.25);
currentWeight = saturate(currentWeight);
float3 resolved = lerp(historyColor, max(raw.rgb, 0.0), currentWeight);