(TAA) Add settings to control sampler filtering and variance clipping

This commit is contained in:
Xonk
2026-08-09 00:31:46 -04:00
parent f374e79f12
commit 8805645eba
4 changed files with 81 additions and 42 deletions
+65 -37
View File
@@ -18,6 +18,8 @@ uniform vec2 texelSize;
uniform float frameTimeCounter;
uniform float viewHeight;
uniform float viewWidth;
uniform bool windowResizeCheck;
uniform int frameCounter;
uniform vec3 previousCameraPosition;
uniform mat4 gbufferPreviousModelView;
@@ -48,15 +50,18 @@ vec2 decodeVec2(float a){
float luma(vec3 color) {
return dot(color,vec3(0.21, 0.72, 0.07));
}
float interleaved_gradientNoise(){
return fract(52.9829189*fract(0.06711056*gl_FragCoord.x + 0.00583715*gl_FragCoord.y)+tempOffsets);
}
float triangularize(float dither)
{
float center = dither*2.0-1.0;
dither = center*inversesqrt(abs(center));
return clamp(dither-fsign(center),0.0,1.0);
}
vec4 fp10Dither(vec4 color ,float dither){
const vec3 mantissaBits = vec3(6.,6.,5.);
vec3 exponent = floor(log2(color.rgb));
@@ -194,12 +199,12 @@ vec3 FastCatmulRom(sampler2D colorTex, vec2 texcoord, vec4 rtMetrics, float shar
vec2 w12 = w1 + w2;
vec2 tc12 = rtMetrics.xy * (centerPosition + w2 / w12);
vec3 centerColor = texture(colorTex, vec2(tc12.x, tc12.y)).rgb;
vec2 tc0 = rtMetrics.xy * (centerPosition - 1.0);
vec2 tc3 = rtMetrics.xy * (centerPosition + 2.0);
vec4 color = vec4(texture(colorTex, vec2(tc12.x, tc0.y )).rgb, 1.0) * (w12.x * w0.y ) +
vec4(texture(colorTex, vec2(tc0.x, tc12.y)).rgb, 1.0) * (w0.x * w12.y) +
vec4(centerColor, 1.0) * (w12.x * w12.y) +
vec4(texture(colorTex, vec2(tc12.x, tc12.y)).rgb, 1.0) * (w12.x * w12.y) +
vec4(texture(colorTex, vec2(tc3.x, tc12.y)).rgb, 1.0) * (w3.x * w12.y) +
vec4(texture(colorTex, vec2(tc12.x, tc3.y )).rgb, 1.0) * (w12.x * w3.y );
@@ -212,11 +217,17 @@ vec3 closestToCamera5taps(vec2 texcoord, sampler2D depth)
vec2 du = vec2(texelSize.x*2., 0.0);
vec2 dv = vec2(0.0, texelSize.y*2.);
vec3 dtl = vec3(texcoord,0.) + vec3(-texelSize, texture(depth, texcoord - dv - du).x);
vec3 dtr = vec3(texcoord,0.) + vec3( texelSize.x, -texelSize.y, texture(depth, texcoord - dv + du).x);
vec3 dmc = vec3(texcoord,0.) + vec3( 0.0, 0.0, texture(depth, texcoord).x);
vec3 dbl = vec3(texcoord,0.) + vec3(-texelSize.x, texelSize.y, texture(depth, texcoord + dv - du).x);
vec3 dbr = vec3(texcoord,0.) + vec3( texelSize.x, texelSize.y, texture(depth, texcoord + dv + du).x);
// vec3 dtl = vec3(texcoord,0.) + vec3(-texelSize, texture(depth, texcoord - dv - du).x);
// vec3 dtr = vec3(texcoord,0.) + vec3( texelSize.x, -texelSize.y, texture(depth, texcoord - dv + du).x);
// vec3 dmc = vec3(texcoord,0.) + vec3( 0.0, 0.0, texture(depth, texcoord).x);
// vec3 dbl = vec3(texcoord,0.) + vec3(-texelSize.x, texelSize.y, texture(depth, texcoord + dv - du).x);
// vec3 dbr = vec3(texcoord,0.) + vec3( texelSize.x, texelSize.y, texture(depth, texcoord + dv + du).x);
vec3 dtl = vec3(texcoord,0.) + vec3(-texelSize, texelFetch(depth, ivec2((texcoord - dv - du)/texelSize),0).x);
vec3 dtr = vec3(texcoord,0.) + vec3( texelSize.x, -texelSize.y, texelFetch(depth, ivec2((texcoord - dv + du)/texelSize),0).x);
vec3 dmc = vec3(texcoord,0.) + vec3( 0.0, 0.0, texelFetch(depth, ivec2(texcoord/texelSize),0).x);
vec3 dbl = vec3(texcoord,0.) + vec3(-texelSize.x, texelSize.y, texelFetch(depth, ivec2((texcoord + dv - du)/texelSize),0).x);
vec3 dbr = vec3(texcoord,0.) + vec3( texelSize.x, texelSize.y, texelFetch(depth, ivec2((texcoord + dv + du)/texelSize),0).x);
vec3 dmin = dmc;
dmin = dmin.z > dtr.z ? dtr : dmin;
@@ -242,11 +253,17 @@ vec3 closestToCamera5taps_DH(vec2 texcoord, sampler2D depth, sampler2D dhDepth,
vec3 dbl = vec3(texcoord,0.);
vec3 dbr = vec3(texcoord,0.);
dtl += vec3(-texelSize, depthCheck ? texture(dhDepth, texcoord - dv - du).x : texture(depth, texcoord - dv - du).x);
dtr += vec3( texelSize.x, -texelSize.y, depthCheck ? texture(dhDepth, texcoord - dv + du).x : texture(depth, texcoord - dv + du).x);
dmc += vec3( 0.0, 0.0, depthCheck ? texture(dhDepth, texcoord).x : texture(depth, texcoord).x);
dbl += vec3(-texelSize.x, texelSize.y, depthCheck ? texture(dhDepth, texcoord + dv - du).x : texture(depth, texcoord + dv - du).x);
dbr += vec3( texelSize.x, texelSize.y, depthCheck ? texture(dhDepth, texcoord + dv + du).x : texture(depth, texcoord + dv + du).x);
// dtl += vec3(-texelSize, depthCheck ? texture(dhDepth, texcoord - dv - du).x : texture(depth, texcoord - dv - du).x);
// dtr += vec3( texelSize.x, -texelSize.y, depthCheck ? texture(dhDepth, texcoord - dv + du).x : texture(depth, texcoord - dv + du).x);
// dmc += vec3( 0.0, 0.0, depthCheck ? texture(dhDepth, texcoord).x : texture(depth, texcoord).x);
// dbl += vec3(-texelSize.x, texelSize.y, depthCheck ? texture(dhDepth, texcoord + dv - du).x : texture(depth, texcoord + dv - du).x);
// dbr += vec3( texelSize.x, texelSize.y, depthCheck ? texture(dhDepth, texcoord + dv + du).x : texture(depth, texcoord + dv + du).x);
dtl += vec3(-texelSize, depthCheck ? texelFetch(dhDepth, ivec2((texcoord - dv - du)/texelSize),0).x : texture(depth, ivec2((texcoord - dv - du)/texelSize),0).x);
dtr += vec3( texelSize.x, -texelSize.y, depthCheck ? texelFetch(dhDepth, ivec2((texcoord - dv + du)/texelSize),0).x : texture(depth, ivec2((texcoord - dv + du)/texelSize),0).x);
dmc += vec3( 0.0, 0.0, depthCheck ? texelFetch(dhDepth, ivec2(texcoord/texelSize ),0).x : texture(depth, ivec2(texcoord/texelSize) ,0).x);
dbl += vec3(-texelSize.x, texelSize.y, depthCheck ? texelFetch(dhDepth, ivec2((texcoord + dv - du)/texelSize),0).x : texture(depth, ivec2((texcoord + dv - du)/texelSize),0).x);
dbr += vec3( texelSize.x, texelSize.y, depthCheck ? texelFetch(dhDepth, ivec2((texcoord + dv + du)/texelSize),0).x : texture(depth, ivec2((texcoord + dv + du)/texelSize),0).x);
vec3 dmin = dmc;
dmin = dmin.z > dtr.z ? dtr : dmin;
@@ -260,12 +277,20 @@ vec3 closestToCamera5taps_DH(vec2 texcoord, sampler2D depth, sampler2D dhDepth,
return dmin;
}
uniform bool windowResizeCheck;
uniform int frameCounter;
// TAA_TEXTURE_FILTERING_MODES
#define NEAREST_ONLY 0
#define LIENAR_ONLY 1
#define NEAREST_AND_LINEAR 2
vec4 computeTAA(vec2 texcoord, bool hand){
vec2 jitter = taaJitter*texelSize*0.5;
vec2 adjTC = clamp(texcoord*RENDER_SCALE - texelSize*0.5, vec2(0.0), RENDER_SCALE - texelSize*1.5);
vec2 adjTC = texcoord*RENDER_SCALE;
// when linear filtering is used, ensure it samples center of pixel
#if TAA_TEXTURE_FILTERING_MODE == LIENAR_ONLY || TAA_TEXTURE_FILTERING_MODE == NEAREST_AND_LINEAR
adjTC -= texelSize*0.5;
#endif
vec2 adjTC_noJitter = adjTC + jitter;
// get previous frames position stuff for UV
@@ -289,9 +314,7 @@ vec4 computeTAA(vec2 texcoord, bool hand){
#endif
vec2 velocity = previousPosition.xy - closestToCamera.xy;
previousPosition.xy = texcoord + (hand ? vec2(0.0) : velocity);
float cameraMovement = length(velocity/texelSize);
// adjust clamping radius when motion is detected to reduce ghosting further without needing to change blend factor
@@ -302,25 +325,22 @@ vec4 computeTAA(vec2 texcoord, bool hand){
#endif
// sample current frame, and make sure it is de-jittered
#if TAA_MODE == 3
#if TAA_MODE == 3 || TAA_TEXTURE_FILTERING_MODE == LIENAR_ONLY
vec3 currentFrame = smoothfilter(colortex3, adjTC_noJitter).rgb;
#else
vec3 currentFrame = texelFetch(colortex3, ivec2(adjTC_noJitter/texelSize), 0).rgb;
#endif
//reject history if off-screen and early exit
#if CRITICAL_DAMAGE_TAKEN_EFFECT_START > 0
if (CriticalDamageTaken < 0.001 && (previousPosition.x < 0.0 || previousPosition.y < 0.0 || previousPosition.x > 1.0 || previousPosition.y > 1.0)) return vec4(currentFrame, 1.0);
#else
//reject history if off-screen and early exit
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;
float tuner = 1.25;
vec3 momentsA = texture(colortex0, adjTC_noJitter).rgb;
vec3 momentsB = texture(colortex6, adjTC_noJitter).rgb;
@@ -330,15 +350,27 @@ vec4 computeTAA(vec2 texcoord, bool hand){
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;
vec3 col1 = texture(colortex3, adjTC_noJitter + vec2( texelSize.x, texelSize.y)*clampRadius).rgb;
vec3 col2 = texture(colortex3, adjTC_noJitter + vec2( texelSize.x, -texelSize.y)*clampRadius).rgb;
vec3 col3 = texture(colortex3, adjTC_noJitter + vec2(-texelSize.x, -texelSize.y)*clampRadius).rgb;
vec3 col4 = texture(colortex3, adjTC_noJitter + vec2(-texelSize.x, texelSize.y)*clampRadius).rgb;
vec3 col5 = texture(colortex3, adjTC_noJitter + vec2( 0.0, texelSize.y)*clampRadius).rgb;
vec3 col6 = texture(colortex3, adjTC_noJitter + vec2( 0.0, -texelSize.y)*clampRadius).rgb;
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;
#if TAA_TEXTURE_FILTERING_MODE == LIENAR_ONLY || TAA_TEXTURE_FILTERING_MODE == NEAREST_AND_LINEAR
vec3 col0 = texture(colortex3, adjTC_noJitter).rgb;
vec3 col1 = texture(colortex3, adjTC_noJitter + vec2( texelSize.x, texelSize.y)*clampRadius).rgb;
vec3 col2 = texture(colortex3, adjTC_noJitter + vec2( texelSize.x, -texelSize.y)*clampRadius).rgb;
vec3 col3 = texture(colortex3, adjTC_noJitter + vec2(-texelSize.x, -texelSize.y)*clampRadius).rgb;
vec3 col4 = texture(colortex3, adjTC_noJitter + vec2(-texelSize.x, texelSize.y)*clampRadius).rgb;
vec3 col5 = texture(colortex3, adjTC_noJitter + vec2( 0.0, texelSize.y)*clampRadius).rgb;
vec3 col6 = texture(colortex3, adjTC_noJitter + vec2( 0.0, -texelSize.y)*clampRadius).rgb;
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;
#else
vec3 col0 = texelFetch(colortex3, ivec2(adjTC_noJitter/texelSize) ,0).rgb;
vec3 col1 = texelFetch(colortex3, ivec2((adjTC_noJitter + vec2( texelSize.x, texelSize.y)*clampRadius)/texelSize),0).rgb;
vec3 col2 = texelFetch(colortex3, ivec2((adjTC_noJitter + vec2( texelSize.x, -texelSize.y)*clampRadius)/texelSize),0).rgb;
vec3 col3 = texelFetch(colortex3, ivec2((adjTC_noJitter + vec2(-texelSize.x, -texelSize.y)*clampRadius)/texelSize),0).rgb;
vec3 col4 = texelFetch(colortex3, ivec2((adjTC_noJitter + vec2(-texelSize.x, texelSize.y)*clampRadius)/texelSize),0).rgb;
vec3 col5 = texelFetch(colortex3, ivec2((adjTC_noJitter + vec2( 0.0, texelSize.y)*clampRadius)/texelSize),0).rgb;
vec3 col6 = texelFetch(colortex3, ivec2((adjTC_noJitter + vec2( 0.0, -texelSize.y)*clampRadius)/texelSize),0).rgb;
vec3 col7 = texelFetch(colortex3, ivec2((adjTC_noJitter + vec2(-texelSize.x, 0.0)*clampRadius)/texelSize),0).rgb;
vec3 col8 = texelFetch(colortex3, ivec2((adjTC_noJitter + vec2( texelSize.x, 0.0)*clampRadius)/texelSize),0).rgb;
#endif
float tuner = 1.25;
vec3 momentsA = (col0+col1+col2+col3+col4+col5+col6+col7+col8)/9.0;
@@ -361,13 +393,10 @@ vec4 computeTAA(vec2 texcoord, bool hand){
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.
blendingFactor = clamp(cameraMovement, blendingFactor, BLEND_FACTOR_DURING_MOVEMENT);
// #if NEIGHBORHOOD_CLAMP_RADIUS_MULT_DURING_MOVEMENT > 99
// if(hand) blendingFactor = clamp(cameraMovement, blendingFactor, 1.0);
// #endif
#if CRITICAL_DAMAGE_TAKEN_EFFECT_START > 0
if(CriticalDamageTaken > 0.001){
clampedframeHistory = mix(clampedframeHistory, frameHistory, pow(CriticalDamageTaken,0.3));
@@ -391,10 +420,9 @@ vec4 computeTAA(vec2 texcoord, bool hand){
return vec4(finalResult, 1.0);
}
void main() {
/* RENDERTARGETS:5 */
#if TAA_MODE > 0
// vec2 taauTC = clamp(texcoord*RENDER_SCALE, vec2(0.0), RENDER_SCALE - texelSize*2.0) + taaJitter*texelSize*0.5;
vec2 taauTC = clamp(texcoord*RENDER_SCALE - texelSize*0.5, vec2(0.0), RENDER_SCALE - texelSize*1.5);
+9
View File
@@ -444,6 +444,12 @@ screen.Post_Processing = Post Processing
prefix.SCALE_FACTOR = §fUpscale from
suffix.SCALE_FACTOR = x §fof the window resolution
option.TAA_TEXTURE_FILTERING_MODE = Sampler Filter Mode
value.TAA_TEXTURE_FILTERING_MODE.0 = Nearest Neighbor §bⓘ Sharpest but Grainy§r
value.TAA_TEXTURE_FILTERING_MODE.1 = Linear §bⓘ Cleanest but slightly blurry§r
value.TAA_TEXTURE_FILTERING_MODE.2 = Nearest (current frame) + Linear (neighborhood sampling)
option.VARIANCE_CLIP_GAMMA_VAR = Variance Clip Tuning
option.MOTION_BLUR_AMOUNT = Motion Blur Amount
suffix.MOTION_BLUR_AMOUNT =%
value.MOTION_BLUR_AMOUNT.0 = §cOFF
@@ -518,6 +524,9 @@ screen.Post_Processing = Post Processing
option.MINOR_DAMAGE_TAKEN_EFFECT_START.comment = §bⓘ What is this?§r This is the flash of red color that happens when damage is taken. Configure what amount of sudden health loss needs to be had for this screen effect to activate. §a⚠ PERFORMANCE COST:§r very very low
option.CRITICAL_DAMAGE_TAKEN_EFFECT_START.comment = §bⓘ What is this?§r This is the intense red colored trailing effect that happens when A LOT of damage is taken. Configure what amount of sudden health loss needs to be had for this screen effect to activate. §a⚠ PERFORMANCE COST:§r very very low
option.TAA_TEXTURE_FILTERING_MODE.comment = §bⓘ What is this?§r Configure the texture filtering used for TAA. §a⚠ PERFORMANCE COST:§r basically none
option.VARIANCE_CLIP_GAMMA_VAR.comment = §bⓘ What is this?§r Variance Clipping restrics TAA history to reduce ghosting or trailing motion artifacts. Low values have less trailing artifacts, but flicker more and are blurrier. High values have a cleaner and more stable image, but more trailing motion artifacts. §a⚠ PERFORMANCE COST:§r basically none
###################################################### ↓↓↓ THIS SUBMENU'S LABELS
screen.Color_Processing = Color Processing
+2
View File
@@ -219,6 +219,8 @@
#define BLEND_FACTOR 0.125 // [0.01 0.02 0.03 0.04 0.05 0.06 0.08 0.1 0.12 0.125 0.14 0.16 0.18 0.20 0.25 0.30 0.40 0.50 0.60 0.70 0.80 0.90 1.00]
#define BLEND_FACTOR_DURING_MOVEMENT 0.125 // [0.01 0.02 0.03 0.04 0.05 0.06 0.08 0.1 0.12 0.125 0.14 0.16 0.18 0.20 0.25 0.30 0.40 0.50 0.60 0.70 0.80 0.90 1.00]
#define NEIGHBORHOOD_CLAMP_RADIUS_MULT_DURING_MOVEMENT 100 // [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100]
#define TAA_TEXTURE_FILTERING_MODE 0 // [0 1 2]
#define VARIANCE_CLIP_GAMMA_VAR 1.25 // [0.0 0.05 0.1 0.15 0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 0.95 1.0 1.05 1.1 1.15 1.2 1.25 1.3 1.35 1.4 1.45 1.5 1.55 1.6 1.65 1.7 1.75 1.8 1.85 1.9 1.95 2.0 2.05 2.1 2.15 2.2 2.25 2.3 2.35 2.4 2.45 2.5 2.55 2.6 2.65 2.7 2.75 2.8 2.85 2.9 2.95 3.0 3.05 3.1 3.15 3.2 3.25 3.3 3.35 3.4 3.45 3.5 3.55 3.6 3.65 3.7 3.75 3.8 3.85 3.9 3.95 4.0 4.05 4.1 4.15 4.2 4.25 4.3 4.35 4.4 4.45 4.5 4.55 4.6 4.65 4.7 4.75 4.8 4.85 4.9 4.95 5.0 5.05 5.1 5.15 5.2 5.25 5.3 5.35 5.4 5.45 5.5 5.55 5.6 5.65 5.7 5.75 5.8 5.85 5.9 5.95 6.0 6.05 6.1 6.15 6.2 6.25 6.3 6.35 6.4 6.45 6.5 6.55 6.6 6.65 6.7 6.75 6.8 6.85 6.9 6.95 7.0 7.05 7.1 7.15 7.2 7.25 7.3 7.35 7.4 7.45 7.5 7.55 7.6 7.65 7.7 7.75 7.8 7.85 7.9 7.95 8.0 8.05 8.1 8.15 8.2 8.25 8.3 8.35 8.4 8.45 8.5 8.55 8.6 8.65 8.7 8.75 8.8 8.85 8.9 8.95 9.0 9.05 9.1 9.15 9.2 9.25 9.3 9.35 9.4 9.45 9.5 9.55 9.6 9.65 9.7 9.75 9.8 9.85 9.9 9.95 10.0]
#endif
#if defined POST_PROCESSING_RELATED_SETTINGS
File diff suppressed because one or more lines are too long