BilateralFilter.glsl 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  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 once
  6. #include <shaders/Common.glsl>
  7. struct BilateralSample
  8. {
  9. F32 m_depth;
  10. Vec3 m_position;
  11. Vec3 m_normal;
  12. F32 m_roughness;
  13. };
  14. struct BilateralConfig
  15. {
  16. F32 m_depthWeight;
  17. F32 m_normalWeight;
  18. F32 m_planeWeight;
  19. F32 m_roughnessWeight;
  20. };
  21. // https://cs.dartmouth.edu/~wjarosz/publications/mara17towards.html
  22. F32 calculateBilateralWeight(BilateralSample center, BilateralSample tap, BilateralConfig config)
  23. {
  24. F32 depthWeight = 1.0;
  25. F32 normalWeight = 1.0;
  26. F32 planeWeight = 1.0;
  27. F32 glossyWeight = 1.0;
  28. if(config.m_depthWeight > 0.0)
  29. {
  30. #if 0
  31. depthWeight = max(0.0, 1.0 - abs(tap.m_depth - center.m_depth) * config.m_depthWeight);
  32. #else
  33. const F32 diff = abs(tap.m_depth - center.m_depth);
  34. depthWeight = sqrt(1.0 / (EPSILON + diff)) * config.m_depthWeight;
  35. #endif
  36. }
  37. if(config.m_normalWeight > 0.0)
  38. {
  39. F32 normalCloseness = dot(tap.m_normal, center.m_normal);
  40. normalCloseness = normalCloseness * normalCloseness;
  41. normalCloseness = normalCloseness * normalCloseness;
  42. const F32 normalError = (1.0 - normalCloseness);
  43. normalWeight = max((1.0 - normalError * config.m_normalWeight), 0.0);
  44. }
  45. if(config.m_planeWeight > 0.0)
  46. {
  47. const F32 lowDistanceThreshold2 = 0.001;
  48. // Change in position in camera space
  49. Vec3 dq = center.m_position - tap.m_position;
  50. // How far away is this point from the original sample in camera space? (Max value is unbounded)
  51. const F32 distance2 = dot(dq, dq);
  52. // How far off the expected plane (on the perpendicular) is this point? Max value is unbounded.
  53. const F32 planeError = max(abs(dot(dq, tap.m_normal)), abs(dot(dq, center.m_normal)));
  54. planeWeight = (distance2 < lowDistanceThreshold2)
  55. ? 1.0
  56. : pow(max(0.0, 1.0 - 2.0 * config.m_planeWeight * planeError / sqrt(distance2)), 2.0);
  57. }
  58. if(config.m_roughnessWeight > 0.0)
  59. {
  60. const F32 gDiff = abs(tap.m_roughness - center.m_roughness) * 10.0;
  61. glossyWeight = max(0.0, 1.0 - (gDiff * config.m_roughnessWeight));
  62. }
  63. return depthWeight * normalWeight * planeWeight * glossyWeight;
  64. }