|
@@ -3,106 +3,58 @@
|
|
|
// Code licensed under the BSD License.
|
|
// Code licensed under the BSD License.
|
|
|
// http://www.anki3d.org/LICENSE
|
|
// http://www.anki3d.org/LICENSE
|
|
|
|
|
|
|
|
|
|
+#pragma anki 16bit
|
|
|
|
|
+
|
|
|
#pragma anki mutator VARIANCE_CLIPPING 0 1
|
|
#pragma anki mutator VARIANCE_CLIPPING 0 1
|
|
|
#pragma anki mutator YCBCR 0 1
|
|
#pragma anki mutator YCBCR 0 1
|
|
|
|
|
|
|
|
#pragma anki technique vert pixel comp
|
|
#pragma anki technique vert pixel comp
|
|
|
|
|
|
|
|
#include <AnKi/Shaders/QuadVert.hlsl>
|
|
#include <AnKi/Shaders/QuadVert.hlsl>
|
|
|
-#if ANKI_COMPUTE_SHADER || ANKI_PIXEL_SHADER
|
|
|
|
|
-# include <AnKi/Shaders/Functions.hlsl>
|
|
|
|
|
-# include <AnKi/Shaders/PackFunctions.hlsl>
|
|
|
|
|
-
|
|
|
|
|
-constexpr F32 kVarianceClippingGamma = 2.7f; // Variance clipping paper proposes 1.0
|
|
|
|
|
-constexpr F32 kBlendFactor = 1.0f / 16.0f;
|
|
|
|
|
|
|
+#include <AnKi/Shaders/Functions.hlsl>
|
|
|
|
|
+#include <AnKi/Shaders/PackFunctions.hlsl>
|
|
|
|
|
+#include <AnKi/Shaders/TemporalAA.hlsl>
|
|
|
|
|
|
|
|
SamplerState g_linearAnyClampSampler : register(s0);
|
|
SamplerState g_linearAnyClampSampler : register(s0);
|
|
|
-Texture2D<RVec4> g_inputRt : register(t0);
|
|
|
|
|
-Texture2D<RVec4> g_historyRt : register(t1);
|
|
|
|
|
|
|
+Texture2D<Vec4> g_inputRt : register(t0);
|
|
|
|
|
+Texture2D<Vec4> g_historyRt : register(t1);
|
|
|
Texture2D g_motionVectorsTex : register(t2);
|
|
Texture2D g_motionVectorsTex : register(t2);
|
|
|
|
|
|
|
|
-# if ANKI_COMPUTE_SHADER
|
|
|
|
|
-RWTexture2D<RVec4> g_storageTex : register(u0);
|
|
|
|
|
-# endif
|
|
|
|
|
|
|
+RWTexture2D<Vec4> g_outTex : register(u0);
|
|
|
|
|
|
|
|
-# if YCBCR
|
|
|
|
|
-# define sample(s, uv) rgbToYCbCr(s.SampleLevel(g_linearAnyClampSampler, uv, 0.0).rgb)
|
|
|
|
|
-# define sampleOffset(s, uv, x, y) rgbToYCbCr(s.SampleLevel(g_linearAnyClampSampler, uv, 0.0, IVec2(x, y)).rgb)
|
|
|
|
|
-# else
|
|
|
|
|
-# define sample(s, uv) s.SampleLevel(g_linearAnyClampSampler, uv, 0.0).rgb
|
|
|
|
|
-# define sampleOffset(s, uv, x, y) s.SampleLevel(g_linearAnyClampSampler, uv, 0.0, IVec2(x, y)).rgb
|
|
|
|
|
-# endif
|
|
|
|
|
-
|
|
|
|
|
-# if ANKI_COMPUTE_SHADER
|
|
|
|
|
-[numthreads(8, 8, 1)] void main(UVec3 svDispatchThreadId : SV_DISPATCHTHREADID)
|
|
|
|
|
-# else
|
|
|
|
|
-RVec3 main(VertOut input) : SV_Target0
|
|
|
|
|
-# endif
|
|
|
|
|
|
|
+Vec3 computeTaa(Vec2 coord)
|
|
|
{
|
|
{
|
|
|
-# if ANKI_COMPUTE_SHADER
|
|
|
|
|
- Vec2 outStorageTexSize;
|
|
|
|
|
- g_storageTex.GetDimensions(outStorageTexSize.x, outStorageTexSize.y);
|
|
|
|
|
-
|
|
|
|
|
- const Vec2 uv = (Vec2(svDispatchThreadId.xy) + 0.5) / outStorageTexSize;
|
|
|
|
|
-# else
|
|
|
|
|
- const Vec2 uv = input.m_uv;
|
|
|
|
|
-# endif
|
|
|
|
|
-
|
|
|
|
|
- // Get prev uv coords
|
|
|
|
|
- const Vec2 oldUv = uv + g_motionVectorsTex.SampleLevel(g_linearAnyClampSampler, uv, 0.0).rg;
|
|
|
|
|
-
|
|
|
|
|
- // Read textures
|
|
|
|
|
- Vec3 historyCol = sample(g_historyRt, oldUv);
|
|
|
|
|
- const Vec3 crntCol = sample(g_inputRt, uv);
|
|
|
|
|
-
|
|
|
|
|
- // Remove ghosting by clamping the history color to neighbour's AABB
|
|
|
|
|
- const Vec3 near0 = sampleOffset(g_inputRt, uv, 1, 0);
|
|
|
|
|
- const Vec3 near1 = sampleOffset(g_inputRt, uv, 0, 1);
|
|
|
|
|
- const Vec3 near2 = sampleOffset(g_inputRt, uv, -1, 0);
|
|
|
|
|
- const Vec3 near3 = sampleOffset(g_inputRt, uv, 0, -1);
|
|
|
|
|
|
|
+ Vec2 viewportSize;
|
|
|
|
|
+ g_historyRt.GetDimensions(viewportSize.x, viewportSize.y);
|
|
|
|
|
|
|
|
-# if VARIANCE_CLIPPING
|
|
|
|
|
- const Vec3 m1 = crntCol + near0 + near1 + near2 + near3;
|
|
|
|
|
- const Vec3 m2 = crntCol * crntCol + near0 * near0 + near1 * near1 + near2 * near2 + near3 * near3;
|
|
|
|
|
|
|
+ const Vec2 uv = (Vec2(coord) + 0.5f) / viewportSize;
|
|
|
|
|
+ const Vec2 historyUv = uv + g_motionVectorsTex.SampleLevel(g_linearAnyClampSampler, uv, 0.0).xy;
|
|
|
|
|
|
|
|
- const Vec3 mu = m1 / 5.0;
|
|
|
|
|
- const Vec3 sigma = sqrt(m2 / 5.0 - mu * mu);
|
|
|
|
|
|
|
+ const Vec3 history = g_historyRt.SampleLevel(g_linearAnyClampSampler, historyUv, 0.0);
|
|
|
|
|
|
|
|
- const Vec3 boxMin = mu - kVarianceClippingGamma * sigma;
|
|
|
|
|
- const Vec3 boxMax = mu + kVarianceClippingGamma * sigma;
|
|
|
|
|
-# else
|
|
|
|
|
- const Vec3 boxMin = min(crntCol, min(near0, min(near1, min(near2, near3))));
|
|
|
|
|
- const Vec3 boxMax = max(crntCol, max(near0, max(near1, max(near2, near3))));
|
|
|
|
|
-# endif
|
|
|
|
|
|
|
+ const Vec3 outColor = computeTemporalAA<F32>(g_inputRt, g_linearAnyClampSampler, history, coord);
|
|
|
|
|
|
|
|
- historyCol = clamp(historyCol, boxMin, boxMax);
|
|
|
|
|
|
|
+ return outColor;
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
- // Remove jitter (T. Lottes)
|
|
|
|
|
-# if YCBCR
|
|
|
|
|
- const F32 lum0 = crntCol.r;
|
|
|
|
|
- const F32 lum1 = historyCol.r;
|
|
|
|
|
- const F32 maxLum = boxMax.r;
|
|
|
|
|
-# else
|
|
|
|
|
- const F32 lum0 = computeLuminance(reinhardTonemap(crntCol));
|
|
|
|
|
- const F32 lum1 = computeLuminance(reinhardTonemap(historyCol));
|
|
|
|
|
- const F32 maxLum = 1.0;
|
|
|
|
|
-# endif
|
|
|
|
|
|
|
+#if ANKI_COMPUTE_SHADER
|
|
|
|
|
+[numthreads(64, 1, 1)] void main(COMPUTE_ARGS)
|
|
|
|
|
+{
|
|
|
|
|
+ UVec2 viewportSize;
|
|
|
|
|
+ g_historyRt.GetDimensions(viewportSize.x, viewportSize.y);
|
|
|
|
|
|
|
|
- F32 diff = abs(lum0 - lum1) / max(lum0, max(lum1, maxLum + kEpsilonF32));
|
|
|
|
|
- diff = 1.0 - diff;
|
|
|
|
|
- diff = diff * diff;
|
|
|
|
|
- const F32 feedback = lerp(0.0, kBlendFactor, diff);
|
|
|
|
|
|
|
+ const UVec2 coord = getOptimalDispatchThreadId8x8Amd(svGroupIndex, svGroupId.xy);
|
|
|
|
|
|
|
|
- // Write result
|
|
|
|
|
- Vec3 outColor = lerp(historyCol, crntCol, feedback);
|
|
|
|
|
-# if YCBCR
|
|
|
|
|
- outColor = yCbCrToRgb(outColor);
|
|
|
|
|
-# endif
|
|
|
|
|
|
|
+ if(any(coord >= viewportSize))
|
|
|
|
|
+ {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
-# if ANKI_COMPUTE_SHADER
|
|
|
|
|
- g_storageTex[svDispatchThreadId.xy] = RVec4(outColor, 0.0);
|
|
|
|
|
-# else
|
|
|
|
|
- return outColor;
|
|
|
|
|
-# endif
|
|
|
|
|
|
|
+ TEX(g_outTex, coord) = Vec4(computeTaa(coord), 0.0);
|
|
|
|
|
+}
|
|
|
|
|
+#elif ANKI_PIXEL_SHADER
|
|
|
|
|
+Vec3 main(VertOut input) : SV_Target0
|
|
|
|
|
+{
|
|
|
|
|
+ return computeTaa(floor(input.m_svPosition));
|
|
|
}
|
|
}
|
|
|
-#endif // ANKI_COMPUTE_SHADER || ANKI_PIXEL_SHADER
|
|
|
|
|
|
|
+#endif
|