From ebe513a1c501a9b6800732548ad18c24ad6624a7 Mon Sep 17 00:00:00 2001 From: Xonk Date: Tue, 14 Jul 2026 16:01:36 -0400 Subject: [PATCH] variance clip for temporal upscaling as well --- shaders/dimensions/composite4.fsh | 57 +++++-------------------------- shaders/dimensions/composite5.fsh | 25 +++++++------- 2 files changed, 21 insertions(+), 61 deletions(-) diff --git a/shaders/dimensions/composite4.fsh b/shaders/dimensions/composite4.fsh index b866beb..dd176b4 100644 --- a/shaders/dimensions/composite4.fsh +++ b/shaders/dimensions/composite4.fsh @@ -1,15 +1,12 @@ #include "/lib/settings.glsl" uniform sampler2D colortex3; - uniform vec2 texelSize; - -#include "/lib/TAA_jitter.glsl" -// Compute 3x3 min max for TAA - uniform float viewHeight; uniform float viewWidth; +#include "/lib/TAA_jitter.glsl" + //////////////////////////////VOID MAIN////////////////////////////// //////////////////////////////VOID MAIN////////////////////////////// //////////////////////////////VOID MAIN////////////////////////////// @@ -19,39 +16,9 @@ uniform float viewWidth; void main() { /* RENDERTARGETS:0,6 */ vec2 screenEdges = 2.0/vec2(viewWidth, viewHeight); - vec2 jitter = taaJitter*texelSize*0.5; ivec2 center = ivec2(clamp(gl_FragCoord.xy*texelSize, screenEdges, 1.0-screenEdges)/texelSize); - - // vec3 current = texelFetch2D(colortex3, center, 0).rgb; - // vec3 cMin = current; - // vec3 cMax = current; - // current = texelFetch2D(colortex3, center + ivec2(-1, -1), 0).rgb; - // cMin = min(cMin, current); - // cMax = max(cMax, current); - // current = texelFetch2D(colortex3, center + ivec2(-1, 0), 0).rgb; - // cMin = min(cMin, current); - // cMax = max(cMax, current); - // current = texelFetch2D(colortex3, center + ivec2(-1, 1), 0).rgb; - // cMin = min(cMin, current); - // cMax = max(cMax, current); - // current = texelFetch2D(colortex3, center + ivec2(0, -1), 0).rgb; - // cMin = min(cMin, current); - // cMax = max(cMax, current); - // current = texelFetch2D(colortex3, center + ivec2(0, 1), 0).rgb; - // cMin = min(cMin, current); - // cMax = max(cMax, current); - // current = texelFetch2D(colortex3, center + ivec2(1, -1), 0).rgb; - // cMin = min(cMin, current); - // cMax = max(cMax, current); - // current = texelFetch2D(colortex3, center + ivec2(1, 0), 0).rgb; - // cMin = min(cMin, current); - // cMax = max(cMax, current); - // current = texelFetch2D(colortex3, center + ivec2(1, 1), 0).rgb; - // cMin = min(cMin, current); - // cMax = max(cMax, current); - // gl_FragData[0].rgb = cMax; - // gl_FragData[1].rgb = cMin; - + + // variance clip: https://developer.download.nvidia.com/gameworks/events/GDC2016/msalvi_temporal_supersampling.pdf vec3 col0 = texelFetch(colortex3, center, 0).rgb; vec3 col1 = texelFetch(colortex3, center + ivec2(1, 1), 0).rgb; vec3 col2 = texelFetch(colortex3, center + ivec2(1, -1), 0).rgb; @@ -62,15 +29,9 @@ void main() { vec3 col7 = texelFetch(colortex3, center + ivec2(-1, 0), 0).rgb; vec3 col8 = texelFetch(colortex3, center + ivec2(1, 0), 0).rgb; - vec3 colMax = max(col0,max(col1,max(col2,max(col3, max(col4, max(col5, max(col6, max(col7, col8)))))))); - vec3 colMin = min(col0,min(col1,min(col2,min(col3, min(col4, min(col5, min(col6, min(col7, col8)))))))); + vec3 momentsA = (col0+col1+col2+col3+col4+col5+col6+col7+col8)/9.0; + vec3 momentsB = (col0*col0+col1*col1+col2*col2+col3*col3+col4*col4+col5*col5+col6*col6+col7*col7+col8*col8)/9.0; - vec3 colMax5 = max(col0,max(col5,max(col6,max(col7,col8)))); - vec3 colMin5 = min(col0,min(col5,min(col6,min(col7,col8)))); - - colMin = 0.5 * (colMin + colMin5); - colMax = 0.5 * (colMax + colMax5); - - gl_FragData[0].rgb = colMax; - gl_FragData[1].rgb = colMin; -} + gl_FragData[0].rgb = momentsA; + gl_FragData[1].rgb = momentsB; +} \ No newline at end of file diff --git a/shaders/dimensions/composite5.fsh b/shaders/dimensions/composite5.fsh index cabdeb8..eac5e42 100644 --- a/shaders/dimensions/composite5.fsh +++ b/shaders/dimensions/composite5.fsh @@ -315,10 +315,19 @@ vec4 computeTAA(vec2 texcoord, bool hand){ if (previousPosition.x < 0.0 || previousPosition.y < 0.0 || previousPosition.x > 1.0 || previousPosition.y > 1.0) return vec4(currentFrame, 1.0); #endif + // variance clip: https://developer.download.nvidia.com/gameworks/events/GDC2016/msalvi_temporal_supersampling.pdf #if TAA_MODE == 3 // Interpolating neighboorhood clampling boundaries between pixels - vec3 colMax = texture(colortex0, adjTC_noJitter).rgb; - vec3 colMin = texture(colortex6, adjTC_noJitter).rgb; + // vec3 colMax = texture(colortex0, adjTC_noJitter).rgb; + // vec3 colMin = texture(colortex6, adjTC_noJitter).rgb; + + float tuner = 1.25; + vec3 momentsA = texture(colortex0, adjTC_noJitter).rgb; + vec3 momentsB = texture(colortex6, adjTC_noJitter).rgb; + vec3 standardDev = sqrt(max(momentsB - momentsA*momentsA,0.0)); + + vec3 colMin = momentsA - tuner*standardDev; + vec3 colMax = momentsA + tuner*standardDev; #else //Assuming the history color is a blend of the 3x3 neighborhood, we clamp the history to the min and max of each channel in the 3x3 neighborhood vec3 col0 = texture(colortex3, adjTC_noJitter).rgb; @@ -331,7 +340,6 @@ vec4 computeTAA(vec2 texcoord, bool hand){ vec3 col7 = texture(colortex3, adjTC_noJitter + vec2(-texelSize.x, 0.0)*clampRadius).rgb; vec3 col8 = texture(colortex3, adjTC_noJitter + vec2( texelSize.x, 0.0)*clampRadius).rgb; - // variance clip: https://developer.download.nvidia.com/gameworks/events/GDC2016/msalvi_temporal_supersampling.pdf float tuner = 1.25; vec3 momentsA = (col0+col1+col2+col3+col4+col5+col6+col7+col8)/9.0; vec3 momentsB = (col0*col0+col1*col1+col2*col2+col3*col3+col4*col4+col5*col5+col6*col6+col7*col7+col8*col8)/9.0; @@ -339,11 +347,6 @@ vec4 computeTAA(vec2 texcoord, bool hand){ vec3 colMin = momentsA - tuner*standardDev; vec3 colMax = momentsA + tuner*standardDev; - - // colMax = max(col0,max(col1,max(col2,max(col3, max(col4, max(col5, max(col6, max(col7, col8)))))))); - // colMin = min(col0,min(col1,min(col2,min(col3, min(col4, min(col5, min(col6, min(col7, col8)))))))); - // colMin = 0.5 * (colMin + min(col0,min(col5,min(col6,min(col7,col8))))); - // colMax = 0.5 * (colMax + max(col0,max(col5,max(col6,max(col7,col8))))); #endif #if CRITICAL_DAMAGE_TAKEN_EFFECT_START > 0 @@ -355,11 +358,7 @@ vec4 computeTAA(vec2 texcoord, bool hand){ vec3 clampedframeHistory = clamp(frameHistory, colMin, colMax); // return the first moments instead of history if the difference across frames in the neighborhood is enough for it. helps reduces ghosting without looking too grainy/flickery - #if TAA_MODE == 3 - clampedframeHistory = mix(clampedframeHistory, currentFrame, clamp(abs(clampedframeHistory - frameHistory)/clampedframeHistory,0.0,1.0)); - #else - clampedframeHistory = mix(clampedframeHistory, momentsA, clamp(abs(clampedframeHistory - frameHistory)/clampedframeHistory,0.0,1.0)); - #endif + clampedframeHistory = mix(clampedframeHistory, momentsA, clamp(abs(clampedframeHistory - frameHistory)/clampedframeHistory,0.0,1.0)); float blendingFactor = BLEND_FACTOR; // reduce history usage if the camera moves to reduce artifacts in motion.