diff --git a/Content/Shaders/TAA.flax b/Content/Shaders/TAA.flax index fca1b3990..a7c9ed02f 100644 --- a/Content/Shaders/TAA.flax +++ b/Content/Shaders/TAA.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:53701ca887c28125ee0bab003eca173b18e795b56a6f45c40e38cf6078fb434b -size 10434 +oid sha256:fd77c5c059f221d4e82e774d328af091b72ed5a819f2b972a41aff5f947f4da4 +size 9466 diff --git a/Source/Shaders/TAA.shader b/Source/Shaders/TAA.shader index 73132d32f..d4e08bcf5 100644 --- a/Source/Shaders/TAA.shader +++ b/Source/Shaders/TAA.shader @@ -15,7 +15,6 @@ #define DEBUG_MOTION 0 #define DEBUG_VELOCITY_REJECTION 0 -#define TAA_EPSILON 0.000001f #define NO_GBUFFER_SAMPLING #define NEED_DEPTH_VELOCITY (MINMAX_4TAP_VARYING) #if NEED_DEPTH_VELOCITY @@ -149,23 +148,6 @@ VelocityDepth SampleVelocityDepth(float2 uv) return velocityDepth; } -float4 ClipAAB(float3 aabbMin, float3 aabbMax, float4 p, float4 q) -{ - // only clips towards aabb center - float3 pClip = 0.5 * (aabbMax + aabbMin); - float3 eClip = 0.5 * (aabbMax - aabbMin) + TAA_EPSILON; - - float4 vClip = q - float4(pClip, p.w); - float3 vUnit = vClip.xyz / eClip; - float3 aUnit = abs(vUnit); - float maUnit = max(aUnit.x, max(aUnit.y, aUnit.z)); - - if (maUnit > 1.0) - return float4(pClip, p.w) + vClip / maUnit; - else - return q; // point inside aabb -} - // Pixel Shader for Temporal Anti-Aliasing META_PS(true, FEATURE_LEVEL_ES2) META_PERMUTATION_1(QUALITY=0) @@ -248,16 +230,10 @@ float4 PS(Quad_VS2PS input) : SV_Target0 //history = clamp(history, cMin, cMax); // Calculate history weight from unbiased luminance diff - // [Reference: "TSSAA (Temporal Super-Sampling AA)" by Timothy Lottes (2011)] - float currentLum = Luminance(current.rgb); - float historyLum = Luminance(history.rgb); - float unbiasedDiff = abs(currentLum - historyLum) / max(currentLum, max(historyLum, 0.2f)); - float unbiasedWeight = 1.0 - unbiasedDiff; - float unbiasedWeightSqr = unbiasedWeight * unbiasedWeight; + float historyBlend = TemporalHistoryWeight(current, history, MotionBlending); #if DEBUG_LUMINANCE_DIFF - return unbiasedWeightSqr.xxxx; + return historyBlend.xxxx; #endif - float historyBlend = lerp(MotionBlending, min(MotionBlending + 0.2f, 0.97f), unbiasedWeightSqr); // Higher history blend when there is no motion float motion = saturate(length(velocityDepth.xy) * 1000.0f); diff --git a/Source/Shaders/Temporal.hlsl b/Source/Shaders/Temporal.hlsl index 8c32253e6..6cea8c14a 100644 --- a/Source/Shaders/Temporal.hlsl +++ b/Source/Shaders/Temporal.hlsl @@ -5,6 +5,25 @@ #include "./Flax/Common.hlsl" +#define TAA_EPSILON 0.000001f + +// Calculates history weight from unbiased luminance diff +// [Timothy Lottes, 2011, "TSSAA (Temporal Super-Sampling AA)"] +float TemporalHistoryWeight(float4 current, float4 history, float motionBlending = 0.85f) +{ + float currentLum = Luminance(current.rgb); + float historyLum = Luminance(history.rgb); + float unbiasedDiff = abs(currentLum - historyLum) / max(currentLum, max(historyLum, 0.2f)); + float unbiasedWeight = 1.0 - unbiasedDiff; + float unbiasedWeightSqr = unbiasedWeight * unbiasedWeight; + float historyBlend = lerp(motionBlending, min(motionBlending + 0.2f, 0.97f), unbiasedWeightSqr); +#if defined(DEBUG_LUMINANCE_DIFF) && DEBUG_LUMINANCE_DIFF + return unbiasedWeightSqr; +#endif + return historyBlend; +} + +// Clamps sample color to neighbourhood pixels bounds // [Pedersen, 2016, "Temporal Reprojection Anti-Aliasing in INSIDE"] float4 ClipToAABB(float4 color, float4 minimum, float4 maximum) { @@ -16,4 +35,21 @@ float4 ClipToAABB(float4 color, float4 minimum, float4 maximum) return maxUnit > 1.0 ? center + (shift / maxUnit) : color; } +float4 ClipAAB(float3 aabbMin, float3 aabbMax, float4 p, float4 q) +{ + // only clips towards aabb center + float3 pClip = 0.5 * (aabbMax + aabbMin); + float3 eClip = 0.5 * (aabbMax - aabbMin) + TAA_EPSILON; + + float4 vClip = q - float4(pClip, p.w); + float3 vUnit = vClip.xyz / eClip; + float3 aUnit = abs(vUnit); + float maUnit = max(aUnit.x, max(aUnit.y, aUnit.z)); + + if (maUnit > 1.0) + return float4(pClip, p.w) + vClip / maUnit; + else + return q; // point inside aabb +} + #endif