DepthAwareBlur.glsl 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. // Copyright (C) 2009-2020, 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. ANKI_SPECIALIZATION_CONSTANT_UVEC2(TEXTURE_SIZE, 0, UVec2(1));
  9. #include <shaders/Common.glsl>
  10. #if ORIENTATION == 0
  11. # define VERTICAL 1
  12. #elif ORIENTATION == 1
  13. # define HORIZONTAL 1
  14. #else
  15. # define BOX 1
  16. #endif
  17. #if SAMPLE_COUNT < 3
  18. # error See file
  19. #endif
  20. #if defined(ANKI_COMPUTE_SHADER)
  21. # define USE_COMPUTE 1
  22. const UVec2 WORKGROUP_SIZE = UVec2(8u, 8u);
  23. #else
  24. # define USE_COMPUTE 0
  25. #endif
  26. // Define some macros depending on the number of components
  27. #if COLOR_COMPONENTS == 4
  28. # define COL_TYPE Vec4
  29. # define TEX_FETCH rgba
  30. # define TO_VEC4(x_) x_
  31. #elif COLOR_COMPONENTS == 3
  32. # define COL_TYPE Vec3
  33. # define TEX_FETCH rgb
  34. # define TO_VEC4(x_) Vec4(x_, 0.0)
  35. #elif COLOR_COMPONENTS == 1
  36. # define COL_TYPE F32
  37. # define TEX_FETCH r
  38. # define TO_VEC4(x_) Vec4(x_, 0.0, 0.0, 0.0)
  39. #else
  40. # error See file
  41. #endif
  42. layout(set = 0, binding = 0) uniform sampler u_linearAnyClampSampler;
  43. layout(set = 0, binding = 1) uniform texture2D u_inTex;
  44. layout(set = 0, binding = 2) uniform texture2D u_depthTex;
  45. #if USE_COMPUTE
  46. layout(local_size_x = WORKGROUP_SIZE.x, local_size_y = WORKGROUP_SIZE.y, local_size_z = 1) in;
  47. layout(set = 0, binding = 3) writeonly uniform image2D u_outImg;
  48. #else
  49. layout(location = 0) in Vec2 in_uv;
  50. layout(location = 0) out COL_TYPE out_color;
  51. #endif
  52. F32 computeDepthWeight(F32 refDepth, F32 depth)
  53. {
  54. const F32 diff = abs(refDepth - depth);
  55. const F32 weight = 1.0 / (EPSILON + diff);
  56. return sqrt(weight);
  57. }
  58. F32 readDepth(Vec2 uv)
  59. {
  60. return textureLod(u_depthTex, u_linearAnyClampSampler, uv, 0.0).r;
  61. }
  62. void sampleTex(Vec2 uv, F32 refDepth, inout COL_TYPE col, inout F32 weight)
  63. {
  64. const COL_TYPE color = textureLod(u_inTex, u_linearAnyClampSampler, uv, 0.0).TEX_FETCH;
  65. F32 w = computeDepthWeight(refDepth, readDepth(uv));
  66. col += color * w;
  67. weight += w;
  68. }
  69. void main()
  70. {
  71. // Set UVs
  72. #if USE_COMPUTE
  73. ANKI_BRANCH if(gl_GlobalInvocationID.x >= TEXTURE_SIZE.x || gl_GlobalInvocationID.y >= TEXTURE_SIZE.y)
  74. {
  75. // Out of bounds
  76. return;
  77. }
  78. const Vec2 uv = (Vec2(gl_GlobalInvocationID.xy) + 0.5) / Vec2(TEXTURE_SIZE);
  79. #else
  80. const Vec2 uv = in_uv;
  81. #endif
  82. const Vec2 TEXEL_SIZE = 1.0 / Vec2(TEXTURE_SIZE);
  83. // Sample
  84. COL_TYPE color = textureLod(u_inTex, u_linearAnyClampSampler, uv, 0.0).TEX_FETCH;
  85. const F32 refDepth = readDepth(uv);
  86. F32 weight = 1.0;
  87. #if !defined(BOX)
  88. // Do seperable
  89. # if defined(HORIZONTAL)
  90. # define X_OR_Y x
  91. # else
  92. # define X_OR_Y y
  93. # endif
  94. Vec2 uvOffset = Vec2(0.0);
  95. uvOffset.X_OR_Y = 1.5 * TEXEL_SIZE.X_OR_Y;
  96. ANKI_UNROLL for(U32 i = 0u; i < (SAMPLE_COUNT - 1u) / 2u; ++i)
  97. {
  98. sampleTex(uv + uvOffset, refDepth, color, weight);
  99. sampleTex(uv - uvOffset, refDepth, color, weight);
  100. uvOffset.X_OR_Y += 2.0 * TEXEL_SIZE.X_OR_Y;
  101. }
  102. #else
  103. // Do box
  104. const Vec2 OFFSET = 1.5 * TEXEL_SIZE;
  105. sampleTex(uv + Vec2(+OFFSET.x, +OFFSET.y), refDepth, color, weight);
  106. sampleTex(uv + Vec2(+OFFSET.x, -OFFSET.y), refDepth, color, weight);
  107. sampleTex(uv + Vec2(-OFFSET.x, +OFFSET.y), refDepth, color, weight);
  108. sampleTex(uv + Vec2(-OFFSET.x, -OFFSET.y), refDepth, color, weight);
  109. sampleTex(uv + Vec2(OFFSET.x, 0.0), refDepth, color, weight);
  110. sampleTex(uv + Vec2(0.0, OFFSET.y), refDepth, color, weight);
  111. sampleTex(uv + Vec2(-OFFSET.x, 0.0), refDepth, color, weight);
  112. sampleTex(uv + Vec2(0.0, -OFFSET.y), refDepth, color, weight);
  113. #endif
  114. color = color / weight;
  115. // Write value
  116. #if USE_COMPUTE
  117. imageStore(u_outImg, IVec2(gl_GlobalInvocationID.xy), TO_VEC4(color));
  118. #else
  119. out_color = color;
  120. #endif
  121. }