| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
- // All rights reserved.
- // Code licensed under the BSD License.
- // http://www.anki3d.org/LICENSE
- // Calculates the disocclusion length. The longer the length the better the pixel is for temporal accumulation
- #pragma anki technique comp vert pixel
- #include <AnKi/Shaders/Functions.hlsl>
- #include <AnKi/Shaders/Include/MiscRendererTypes.h>
- #include <AnKi/Shaders/QuadVert.hlsl>
- constexpr F32 kZDistanceLimit = 0.05; // In meters
- Texture2D<F32> g_depthTex : register(t0);
- Texture2D<F32> g_historyDepthTex : register(t1);
- Texture2D<Vec2> g_motionVectorsTex : register(t2);
- Texture2D<F32> g_prevHistoryLengthTex : register(t3);
- RWTexture2D<F32> g_historyLengthTex : register(u0);
- ConstantBuffer<GlobalRendererConstants> g_globalRendererConsts : register(b0);
- SamplerState g_linearAnyClampSampler : register(s0);
- Vec3 unproject(Vec2 ndc, F32 d)
- {
- return cheapPerspectiveUnprojection(g_globalRendererConsts.m_matrices.m_unprojectionParameters, ndc, d);
- }
- F32 computeLength(Vec2 coord)
- {
- Vec2 viewport;
- g_depthTex.GetDimensions(viewport.x, viewport.y);
- const Vec2 uv = (coord + 0.5) / viewport;
- const Vec2 ndc = uvToNdc(uv);
- const Vec2 historyUv =
- uv + TEX(g_motionVectorsTex, coord)
- + (g_globalRendererConsts.m_previousMatrices.m_jitterOffsetNdc - g_globalRendererConsts.m_matrices.m_jitterOffsetNdc) / Vec2(2.0, -2.0);
- // Compute length
- F32 good = 0.0; // Zero means "new" pixel this frame
- if(any(historyUv < 0.0) || any(historyUv > 1.0))
- {
- good = 0.0;
- }
- else
- {
- const F32 crntDepth = g_depthTex[coord];
- if(crntDepth == 1.0)
- {
- return 0.0;
- }
- const F32 crntViewZ = cheapPerspectiveUnprojection(g_globalRendererConsts.m_matrices.m_unprojectionParameters, ndc, crntDepth).z;
- // Read history
- const F32 historyDepth = g_historyDepthTex.SampleLevel(g_linearAnyClampSampler, historyUv, 0.0f);
- const Vec4 v = mul(g_globalRendererConsts.m_previousMatrices.m_invertedViewProjection, Vec4(uvToNdc(historyUv), historyDepth, 1.0));
- const F32 historyViewZ = mul(g_globalRendererConsts.m_matrices.m_view, Vec4(v.xyz / v.w, 1.0)).z;
- const F32 dist = abs(crntViewZ - historyViewZ);
- const F32 factor = dist / kZDistanceLimit;
- good = 1.0 - min(factor, 1.0);
- }
- F32 len = good;
- if(good > 0.1)
- {
- const F32 prevLen = g_prevHistoryLengthTex.SampleLevel(g_linearAnyClampSampler, historyUv, 0.0f) * kMaxHistoryLength;
- len += prevLen;
- len = min(len, kMaxHistoryLength);
- }
- return len / kMaxHistoryLength;
- }
- #if ANKI_COMPUTE_SHADER
- [numthreads(64, 1, 1)] void main(COMPUTE_ARGS)
- {
- const Vec2 coord = getOptimalDispatchThreadId8x8Amd(svGroupIndex, svGroupId.xy);
- Vec2 viewport;
- g_historyLengthTex.GetDimensions(viewport.x, viewport.y);
- if(any(coord >= viewport))
- {
- return;
- }
- const F32 len = computeLength(coord);
- TEX(g_historyLengthTex, coord) = len;
- }
- #endif
- #if ANKI_PIXEL_SHADER
- F32 main(VertOut input) : SV_TARGET0
- {
- const Vec2 coord = floor(input.m_svPosition.xy);
- return computeLength(coord);
- }
- #endif
|