TonemappingFunctions.glsl 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. // Copyright (C) 2009-2022, 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 <AnKi/Shaders/Common.glsl>
  7. // A tick to compute log of base 10
  8. ANKI_RP F32 log10(ANKI_RP F32 x)
  9. {
  10. return log(x) / log(10.0);
  11. }
  12. ANKI_RP F32 computeLuminance(ANKI_RP Vec3 color)
  13. {
  14. return max(dot(Vec3(0.30, 0.59, 0.11), color), EPSILON_RP);
  15. }
  16. ANKI_RP F32 computeExposure(ANKI_RP F32 avgLum, ANKI_RP F32 threshold)
  17. {
  18. const ANKI_RP F32 keyValue = 1.03 - (2.0 / (2.0 + log10(avgLum + 1.0)));
  19. const ANKI_RP F32 linearExposure = (keyValue / avgLum);
  20. ANKI_RP F32 exposure = log2(linearExposure);
  21. exposure -= threshold;
  22. return exp2(exposure);
  23. }
  24. ANKI_RP Vec3 computeExposedColor(ANKI_RP Vec3 color, ANKI_RP F32 avgLum, ANKI_RP F32 threshold)
  25. {
  26. return computeExposure(avgLum, threshold) * color;
  27. }
  28. // Reinhard operator
  29. ANKI_RP Vec3 tonemapReinhard(ANKI_RP Vec3 color, ANKI_RP F32 saturation)
  30. {
  31. const ANKI_RP F32 lum = computeLuminance(color);
  32. const ANKI_RP F32 toneMappedLuminance = lum / (lum + 1.0);
  33. return toneMappedLuminance * pow(color / lum, Vec3(saturation));
  34. }
  35. // Uncharted 2 operator
  36. ANKI_RP Vec3 tonemapUncharted2(ANKI_RP Vec3 color)
  37. {
  38. const F32 A = 0.15;
  39. const F32 B = 0.50;
  40. const F32 C = 0.10;
  41. const F32 D = 0.20;
  42. const F32 E = 0.02;
  43. const F32 F = 0.30;
  44. return ((color * (A * color + C * B) + D * E) / (color * (A * color + B) + D * F)) - E / F;
  45. }
  46. ANKI_RP Vec3 tonemapACESFilm(ANKI_RP Vec3 x)
  47. {
  48. const ANKI_RP F32 a = 2.51;
  49. const ANKI_RP F32 b = 0.03;
  50. const ANKI_RP F32 c = 2.43;
  51. const ANKI_RP F32 d = 0.59;
  52. const ANKI_RP F32 e = 0.14;
  53. return saturate((x * (a * x + b)) / (x * (c * x + d) + e));
  54. }
  55. ANKI_RP Vec3 invertTonemapACESFilm(ANKI_RP Vec3 x)
  56. {
  57. const ANKI_RP F32 a = 2.51;
  58. const ANKI_RP F32 b = 0.03;
  59. const ANKI_RP F32 c = 2.43;
  60. const ANKI_RP F32 d = 0.59;
  61. const ANKI_RP F32 e = 0.14;
  62. return (-0.59 * x + 0.03 - sqrt(-1.0127 * x * x + 1.3702 * x + 0.0009)) / (2.0 * (2.43 * x - 2.51));
  63. }
  64. ANKI_RP Vec3 tonemap(ANKI_RP Vec3 color, ANKI_RP F32 exposure)
  65. {
  66. color *= exposure;
  67. return tonemapACESFilm(color);
  68. }
  69. ANKI_RP Vec3 invertTonemap(ANKI_RP Vec3 color, ANKI_RP F32 exposure)
  70. {
  71. color = invertTonemapACESFilm(color);
  72. color /= max(EPSILON, exposure);
  73. return color;
  74. }
  75. ANKI_RP Vec3 tonemap(ANKI_RP Vec3 color, ANKI_RP F32 avgLum, ANKI_RP F32 threshold)
  76. {
  77. const ANKI_RP F32 exposure = computeExposure(avgLum, threshold);
  78. return tonemap(color, exposure);
  79. }
  80. // https://graphicrants.blogspot.com/2013/12/tone-mapping.html
  81. Vec3 reinhardTonemap(Vec3 colour)
  82. {
  83. // rgb / (1 + max(rgb))
  84. return colour / (1.0 + max(max(colour.r, colour.g), colour.b));
  85. }
  86. F32 reinhardTonemap(F32 value)
  87. {
  88. return value / (1.0 + value);
  89. }
  90. F16 reinhardTonemap(F16 value)
  91. {
  92. return value / (1.0hf + value);
  93. }
  94. Vec3 invertReinhardTonemap(Vec3 colour)
  95. {
  96. // rgb / (1 - max(rgb))
  97. return colour / max(1.0 / 32768.0, 1.0 - max(max(colour.r, colour.g), colour.b));
  98. }
  99. HVec3 invertReinhardTonemap(HVec3 colour)
  100. {
  101. // rgb / (1 - max(rgb))
  102. return colour / max(F16(1.0 / 32768.0), 1.0hf - max(max(colour.r, colour.g), colour.b));
  103. }