HistoryLength.ankiprog 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. // Calculates the disocclusion length. The longer the length the better the pixel is for temporal accumulation
  6. #pragma anki technique comp vert pixel
  7. #include <AnKi/Shaders/Functions.hlsl>
  8. #include <AnKi/Shaders/Include/MiscRendererTypes.h>
  9. #include <AnKi/Shaders/QuadVert.hlsl>
  10. constexpr F32 kZDistanceLimit = 0.05; // In meters
  11. Texture2D<F32> g_depthTex : register(t0);
  12. Texture2D<F32> g_historyDepthTex : register(t1);
  13. Texture2D<Vec2> g_motionVectorsTex : register(t2);
  14. Texture2D<F32> g_prevHistoryLengthTex : register(t3);
  15. RWTexture2D<F32> g_historyLengthTex : register(u0);
  16. ConstantBuffer<GlobalRendererConstants> g_globalRendererConsts : register(b0);
  17. SamplerState g_linearAnyClampSampler : register(s0);
  18. Vec3 unproject(Vec2 ndc, F32 d)
  19. {
  20. return cheapPerspectiveUnprojection(g_globalRendererConsts.m_matrices.m_unprojectionParameters, ndc, d);
  21. }
  22. F32 computeLength(Vec2 coord)
  23. {
  24. Vec2 viewport;
  25. g_depthTex.GetDimensions(viewport.x, viewport.y);
  26. const Vec2 uv = (coord + 0.5) / viewport;
  27. const Vec2 ndc = uvToNdc(uv);
  28. const Vec2 historyUv =
  29. uv + TEX(g_motionVectorsTex, coord)
  30. + (g_globalRendererConsts.m_previousMatrices.m_jitterOffsetNdc - g_globalRendererConsts.m_matrices.m_jitterOffsetNdc) / Vec2(2.0, -2.0);
  31. // Compute length
  32. F32 good = 0.0; // Zero means "new" pixel this frame
  33. if(any(historyUv < 0.0) || any(historyUv > 1.0))
  34. {
  35. good = 0.0;
  36. }
  37. else
  38. {
  39. const F32 crntDepth = g_depthTex[coord];
  40. if(crntDepth == 1.0)
  41. {
  42. return 0.0;
  43. }
  44. const F32 crntViewZ = cheapPerspectiveUnprojection(g_globalRendererConsts.m_matrices.m_unprojectionParameters, ndc, crntDepth).z;
  45. // Read history
  46. const F32 historyDepth = g_historyDepthTex.SampleLevel(g_linearAnyClampSampler, historyUv, 0.0f);
  47. const Vec4 v = mul(g_globalRendererConsts.m_previousMatrices.m_invertedViewProjection, Vec4(uvToNdc(historyUv), historyDepth, 1.0));
  48. const F32 historyViewZ = mul(g_globalRendererConsts.m_matrices.m_view, Vec4(v.xyz / v.w, 1.0)).z;
  49. const F32 dist = abs(crntViewZ - historyViewZ);
  50. const F32 factor = dist / kZDistanceLimit;
  51. good = 1.0 - min(factor, 1.0);
  52. }
  53. F32 len = good;
  54. if(good > 0.1)
  55. {
  56. const F32 prevLen = g_prevHistoryLengthTex.SampleLevel(g_linearAnyClampSampler, historyUv, 0.0f) * kMaxHistoryLength;
  57. len += prevLen;
  58. len = min(len, kMaxHistoryLength);
  59. }
  60. return len / kMaxHistoryLength;
  61. }
  62. #if ANKI_COMPUTE_SHADER
  63. [numthreads(64, 1, 1)] void main(COMPUTE_ARGS)
  64. {
  65. const Vec2 coord = getOptimalDispatchThreadId8x8Amd(svGroupIndex, svGroupId.xy);
  66. Vec2 viewport;
  67. g_historyLengthTex.GetDimensions(viewport.x, viewport.y);
  68. if(any(coord >= viewport))
  69. {
  70. return;
  71. }
  72. const F32 len = computeLength(coord);
  73. TEX(g_historyLengthTex, coord) = len;
  74. }
  75. #endif
  76. #if ANKI_PIXEL_SHADER
  77. F32 main(VertOut input) : SV_TARGET0
  78. {
  79. const Vec2 coord = floor(input.m_svPosition.xy);
  80. return computeLength(coord);
  81. }
  82. #endif