fs_denoise_spatial_implementation.sh 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*
  2. * Copyright 2021 elven cache. All rights reserved.
  3. * License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE
  4. */
  5. #ifndef FS_DENOISE_SPATIAL_IMPLEMENTATION_SH
  6. #define FS_DENOISE_SPATIAL_IMPLEMENTATION_SH
  7. #include "../common/common.sh"
  8. #include "parameters.sh"
  9. #include "normal_encoding.sh"
  10. SAMPLER2D(s_color, 0); // input color, signal to be denoised
  11. SAMPLER2D(s_normal, 1); // scene's gbuffer normal, used for edge stopping function
  12. SAMPLER2D(s_depth, 2); // scene's depth, used for edge stopping function
  13. void main()
  14. {
  15. vec2 texCoord = v_texcoord0;
  16. // read center pixel
  17. vec4 color = texture2D(s_color, texCoord);
  18. vec3 normal = NormalDecode(texture2D(s_normal, texCoord).xyz); // * 2.0 - 1.0;
  19. float depth = texture2D(s_depth, texCoord).x;
  20. // want depth gradient for edge stopping function
  21. float depthGradient = abs(dFdx(depth)) + abs(dFdy(depth));
  22. float du = u_texCoordStep * u_viewTexel.x;
  23. float dv = u_texCoordStep * u_viewTexel.y;
  24. #if USE_SPATIAL_5X5
  25. float gaussianWeights[5];
  26. gaussianWeights[0] = 1.0/16.0;
  27. gaussianWeights[1] = 4.0/16.0;
  28. gaussianWeights[2] = 6.0/16.0;
  29. gaussianWeights[3] = 4.0/16.0;
  30. gaussianWeights[4] = 1.0/16.0;
  31. float initialWeight = (gaussianWeights[2]*gaussianWeights[2]);
  32. int centerIdx = 2;
  33. vec4 accumulateColor = color * initialWeight;
  34. float accumulateWeight = initialWeight;
  35. for (int yy = 0; yy < 5; ++yy)
  36. {
  37. for (int xx = 0; xx < 5; ++xx)
  38. {
  39. #else
  40. float gaussianWeights[3];
  41. gaussianWeights[0] = 1.0/4.0;
  42. gaussianWeights[1] = 2.0/4.0;
  43. gaussianWeights[2] = 1.0/4.0;
  44. float initialWeight = (gaussianWeights[1]*gaussianWeights[1]);
  45. int centerIdx = 1;
  46. vec4 accumulateColor = color * initialWeight;
  47. float accumulateWeight = initialWeight;
  48. for (int yy = 0; yy < 3; ++yy)
  49. {
  50. for (int xx = 0; xx < 3; ++xx)
  51. {
  52. #endif // USE_SPATIAL_5X5
  53. if ((centerIdx == xx) && (centerIdx == yy)) {
  54. continue;
  55. }
  56. float xOffset = float(xx) - float(centerIdx);
  57. float yOffset = float(yy) - float(centerIdx);
  58. vec2 sampleTexCoord = texCoord;
  59. sampleTexCoord.x += xOffset * du;
  60. sampleTexCoord.y += yOffset * dv;
  61. vec4 sampleColor = texture2D(s_color, sampleTexCoord);
  62. vec3 sampleNormal = NormalDecode(texture2D(s_normal, sampleTexCoord).xyz);
  63. float normalWeight = pow(saturate(dot(normal, sampleNormal)), u_sigmaNormal);
  64. float sampleDepth = texture2D(s_depth, sampleTexCoord).x;
  65. float depthDelta = depth - sampleDepth;
  66. float depthWeight = exp(-abs(depthDelta) / max(1e-5, u_sigmaDepth*u_sigmaDepth));
  67. float weight = depthWeight * normalWeight;
  68. // apply gaussian
  69. weight *= (gaussianWeights[xx]*gaussianWeights[yy]);
  70. accumulateColor += sampleColor * weight;
  71. accumulateWeight += weight;
  72. }
  73. }
  74. accumulateColor /= max(accumulateWeight, 1e-5);
  75. gl_FragColor = accumulateColor;
  76. }
  77. #endif // FS_DENOISE_SPATIAL_IMPLEMENTATION_SH