RtShadowsSvgfVariance.ankiprog 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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. #pragma anki technique comp
  6. #include <AnKi/Shaders/RtShadows.hlsl>
  7. #include <AnKi/Shaders/BilateralFilter.hlsl>
  8. #include <AnKi/Shaders/Functions.hlsl>
  9. SamplerState g_linearAnyClampSampler : register(s0);
  10. Texture2D<Vec4> g_shadowsTex : register(t0);
  11. Texture2D<Vec4> g_momentsTex : register(t1);
  12. Texture2D<Vec4> g_historyLengthTex : register(t2);
  13. Texture2D<Vec4> g_depthTex : register(t3);
  14. RWTexture2D<Vec4> g_shadowUav : register(u0);
  15. RWTexture2D<Vec4> g_varianceUav : register(u1);
  16. ANKI_FAST_CONSTANTS(Mat4, g_invProjMat)
  17. constexpr I32 kConvolutionRadius = 1;
  18. Vec3 toViewspace(Vec2 uv, F32 depth)
  19. {
  20. const Vec4 pos4 = mul(g_invProjMat, Vec4(uvToNdc(uv), depth, 1.0));
  21. const Vec3 pos = pos4.xyz / pos4.w;
  22. return pos;
  23. }
  24. [numthreads(8, 8, 1)] void main(UVec2 svDispatchThreadId : SV_DISPATCHTHREADID)
  25. {
  26. Vec2 shadowUavSize;
  27. g_shadowUav.GetDimensions(shadowUavSize.x, shadowUavSize.y);
  28. if(any(Vec2(svDispatchThreadId) >= shadowUavSize))
  29. {
  30. return;
  31. }
  32. const Vec2 uv = (Vec2(svDispatchThreadId) + 0.5) / shadowUavSize;
  33. const F32 depth = g_depthTex.SampleLevel(g_linearAnyClampSampler, uv, 0.0).r;
  34. if(depth == 1.0)
  35. {
  36. // Sky
  37. g_shadowUav[svDispatchThreadId] = 0.0f;
  38. g_varianceUav[svDispatchThreadId] = 0.0f;
  39. return;
  40. }
  41. const F32 historyLength = g_historyLengthTex.SampleLevel(g_linearAnyClampSampler, uv, 0.0).r * kRtShadowsMaxHistoryLength;
  42. F32 outShadowFactor;
  43. F32 outVariance;
  44. if(historyLength < 4.0)
  45. {
  46. // It's been stable less than 4 frames, need to do some work
  47. const Vec2 texelSize = 1.0 / shadowUavSize;
  48. // Set the reference sample
  49. const F32 depthCenter = depth;
  50. const Vec3 positionCenter = toViewspace(uv, depthCenter);
  51. // Init the sums
  52. Vec2 sumMoments = 0.0f;
  53. F32 sumWeight = kEpsilonF32;
  54. F32 sumShadowFactor = 0.0f;
  55. // Convolve
  56. for(I32 offsetx = -kConvolutionRadius; offsetx <= kConvolutionRadius; offsetx++)
  57. {
  58. for(I32 offsety = -kConvolutionRadius; offsety <= kConvolutionRadius; offsety++)
  59. {
  60. const Vec2 sampleUv = uv + Vec2(offsetx, offsety) * texelSize;
  61. // Set the current sample
  62. const F32 depthTap = g_depthTex.SampleLevel(g_linearAnyClampSampler, sampleUv, 0.0).r;
  63. const Vec3 positionTap = toViewspace(sampleUv, depthTap);
  64. // Do bilateral
  65. const F32 w = calculateBilateralWeightViewspacePosition(positionCenter, positionTap, 0.5);
  66. // Sum
  67. const Vec2 moments = g_momentsTex.SampleLevel(g_linearAnyClampSampler, sampleUv, 0.0).xy;
  68. sumMoments += moments * w;
  69. const F32 localShadowFactor = g_shadowsTex.SampleLevel(g_linearAnyClampSampler, sampleUv, 0.0).r;
  70. sumShadowFactor += localShadowFactor * w;
  71. sumWeight += w;
  72. }
  73. }
  74. sumShadowFactor /= sumWeight;
  75. sumMoments /= sumWeight;
  76. outVariance = max(0.0, sumMoments.y - sumMoments.x * sumMoments.x);
  77. outShadowFactor = sumShadowFactor;
  78. // Give the variance a boost for the first frames
  79. outVariance *= 4.0 / (historyLength * kRtShadowsMaxHistoryLength);
  80. }
  81. else
  82. {
  83. // Stable for more that 4 frames, passthrough
  84. outShadowFactor = g_shadowsTex.SampleLevel(g_linearAnyClampSampler, uv, 0.0).r;
  85. const Vec2 moments = g_momentsTex.SampleLevel(g_linearAnyClampSampler, uv, 0.0).xy;
  86. outVariance = max(0.0, moments.y - moments.x * moments.x);
  87. }
  88. // Store
  89. g_shadowUav[svDispatchThreadId] = outShadowFactor;
  90. g_varianceUav[svDispatchThreadId] = Vec4(outVariance, 0.0, 0.0, 0.0);
  91. }