helperFunctions.fx 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. const float PI = 3.1415926535897932384626433832795;
  2. const float LinearEncodePowerApprox = 2.2;
  3. const float GammaEncodePowerApprox = 1.0 / LinearEncodePowerApprox;
  4. const vec3 LuminanceEncodeApprox = vec3(0.2126, 0.7152, 0.0722);
  5. const float Epsilon = 0.0000001;
  6. #define saturate(x) clamp(x, 0.0, 1.0)
  7. #define absEps(x) abs(x) + Epsilon
  8. #define maxEps(x) max(x, Epsilon)
  9. #define saturateEps(x) clamp(x, Epsilon, 1.0)
  10. mat3 transposeMat3(mat3 inMatrix) {
  11. vec3 i0 = inMatrix[0];
  12. vec3 i1 = inMatrix[1];
  13. vec3 i2 = inMatrix[2];
  14. mat3 outMatrix = mat3(
  15. vec3(i0.x, i1.x, i2.x),
  16. vec3(i0.y, i1.y, i2.y),
  17. vec3(i0.z, i1.z, i2.z)
  18. );
  19. return outMatrix;
  20. }
  21. // https://github.com/glslify/glsl-inverse/blob/master/index.glsl
  22. mat3 inverseMat3(mat3 inMatrix) {
  23. float a00 = inMatrix[0][0], a01 = inMatrix[0][1], a02 = inMatrix[0][2];
  24. float a10 = inMatrix[1][0], a11 = inMatrix[1][1], a12 = inMatrix[1][2];
  25. float a20 = inMatrix[2][0], a21 = inMatrix[2][1], a22 = inMatrix[2][2];
  26. float b01 = a22 * a11 - a12 * a21;
  27. float b11 = -a22 * a10 + a12 * a20;
  28. float b21 = a21 * a10 - a11 * a20;
  29. float det = a00 * b01 + a01 * b11 + a02 * b21;
  30. return mat3(b01, (-a22 * a01 + a02 * a21), (a12 * a01 - a02 * a11),
  31. b11, (a22 * a00 - a02 * a20), (-a12 * a00 + a02 * a10),
  32. b21, (-a21 * a00 + a01 * a20), (a11 * a00 - a01 * a10)) / det;
  33. }
  34. vec3 toLinearSpace(vec3 color)
  35. {
  36. return pow(color, vec3(LinearEncodePowerApprox));
  37. }
  38. vec4 toLinearSpace(vec4 color)
  39. {
  40. return vec4(pow(color.rgb, vec3(LinearEncodePowerApprox)), color.a);
  41. }
  42. vec3 toGammaSpace(vec3 color)
  43. {
  44. return pow(color, vec3(GammaEncodePowerApprox));
  45. }
  46. vec4 toGammaSpace(vec4 color)
  47. {
  48. return vec4(pow(color.rgb, vec3(GammaEncodePowerApprox)), color.a);
  49. }
  50. float toGammaSpace(float color)
  51. {
  52. return pow(color, GammaEncodePowerApprox);
  53. }
  54. float square(float value)
  55. {
  56. return value * value;
  57. }
  58. #ifdef WEBGL2
  59. // https://learnopengl.com/PBR/IBL/Specular-IBL
  60. // Hammersley
  61. float radicalInverse_VdC(uint bits)
  62. {
  63. bits = (bits << 16u) | (bits >> 16u);
  64. bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
  65. bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
  66. bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
  67. bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
  68. return float(bits) * 2.3283064365386963e-10; // / 0x100000000
  69. }
  70. vec2 hammersley(uint i, uint N)
  71. {
  72. return vec2(float(i)/float(N), radicalInverse_VdC(i));
  73. }
  74. #else
  75. float vanDerCorpus(uint n, uint base)
  76. {
  77. float invBase = 1.0 / float(base);
  78. float denom = 1.0;
  79. float result = 0.0;
  80. for(uint i = 0u; i < 32u; ++i)
  81. {
  82. if(n > 0u)
  83. {
  84. denom = mod(float(n), 2.0);
  85. result += denom * invBase;
  86. invBase = invBase / 2.0;
  87. n = uint(float(n) / 2.0);
  88. }
  89. }
  90. return result;
  91. }
  92. vec2 hammersley(uint i, uint N)
  93. {
  94. return vec2(float(i)/float(N), vanDerCorpus(i, 2u));
  95. }
  96. #endif
  97. float log4(float x) {
  98. return log2(x) / 2.;
  99. }
  100. float pow5(float value) {
  101. float sq = value * value;
  102. return sq * sq * value;
  103. }
  104. float getLuminance(vec3 color)
  105. {
  106. return clamp(dot(color, LuminanceEncodeApprox), 0., 1.);
  107. }
  108. // https://stackoverflow.com/questions/4200224/random-noise-functions-for-glsl
  109. float getRand(vec2 seed) {
  110. return fract(sin(dot(seed.xy ,vec2(12.9898,78.233))) * 43758.5453);
  111. }
  112. float dither(vec2 seed, float varianceAmount) {
  113. float rand = getRand(seed);
  114. float dither = mix(-varianceAmount/255.0, varianceAmount/255.0, rand);
  115. return dither;
  116. }
  117. // Check if configurable value is needed.
  118. const float rgbdMaxRange = 255.0;
  119. vec4 toRGBD(vec3 color) {
  120. float maxRGB = maxEps(max(color.r, max(color.g, color.b)));
  121. float D = max(rgbdMaxRange / maxRGB, 1.);
  122. D = clamp(floor(D) / 255.0, 0., 1.);
  123. // vec3 rgb = color.rgb * (D * (255.0 / rgbdMaxRange));
  124. vec3 rgb = color.rgb * D;
  125. // Helps with png quantization.
  126. rgb = toGammaSpace(rgb);
  127. return vec4(rgb, D);
  128. }
  129. vec3 fromRGBD(vec4 rgbd) {
  130. // Helps with png quantization.
  131. rgbd.rgb = toLinearSpace(rgbd.rgb);
  132. // return rgbd.rgb * ((rgbdMaxRange / 255.0) / rgbd.a);
  133. return rgbd.rgb / rgbd.a;
  134. }