Functions.glsl 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. // Copyright (C) 2009-2017, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #ifndef ANKI_SHADERS_FUNCTIONS_GLSL
  6. #define ANKI_SHADERS_FUNCTIONS_GLSL
  7. #include "shaders/Common.glsl"
  8. vec3 dither(in vec3 col, in float C)
  9. {
  10. vec3 vDither = vec3(dot(vec2(171.0, 231.0), gl_FragCoord.xy));
  11. vDither.rgb = fract(vDither.rgb / vec3(103.0, 71.0, 97.0));
  12. col = col * (255.0 / C) + vDither.rgb;
  13. col = floor(col) / 255.0;
  14. col *= C;
  15. return col;
  16. }
  17. float dither(in float col, in float C)
  18. {
  19. float vDither = dot(vec2(171.0, 231.0), gl_FragCoord.xy);
  20. vDither = fract(vDither / 103.0);
  21. col = col * (255.0 / C) + vDither;
  22. col = floor(col) / 255.0;
  23. col *= C;
  24. return col;
  25. }
  26. // Convert to linear depth
  27. float linearizeDepth(in float depth, in float zNear, in float zFar)
  28. {
  29. return (2.0 * zNear) / (zFar + zNear - depth * (zFar - zNear));
  30. }
  31. // This is the optimal linearizeDepth where a=(f+n)/2n and b=(n-f)/2n
  32. float linearizeDepthOptimal(in float depth, in float a, in float b)
  33. {
  34. return 1.0 / (a + depth * b);
  35. }
  36. // Project a vector by knowing only the non zero values of a perspective matrix
  37. vec4 projectPerspective(in vec4 vec, in float m00, in float m11, in float m22, in float m23)
  38. {
  39. vec4 o;
  40. o.x = vec.x * m00;
  41. o.y = vec.y * m11;
  42. o.z = vec.z * m22 + vec.w * m23;
  43. o.w = -vec.z;
  44. return o;
  45. }
  46. // Stolen from shadertoy.com/view/4tyGDD
  47. vec4 textureCatmullRom4Samples(sampler2D tex, vec2 uv, vec2 texSize)
  48. {
  49. vec2 halff = 2.0 * fract(0.5 * uv * texSize - 0.25) - 1.0;
  50. vec2 f = fract(halff);
  51. vec2 sum0 = (2.0 * f - 3.5) * f + 0.5;
  52. vec2 sum1 = (2.0 * f - 2.5) * f - 0.5;
  53. vec4 w = vec4(f * sum0 + 1.0, f * sum1);
  54. vec4 pos = vec4((((-2.0 * f + 3.0) * f + 0.5) * f - 1.5) * f / (w.xy * texSize) + uv,
  55. (((-2.0 * f + 5.0) * f - 2.5) * f - 0.5) / (sum1 * texSize) + uv);
  56. w.xz *= halff.x * halff.y > 0.0 ? 1.0 : -1.0;
  57. return (texture(tex, pos.xy) * w.x + texture(tex, pos.zy) * w.z) * w.y
  58. + (texture(tex, pos.xw) * w.x + texture(tex, pos.zw) * w.z) * w.w;
  59. }
  60. float rand(vec2 n)
  61. {
  62. return 0.5 + 0.5 * fract(sin(dot(n, vec2(12.9898, 78.233))) * 43758.5453);
  63. }
  64. vec3 nearestDepthUpscale(vec2 uv, sampler2D depthFull, sampler2D depthHalf, sampler2D colorTex, float depthThreshold)
  65. {
  66. float fullDepth = texture(depthFull, uv).r;
  67. vec4 halfDepths = textureGather(depthHalf, uv, 0);
  68. vec4 diffs = abs(vec4(fullDepth) - halfDepths);
  69. vec3 color;
  70. if(all(lessThan(diffs, vec4(depthThreshold))))
  71. {
  72. // No major discontinuites, sample with bilinear
  73. color = texture(colorTex, uv).rgb;
  74. }
  75. else
  76. {
  77. // Some discontinuites, need to use the newUv
  78. vec4 r = textureGather(colorTex, uv, 0);
  79. vec4 g = textureGather(colorTex, uv, 1);
  80. vec4 b = textureGather(colorTex, uv, 2);
  81. float minDiff = diffs.x;
  82. uint comp = 0;
  83. if(diffs.y < minDiff)
  84. {
  85. comp = 1;
  86. minDiff = diffs.y;
  87. }
  88. if(diffs.z < minDiff)
  89. {
  90. comp = 2;
  91. minDiff = diffs.z;
  92. }
  93. if(diffs.w < minDiff)
  94. {
  95. comp = 3;
  96. }
  97. color = vec3(r[comp], g[comp], b[comp]);
  98. }
  99. return color;
  100. }
  101. float _calcDepthWeight(sampler2D depthLow, vec2 uv, float ref, vec2 linearDepthCf)
  102. {
  103. float d = texture(depthLow, uv).r;
  104. float linearD = linearizeDepthOptimal(d, linearDepthCf.x, linearDepthCf.y);
  105. return 1.0 / (EPSILON + abs(ref - linearD));
  106. }
  107. vec4 _sampleAndWeight(sampler2D depthLow,
  108. sampler2D colorLow,
  109. vec2 lowInvSize,
  110. vec2 uv,
  111. vec2 offset,
  112. float ref,
  113. float weight,
  114. vec2 linearDepthCf,
  115. inout float normalize)
  116. {
  117. uv += offset * lowInvSize;
  118. float dw = _calcDepthWeight(depthLow, uv, ref, linearDepthCf);
  119. vec4 v = texture(colorLow, uv);
  120. normalize += weight * dw;
  121. return v * dw * weight;
  122. }
  123. vec4 bilateralUpsample(
  124. sampler2D depthHigh, sampler2D depthLow, sampler2D colorLow, vec2 lowInvSize, vec2 uv, vec2 linearDepthCf)
  125. {
  126. const vec3 WEIGHTS = vec3(0.25, 0.125, 0.0625);
  127. float depthRef = linearizeDepthOptimal(texture(depthHigh, uv).r, linearDepthCf.x, linearDepthCf.y);
  128. float normalize = 0.0;
  129. vec4 sum = _sampleAndWeight(
  130. depthLow, colorLow, lowInvSize, uv, vec2(0.0, 0.0), depthRef, WEIGHTS.x, linearDepthCf, normalize);
  131. sum += _sampleAndWeight(
  132. depthLow, colorLow, lowInvSize, uv, vec2(-1.0, 0.0), depthRef, WEIGHTS.y, linearDepthCf, normalize);
  133. sum += _sampleAndWeight(
  134. depthLow, colorLow, lowInvSize, uv, vec2(0.0, -1.0), depthRef, WEIGHTS.y, linearDepthCf, normalize);
  135. sum += _sampleAndWeight(
  136. depthLow, colorLow, lowInvSize, uv, vec2(1.0, 0.0), depthRef, WEIGHTS.y, linearDepthCf, normalize);
  137. sum += _sampleAndWeight(
  138. depthLow, colorLow, lowInvSize, uv, vec2(0.0, 1.0), depthRef, WEIGHTS.y, linearDepthCf, normalize);
  139. sum += _sampleAndWeight(
  140. depthLow, colorLow, lowInvSize, uv, vec2(1.0, 1.0), depthRef, WEIGHTS.z, linearDepthCf, normalize);
  141. sum += _sampleAndWeight(
  142. depthLow, colorLow, lowInvSize, uv, vec2(1.0, -1.0), depthRef, WEIGHTS.z, linearDepthCf, normalize);
  143. sum += _sampleAndWeight(
  144. depthLow, colorLow, lowInvSize, uv, vec2(-1.0, 1.0), depthRef, WEIGHTS.z, linearDepthCf, normalize);
  145. sum += _sampleAndWeight(
  146. depthLow, colorLow, lowInvSize, uv, vec2(-1.0, -1.0), depthRef, WEIGHTS.z, linearDepthCf, normalize);
  147. return sum / normalize;
  148. }
  149. vec3 getCubemapDirection(vec2 norm, uint faceIdx)
  150. {
  151. vec3 zDir = vec3((faceIdx <= 1u) ? 1 : 0, (faceIdx & 2u) >> 1u, (faceIdx & 4u) >> 2u);
  152. zDir *= (((faceIdx & 1u) == 1u) ? -1.0 : 1.0);
  153. vec3 yDir = (faceIdx == 2u) ? vec3(0.0, 0.0, 1.0) : (faceIdx == 3u) ? vec3(0.0, 0.0, -1.0) : vec3(0.0, -1.0, 0.0);
  154. vec3 xDir = cross(zDir, yDir);
  155. return normalize(norm.x * xDir + norm.y * yDir + zDir);
  156. }
  157. #endif