Add sharpening and better AABB history clamp to Screen Space Reflections temporal filter

This commit is contained in:
2026-01-14 14:00:54 +01:00
parent b172b08782
commit d2d7a871ce
4 changed files with 35 additions and 39 deletions
@@ -24,29 +24,23 @@
GPU_CB_STRUCT(Data { GPU_CB_STRUCT(Data {
ShaderGBufferData GBuffer; ShaderGBufferData GBuffer;
float MaxColorMiplevel; float MaxColorMiplevel;
float TraceSizeMax; float TraceSizeMax;
float MaxTraceSamples; float MaxTraceSamples;
float RoughnessFade; float RoughnessFade;
Float2 SSRtexelSize; Float2 SSRtexelSize;
float TemporalTime; float TemporalTime;
float BRDFBias; float BRDFBias;
float WorldAntiSelfOcclusionBias; float WorldAntiSelfOcclusionBias;
float EdgeFadeFactor; float EdgeFadeFactor;
float TemporalResponse; float TemporalResponse;
float TemporalScale; float TemporalScale;
float RayTraceStep; float RayTraceStep;
float TemporalEffect; float TemporalEffect;
float Intensity; float Intensity;
float FadeOutDistance; float FadeOutDistance;
Matrix ViewMatrix; Matrix ViewMatrix;
Matrix ViewProjectionMatrix; Matrix ViewProjectionMatrix;
GlobalSignDistanceFieldPass::ConstantsData GlobalSDF; GlobalSignDistanceFieldPass::ConstantsData GlobalSDF;
GlobalSurfaceAtlasPass::ConstantsData GlobalSurfaceAtlas; GlobalSurfaceAtlasPass::ConstantsData GlobalSurfaceAtlas;
}); });
+15 -21
View File
@@ -5,6 +5,7 @@
#include "./Flax/ReflectionsCommon.hlsl" #include "./Flax/ReflectionsCommon.hlsl"
#include "./Flax/SSR.hlsl" #include "./Flax/SSR.hlsl"
#include "./Flax/GBuffer.hlsl" #include "./Flax/GBuffer.hlsl"
#include "./Flax/Temporal.hlsl"
#include "./Flax/GlobalSignDistanceField.hlsl" #include "./Flax/GlobalSignDistanceField.hlsl"
#include "./Flax/GI/GlobalSurfaceAtlas.hlsl" #include "./Flax/GI/GlobalSurfaceAtlas.hlsl"
@@ -15,34 +16,26 @@
#define SSR_MIX_BLUR 1 #define SSR_MIX_BLUR 1
META_CB_BEGIN(0, Data) META_CB_BEGIN(0, Data)
GBufferData GBuffer; GBufferData GBuffer;
float MaxColorMiplevel; float MaxColorMiplevel;
float TraceSizeMax; float TraceSizeMax;
float MaxTraceSamples; float MaxTraceSamples;
float RoughnessFade; float RoughnessFade;
float2 SSRtexelSize; float2 SSRtexelSize;
float TemporalTime; float TemporalTime;
float BRDFBias; float BRDFBias;
float WorldAntiSelfOcclusionBias; float WorldAntiSelfOcclusionBias;
float EdgeFadeFactor; float EdgeFadeFactor;
float TemporalResponse; float TemporalResponse;
float TemporalScale; float TemporalScale;
float RayTraceStep; float RayTraceStep;
float TemporalEffect; float TemporalEffect;
float Intensity; float Intensity;
float FadeOutDistance; float FadeOutDistance;
float4x4 ViewMatrix; float4x4 ViewMatrix;
float4x4 ViewProjectionMatrix; float4x4 ViewProjectionMatrix;
GlobalSDFData GlobalSDF; GlobalSDFData GlobalSDF;
GlobalSurfaceAtlasData GlobalSurfaceAtlas; GlobalSurfaceAtlasData GlobalSurfaceAtlas;
META_CB_END META_CB_END
DECLARE_GBUFFERDATA_ACCESS(GBuffer) DECLARE_GBUFFERDATA_ACCESS(GBuffer)
@@ -227,15 +220,11 @@ float4 PS_TemporalPass(Quad_VS2PS input) : SV_Target0
// Texture1 - prev frame temporal SSR buffer // Texture1 - prev frame temporal SSR buffer
// Texture2 - motion vectors // Texture2 - motion vectors
// Sample inputss
float2 uv = input.TexCoord; float2 uv = input.TexCoord;
// Sample velocity
float2 velocity = Texture2.SampleLevel(SamplerLinearClamp, uv, 0).xy; float2 velocity = Texture2.SampleLevel(SamplerLinearClamp, uv, 0).xy;
// Prepare
float2 prevUV = uv - velocity; float2 prevUV = uv - velocity;
float4 current = Texture0.SampleLevel(SamplerLinearClamp, uv, 0); float4 current = Texture0.SampleLevel(SamplerLinearClamp, uv, 0);
float4 previous = Texture1.SampleLevel(SamplerLinearClamp, prevUV, 0);
float2 du = float2(SSRtexelSize.x, 0.0); float2 du = float2(SSRtexelSize.x, 0.0);
float2 dv = float2(0.0, SSRtexelSize.y); float2 dv = float2(0.0, SSRtexelSize.y);
@@ -252,18 +241,23 @@ float4 PS_TemporalPass(Quad_VS2PS input) : SV_Target0
float4 currentMin = min(currentTopLeft, min(currentTopCenter, min(currentTopRight, min(currentMiddleLeft, min(currentMiddleCenter, min(currentMiddleRight, min(currentBottomLeft, min(currentBottomCenter, currentBottomRight)))))))); float4 currentMin = min(currentTopLeft, min(currentTopCenter, min(currentTopRight, min(currentMiddleLeft, min(currentMiddleCenter, min(currentMiddleRight, min(currentBottomLeft, min(currentBottomCenter, currentBottomRight))))))));
float4 currentMax = max(currentTopLeft, max(currentTopCenter, max(currentTopRight, max(currentMiddleLeft, max(currentMiddleCenter, max(currentMiddleRight, max(currentBottomLeft, max(currentBottomCenter, currentBottomRight)))))))); float4 currentMax = max(currentTopLeft, max(currentTopCenter, max(currentTopRight, max(currentMiddleLeft, max(currentMiddleCenter, max(currentMiddleRight, max(currentBottomLeft, max(currentBottomCenter, currentBottomRight))))))));
float4 currentSum = currentTopLeft + currentTopCenter + currentTopRight + currentMiddleLeft + currentMiddleCenter + currentMiddleRight + currentBottomLeft + currentBottomCenter + currentBottomRight;
float4 currentAvg = currentSum / 9.0;
float scale = TemporalScale; // Sample history by clamp it to the nearby colors range to reduce artifacts
float lumaOffset = abs(Luminance(currentAvg.rgb) - Luminance(current.rgb));
float velocityLength = length(velocity);
float aabbMargin = lerp(4.0, 0.25, saturate(velocityLength * 100.0)) * lumaOffset;
float4 previous = Texture1.SampleLevel(SamplerLinearClamp, prevUV, 0);
previous = ClipToAABB(previous, currentMin - aabbMargin, currentMax + aabbMargin);
//previous = clamp(previous, currentMin, currentMax);
float4 center = (currentMin + currentMax) * 0.5f; // Blend with history sample
currentMin = (currentMin - center) * scale + center; float response = TemporalResponse * (1 - velocityLength * 8);
currentMax = (currentMax - center) * scale + center; current = lerp(current, previous, saturate(response));
previous = clamp(previous, currentMin, currentMax);
current = clamp(current, 0, HDR_CLAMP_MAX); current = clamp(current, 0, HDR_CLAMP_MAX);
float response = TemporalResponse * (1 - length(velocity) * 8); return current;
return lerp(current, previous, saturate(response));
} }
// Pixel Shader for screen space reflections rendering - mix pass // Pixel Shader for screen space reflections rendering - mix pass
+1 -12
View File
@@ -6,6 +6,7 @@
#include "./Flax/Common.hlsl" #include "./Flax/Common.hlsl"
#include "./Flax/GBuffer.hlsl" #include "./Flax/GBuffer.hlsl"
#include "./Flax/Noise.hlsl" #include "./Flax/Noise.hlsl"
#include "./Flax/Temporal.hlsl"
META_CB_BEGIN(0, Data) META_CB_BEGIN(0, Data)
float2 ScreenSizeInv; float2 ScreenSizeInv;
@@ -24,17 +25,6 @@ Texture2D InputHistory : register(t1);
Texture2D MotionVectors : register(t2); Texture2D MotionVectors : register(t2);
Texture2D Depth : register(t3); Texture2D Depth : register(t3);
// [Pedersen, 2016, "Temporal Reprojection Anti-Aliasing in INSIDE"]
float4 ClipToAABB(float4 color, float4 minimum, float4 maximum)
{
float4 center = (maximum + minimum) * 0.5;
float4 extents = (maximum - minimum) * 0.5;
float4 shift = color - center;
float4 absUnit = abs(shift / max(extents, 0.0001));
float maxUnit = max(max(absUnit.x, absUnit.y), absUnit.z);
return maxUnit > 1.0 ? center + (shift / maxUnit) : color;
}
// Pixel Shader for Temporal Anti-Aliasing // Pixel Shader for Temporal Anti-Aliasing
META_PS(true, FEATURE_LEVEL_ES2) META_PS(true, FEATURE_LEVEL_ES2)
float4 PS(Quad_VS2PS input) : SV_Target0 float4 PS(Quad_VS2PS input) : SV_Target0
@@ -105,7 +95,6 @@ float4 PS(Quad_VS2PS input) : SV_Target0
neighborhoodSharp = float4(1, 0, 0, 1); neighborhoodSharp = float4(1, 0, 0, 1);
#endif #endif
color = lerp(color, neighborhoodSharp, saturate(miss)); color = lerp(color, neighborhoodSharp, saturate(miss));
color = clamp(color, 0, HDR_CLAMP_MAX); color = clamp(color, 0, HDR_CLAMP_MAX);
// Apply quantization error to reduce yellowish artifacts due to R11G11B10 format // Apply quantization error to reduce yellowish artifacts due to R11G11B10 format
+19
View File
@@ -0,0 +1,19 @@
// Copyright (c) Wojciech Figat. All rights reserved.
#ifndef __TEMPORAL__
#define __TEMPORAL__
#include "./Flax/Common.hlsl"
// [Pedersen, 2016, "Temporal Reprojection Anti-Aliasing in INSIDE"]
float4 ClipToAABB(float4 color, float4 minimum, float4 maximum)
{
float4 center = (maximum + minimum) * 0.5;
float4 extents = (maximum - minimum) * 0.5;
float4 shift = color - center;
float4 absUnit = abs(shift / max(extents, 0.0001));
float maxUnit = max(max(absUnit.x, absUnit.y), absUnit.z);
return maxUnit > 1.0 ? center + (shift / maxUnit) : color;
}
#endif