SsgiDenoise.ankiprog 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. // Copyright (C) 2009-2021, 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 VARIANT 0 1 2 3
  6. #pragma anki mutator ORIENTATION 0 1 // 0: VERTICAL, 1: HORIZONTAL
  7. #pragma anki mutator SAMPLE_COUNT 3 5 7 9 11 13 15
  8. ANKI_SPECIALIZATION_CONSTANT_UVEC2(IN_TEXTURE_SIZE, 0u);
  9. #pragma anki start comp
  10. #include <AnKi/Shaders/BilateralFilter.glsl>
  11. #include <AnKi/Shaders/Pack.glsl>
  12. #if SAMPLE_COUNT < 3
  13. # error See file
  14. #endif
  15. const UVec2 WORKGROUP_SIZE = UVec2(8u, 8u);
  16. layout(local_size_x = WORKGROUP_SIZE.x, local_size_y = WORKGROUP_SIZE.y, local_size_z = 1) in;
  17. layout(set = 0, binding = 0) uniform sampler u_linearAnyClampSampler;
  18. layout(set = 0, binding = 1) uniform texture2D u_inTex;
  19. layout(set = 0, binding = 2) uniform texture2D u_depthTex;
  20. layout(set = 0, binding = 3) uniform texture2D u_gbuffer2Tex;
  21. layout(set = 0, binding = 4) writeonly uniform image2D u_outImg;
  22. layout(std140, push_constant, row_major) uniform b_pc
  23. {
  24. Mat4 u_invViewProjMat;
  25. };
  26. Vec3 unproject(Vec2 ndc, F32 depth)
  27. {
  28. const Vec4 worldPos4 = u_invViewProjMat * Vec4(ndc, depth, 1.0);
  29. const Vec3 worldPos = worldPos4.xyz / worldPos4.w;
  30. return worldPos;
  31. }
  32. F32 readDepth(Vec2 uv)
  33. {
  34. return textureLod(u_depthTex, u_linearAnyClampSampler, uv, 0.0).r;
  35. }
  36. Vec3 readNormal(Vec2 uv)
  37. {
  38. return readNormalFromGBuffer(u_gbuffer2Tex, u_linearAnyClampSampler, uv);
  39. }
  40. void sampleTex(Vec2 colorUv, Vec2 fullUv, Vec3 positionCenter, Vec3 normalCenter, inout Vec3 col, inout F32 weight)
  41. {
  42. const Vec3 color = textureLod(u_inTex, u_linearAnyClampSampler, colorUv, 0.0).rgb;
  43. const F32 depthTap = readDepth(fullUv);
  44. const Vec3 positionTap = unproject(UV_TO_NDC(fullUv), depthTap);
  45. const Vec3 normalTap = readNormal(fullUv);
  46. F32 w = calculateBilateralWeightPlane(positionCenter, normalCenter, positionTap, normalTap, 0.5);
  47. w *= calculateBilateralWeightNormal(normalCenter, normalTap, 0.5);
  48. col += color * w;
  49. weight += w;
  50. }
  51. void main()
  52. {
  53. // Set UVs
  54. ANKI_BRANCH if(gl_GlobalInvocationID.x >= IN_TEXTURE_SIZE.x || gl_GlobalInvocationID.y >= IN_TEXTURE_SIZE.y)
  55. {
  56. // Out of bounds
  57. return;
  58. }
  59. const Vec2 inUv = (Vec2(gl_GlobalInvocationID.xy) + 0.5) / Vec2(IN_TEXTURE_SIZE);
  60. #if VARIANT == 0
  61. const UVec2 depthReadOffset = UVec2(0, 0);
  62. #elif VARIANT == 1
  63. const UVec2 depthReadOffset = UVec2(1, 0);
  64. #elif VARIANT == 2
  65. const UVec2 depthReadOffset = UVec2(1, 1);
  66. #else
  67. const UVec2 depthReadOffset = UVec2(1, 0);
  68. #endif
  69. const Vec2 depthUv = (Vec2(gl_GlobalInvocationID.xy * 2u + depthReadOffset) + 0.5) / Vec2(IN_TEXTURE_SIZE * 2u);
  70. const Vec2 IN_TEXEL_SIZE = 1.0 / Vec2(IN_TEXTURE_SIZE);
  71. const Vec2 DEPTH_TEXEL_SIZE = 1.0 / Vec2(IN_TEXTURE_SIZE * 2u);
  72. // Reference
  73. Vec3 color = textureLod(u_inTex, u_linearAnyClampSampler, inUv, 0.0).rgb;
  74. F32 weight = 1.0;
  75. const F32 depthCenter = readDepth(depthUv);
  76. const Vec3 positionCenter = unproject(UV_TO_NDC(depthUv), depthCenter);
  77. const Vec3 normalCenter = readNormal(depthUv);
  78. #if ORIENTATION == 1
  79. # define X_OR_Y x
  80. #else
  81. # define X_OR_Y y
  82. #endif
  83. Vec2 inUvOffset = Vec2(0.0);
  84. inUvOffset.X_OR_Y = 1.0 * IN_TEXEL_SIZE.X_OR_Y;
  85. Vec2 depthUvOffset = Vec2(0.0);
  86. depthUvOffset.X_OR_Y = 2.0 * DEPTH_TEXEL_SIZE.X_OR_Y;
  87. ANKI_UNROLL for(U32 i = 0u; i < (U32(SAMPLE_COUNT) - 1u) / 2u; ++i)
  88. {
  89. sampleTex(inUv + inUvOffset, depthUv + depthUvOffset, positionCenter, normalCenter, color, weight);
  90. sampleTex(inUv - inUvOffset, depthUv - depthUvOffset, positionCenter, normalCenter, color, weight);
  91. inUvOffset.X_OR_Y += IN_TEXEL_SIZE.X_OR_Y;
  92. depthUvOffset.X_OR_Y += 2.0 * DEPTH_TEXEL_SIZE.X_OR_Y;
  93. }
  94. color /= weight;
  95. // Write value
  96. imageStore(u_outImg, IVec2(gl_GlobalInvocationID.xy), Vec4(color, 0.0));
  97. }
  98. #pragma anki end