IndirectDiffuseDenoise.ankiprog 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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 BLUR_ORIENTATION 0 1 // 0: in X asix, 1: in Y axis
  6. #pragma anki start comp
  7. #include <AnKi/Shaders/Include/IndirectDiffuseTypes.h>
  8. #include <AnKi/Shaders/PackFunctions.glsl>
  9. #include <AnKi/Shaders/Functions.glsl>
  10. #include <AnKi/Shaders/BilateralFilter.glsl>
  11. const UVec2 WORKGROUP_SIZE = UVec2(8u, 8u);
  12. layout(local_size_x = WORKGROUP_SIZE.x, local_size_y = WORKGROUP_SIZE.y) in;
  13. layout(set = 0, binding = 0) uniform sampler u_linearAnyClampSampler;
  14. layout(set = 0, binding = 1) uniform texture2D u_toDenoiseTex;
  15. layout(set = 0, binding = 2) uniform texture2D u_depthTex;
  16. layout(set = 0, binding = 3) uniform texture2D u_gbuffer2Tex;
  17. layout(set = 0, binding = 4) writeonly uniform image2D u_outImg;
  18. layout(push_constant, std430, row_major) uniform b_pc
  19. {
  20. IndirectDiffuseDenoiseUniforms u_unis;
  21. };
  22. Vec3 unproject(Vec2 ndc, F32 depth)
  23. {
  24. const Vec4 worldPos4 = u_unis.m_invertedViewProjectionJitterMat * Vec4(ndc, depth, 1.0);
  25. const Vec3 worldPos = worldPos4.xyz / worldPos4.w;
  26. return worldPos;
  27. }
  28. void main()
  29. {
  30. if(skipOutOfBoundsInvocations(WORKGROUP_SIZE, u_unis.m_viewportSize))
  31. {
  32. return;
  33. }
  34. const Vec2 uv = (Vec2(gl_GlobalInvocationID.xy) + 0.5) / u_unis.m_viewportSizef;
  35. // Reference
  36. const F32 depthCenter = textureLod(u_depthTex, u_linearAnyClampSampler, uv, 0.0).r;
  37. if(depthCenter == 1.0)
  38. {
  39. imageStore(u_outImg, IVec2(gl_GlobalInvocationID.xy), Vec4(0.0));
  40. return;
  41. }
  42. const Vec3 positionCenter = unproject(UV_TO_NDC(uv), depthCenter);
  43. const Vec3 normalCenter = readNormalFromGBuffer(u_gbuffer2Tex, u_linearAnyClampSampler, uv);
  44. // Sample
  45. F32 weight = EPSILON;
  46. Vec3 color = Vec3(0.0);
  47. for(F32 i = -u_unis.m_sampleCountDiv2; i <= u_unis.m_sampleCountDiv2; i += 1.0)
  48. {
  49. const Vec2 texelSize = 1.0 / u_unis.m_viewportSizef;
  50. #if BLUR_ORIENTATION == 0
  51. const Vec2 sampleUv = Vec2(uv.x + i * texelSize.x, uv.y);
  52. #else
  53. const Vec2 sampleUv = Vec2(uv.x, uv.y + i * texelSize.y);
  54. #endif
  55. const F32 depthTap = textureLod(u_depthTex, u_linearAnyClampSampler, sampleUv, 0.0).r;
  56. const Vec3 positionTap = unproject(UV_TO_NDC(sampleUv), depthTap);
  57. const Vec3 normalTap =
  58. unpackNormalFromGBuffer(textureLod(u_gbuffer2Tex, u_linearAnyClampSampler, sampleUv, 0.0));
  59. F32 w = calculateBilateralWeightPlane(positionCenter, normalCenter, positionTap, normalTap, 1.0);
  60. // w *= gaussianWeight(0.4, abs(F32(i)) / (sampleCount + 1.0));
  61. weight += w;
  62. color += textureLod(u_toDenoiseTex, u_linearAnyClampSampler, sampleUv, 0.0).xyz * w;
  63. }
  64. // Normalize and store
  65. color /= weight;
  66. imageStore(u_outImg, IVec2(gl_GlobalInvocationID.xy), Vec4(color, 0.0));
  67. // imageStore(u_outImg, IVec2(gl_GlobalInvocationID.xy), textureLod(u_toDenoiseTex, u_linearAnyClampSampler, uv,
  68. // 0.0));
  69. }
  70. #pragma anki end