From f74dcc37e09ba6af0d1476fc92b775fc9c3a1514 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Sun, 8 Mar 2026 14:34:58 -0700 Subject: [PATCH] FSR2: reduce doubling via tighter clamp, MV dead zone, luminance stability MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Motion shader: zero out sub-0.01px motion to eliminate float precision noise in reprojection (distant geometry with large world coords) - Accumulate: tighten neighborhood clamp gamma 3.0→1.5 to catch slightly misaligned history causing ghost doubles - Reduce max jitter-aware blend 30%→20% for less visible oscillation - Add luminance instability dampening: reduce blend when current frame disagrees with history to prevent shimmer on small/distant features --- assets/shaders/fsr2_accumulate.comp.glsl | 30 ++++++++++++++++++++--- assets/shaders/fsr2_accumulate.comp.spv | Bin 18052 -> 19720 bytes assets/shaders/fsr2_motion.comp.glsl | 7 ++++++ assets/shaders/fsr2_motion.comp.spv | Bin 2184 -> 3728 bytes 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/assets/shaders/fsr2_accumulate.comp.glsl b/assets/shaders/fsr2_accumulate.comp.glsl index 44e7c2ad..9684b7c3 100644 --- a/assets/shaders/fsr2_accumulate.comp.glsl +++ b/assets/shaders/fsr2_accumulate.comp.glsl @@ -133,7 +133,10 @@ void main() { vec3 variance = max(m2 / 9.0 - mean * mean, vec3(0.0)); vec3 stddev = sqrt(variance); - float gamma = 3.0; + // Tighter clamp (gamma 1.5) catches slightly misaligned history that + // causes doubling. With jitter-aware blending providing stability, + // the clamp can be tight without causing jitter-chasing. + float gamma = 1.5; vec3 boxMin = mean - gamma * stddev; vec3 boxMax = mean + gamma * stddev; @@ -143,9 +146,28 @@ void main() { float clampDist = length(historyYCoCg - clampedHistory); - // Uniform 5% blend: ~45 frames for 90% convergence. - // Simpler than edge-aware; the anti-ringing bicubic handles edge stability. - float blendFactor = 0.05; + // Jitter-aware sample weighting: compute how close the current frame's + // jittered sample fell to this output pixel. Close samples are high quality + // (blend aggressively for fast convergence), distant samples are low quality + // (blend minimally to avoid visible jitter). + vec2 jitterPx = pc.jitterOffset.xy * 0.5 * pc.internalSize.xy; + vec2 internalPos = outUV * pc.internalSize.xy; + vec2 subPixelOffset = fract(internalPos) - 0.5; + vec2 sampleDelta = subPixelOffset - jitterPx; + float dist2 = dot(sampleDelta, sampleDelta); + float sampleQuality = exp(-dist2 * 3.0); + float baseBlend = mix(0.02, 0.20, sampleQuality); + + // Luminance instability: when current frame differs significantly from + // history, it may be aliased/flickering content. Reduce blend to prevent + // oscillation, especially for small distant features. + float lumCurrent = dot(currentColor, vec3(0.299, 0.587, 0.114)); + float lumHistory = dot(historyColor, vec3(0.299, 0.587, 0.114)); + float lumDelta = abs(lumCurrent - lumHistory) / max(max(lumCurrent, lumHistory), 0.01); + float stability = 1.0 - clamp(lumDelta * 3.0, 0.0, 0.7); + baseBlend *= stability; + + float blendFactor = baseBlend; // Disocclusion: large clamp distance → rapidly replace stale history blendFactor = mix(blendFactor, 0.60, clamp(clampDist * 5.0, 0.0, 1.0)); diff --git a/assets/shaders/fsr2_accumulate.comp.spv b/assets/shaders/fsr2_accumulate.comp.spv index f69e0f3b26e197e6bb3f1616935effe61fa9b971..640fab16dcae1df79e369f65c1959a9d2e37e5ff 100644 GIT binary patch delta 3334 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 KddS}_(Sbi0Bwif=