Tonemapping.glsl 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  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. // A tick to compute log of base 10
  8. F32 log10(F32 x)
  9. {
  10. return log(x) / log(10.0);
  11. }
  12. F32 computeLuminance(Vec3 color)
  13. {
  14. return max(dot(Vec3(0.30, 0.59, 0.11), color), EPSILON);
  15. }
  16. F32 computeExposure(F32 avgLum, F32 threshold)
  17. {
  18. const F32 keyValue = 1.03 - (2.0 / (2.0 + log10(avgLum + 1.0)));
  19. const F32 linearExposure = (keyValue / avgLum);
  20. F32 exposure = log2(linearExposure);
  21. exposure -= threshold;
  22. return exp2(exposure);
  23. }
  24. Vec3 computeExposedColor(Vec3 color, F32 avgLum, F32 threshold)
  25. {
  26. return computeExposure(avgLum, threshold) * color;
  27. }
  28. // Reinhard operator
  29. Vec3 tonemapReinhard(Vec3 color, F32 saturation)
  30. {
  31. const F32 lum = computeLuminance(color);
  32. const F32 toneMappedLuminance = lum / (lum + 1.0);
  33. return toneMappedLuminance * pow(color / lum, Vec3(saturation));
  34. }
  35. // Uncharted 2 operator
  36. Vec3 tonemapUncharted2(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. Vec3 tonemapACESFilm(Vec3 x)
  47. {
  48. const F32 a = 2.51;
  49. const F32 b = 0.03;
  50. const F32 c = 2.43;
  51. const F32 d = 0.59;
  52. const F32 e = 0.14;
  53. return saturate((x * (a * x + b)) / (x * (c * x + d) + e));
  54. }
  55. Vec3 tonemap(Vec3 color, F32 exposure)
  56. {
  57. color *= exposure;
  58. #if 0
  59. const F32 saturation = 1.0;
  60. return tonemapReinhard(color, saturation);
  61. #else
  62. return tonemapACESFilm(color);
  63. #endif
  64. }
  65. Vec3 tonemap(Vec3 color, F32 avgLum, F32 threshold)
  66. {
  67. const F32 exposure = computeExposure(avgLum, threshold);
  68. return tonemap(color, exposure);
  69. }