DepthAwareBlur.ankiprog 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  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 mutator ORIENTATION 0 1 2 // 0: VERTICAL, 1: HORIZONTAL, 2: BOX
  6. #pragma anki mutator SAMPLE_COUNT 3 5 7 9 11 13 15
  7. #pragma anki mutator COLOR_COMPONENTS 4 3 1
  8. #pragma anki technique vert pixel comp
  9. #include <AnKi/Shaders/QuadVert.hlsl>
  10. #include <AnKi/Shaders/Common.hlsl>
  11. #include <AnKi/Shaders/BilateralFilter.hlsl>
  12. #if ANKI_COMPUTE_SHADER || ANKI_PIXEL_SHADER
  13. # define ORIENTATION_VERTICAL 0
  14. # define ORIENTATION_HORIZONTAL 1
  15. # define ORIENTATION_BOX 2
  16. # if SAMPLE_COUNT < 3
  17. # error See file
  18. # endif
  19. // Define some macros depending on the number of components
  20. # if COLOR_COMPONENTS == 4
  21. typedef Vec4 ColorType;
  22. # elif COLOR_COMPONENTS == 3
  23. typedef Vec3 ColorType;
  24. # elif COLOR_COMPONENTS == 1
  25. typedef F32 ColorType;
  26. # else
  27. # error See file
  28. # endif
  29. SamplerState g_linearAnyClampSampler : register(s0);
  30. Texture2D<ColorType> g_inTex : register(t0);
  31. Texture2D<Vec4> g_depthTex : register(t1);
  32. # if ANKI_COMPUTE_SHADER
  33. # define THREADGROUP_SQRT_SIZE 8
  34. RWTexture2D<ColorType> g_outImg : register(u0);
  35. # endif
  36. F32 computeDepthWeight(F32 refDepth, F32 depth)
  37. {
  38. const F32 diff = abs(refDepth - depth);
  39. const F32 weight = 1.0 / (kEpsilonF32 + diff);
  40. return sqrt(weight);
  41. }
  42. F32 readDepth(Vec2 uv)
  43. {
  44. return g_depthTex.SampleLevel(g_linearAnyClampSampler, uv, 0.0).r;
  45. }
  46. void sampleTex(Vec2 uv, F32 refDepth, inout ColorType col, inout F32 weight)
  47. {
  48. const ColorType color = g_inTex.SampleLevel(g_linearAnyClampSampler, uv, 0.0);
  49. const F32 w = calculateBilateralWeightDepth(refDepth, readDepth(uv), 1.0f);
  50. col += color * w;
  51. weight += w;
  52. }
  53. # if ANKI_COMPUTE_SHADER
  54. [numthreads(THREADGROUP_SQRT_SIZE, THREADGROUP_SQRT_SIZE, 1)] void main(UVec2 svDispatchThreadId : SV_DISPATCHTHREADID)
  55. # else
  56. ColorType main(VertOut input) : SV_TARGET0
  57. # endif
  58. {
  59. UVec2 textureSize;
  60. U32 mipCount;
  61. g_inTex.GetDimensions(0, textureSize.x, textureSize.y, mipCount);
  62. // Set UVs
  63. # if ANKI_COMPUTE_SHADER
  64. const Vec2 uv = (Vec2(svDispatchThreadId) + 0.5) / Vec2(textureSize);
  65. # else
  66. const Vec2 uv = input.m_uv;
  67. # endif
  68. const Vec2 texelSize = 1.0 / Vec2(textureSize);
  69. // Sample
  70. ColorType color = g_inTex.SampleLevel(g_linearAnyClampSampler, uv, 0.0);
  71. const F32 refDepth = readDepth(uv);
  72. F32 weight = 1.0;
  73. # if ORIENTATION != ORIENTATION_BOX
  74. // Do seperable
  75. # if ORIENTATION == ORIENTATION_HORIZONTAL
  76. # define X_OR_Y x
  77. # else
  78. # define X_OR_Y y
  79. # endif
  80. Vec2 uvOffset = 0.0f;
  81. uvOffset.X_OR_Y = 1.0f * texelSize.X_OR_Y;
  82. [unroll] for(U32 i = 0u; i < (SAMPLE_COUNT - 1u) / 2u; ++i)
  83. {
  84. sampleTex(uv + uvOffset, refDepth, color, weight);
  85. sampleTex(uv - uvOffset, refDepth, color, weight);
  86. uvOffset.X_OR_Y += 1.0f * texelSize.X_OR_Y;
  87. }
  88. # else
  89. // Do box
  90. const Vec2 offset = 1.5 * texelSize;
  91. sampleTex(uv + Vec2(+offset.x, +offset.y), refDepth, color, weight);
  92. sampleTex(uv + Vec2(+offset.x, -offset.y), refDepth, color, weight);
  93. sampleTex(uv + Vec2(-offset.x, +offset.y), refDepth, color, weight);
  94. sampleTex(uv + Vec2(-offset.x, -offset.y), refDepth, color, weight);
  95. sampleTex(uv + Vec2(offset.x, 0.0), refDepth, color, weight);
  96. sampleTex(uv + Vec2(0.0, offset.y), refDepth, color, weight);
  97. sampleTex(uv + Vec2(-offset.x, 0.0), refDepth, color, weight);
  98. sampleTex(uv + Vec2(0.0, -offset.y), refDepth, color, weight);
  99. # endif
  100. color /= weight;
  101. // Write value
  102. # if ANKI_COMPUTE_SHADER
  103. g_outImg[svDispatchThreadId] = color;
  104. # else
  105. return color;
  106. # endif
  107. }
  108. #endif // ANKI_COMPUTE_SHADER || ANKI_PIXEL_SHADER