Ssao.frag.glsl 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. // Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. // SSAO fragment shader
  6. #include "shaders/Common.glsl"
  7. #include "shaders/Pack.glsl"
  8. #include "shaders/Functions.glsl"
  9. #include "shaders/RendererCommonUniforms.glsl"
  10. const vec3 KERNEL[KERNEL_SIZE] = KERNEL_ARRAY; // This will be appended in C++
  11. // Radius in game units
  12. const float RADIUS = 1.1;
  13. // Initial is 1.0 but the bigger it is the more darker the SSAO factor gets
  14. const float DARKNESS_MULTIPLIER = 2.0;
  15. // The algorithm will chose the number of samples depending on the distance
  16. const float MAX_DISTANCE = 40.0;
  17. layout(location = 0) in vec2 in_texCoords;
  18. layout(location = 0) out float out_color;
  19. layout(ANKI_UBO_BINDING(0, 0), std140, row_major) uniform _blk
  20. {
  21. RendererCommonUniforms u_uniforms;
  22. };
  23. layout(ANKI_TEX_BINDING(0, 0)) uniform sampler2D u_mMsDepthRt;
  24. layout(ANKI_TEX_BINDING(0, 1)) uniform sampler2D u_msRt;
  25. layout(ANKI_TEX_BINDING(0, 2)) uniform sampler2D u_noiseMap;
  26. // Get normal
  27. vec3 readNormal(in vec2 uv)
  28. {
  29. vec3 normal;
  30. readNormalFromGBuffer(u_msRt, uv, normal);
  31. return normal;
  32. }
  33. // Read the noise tex
  34. vec3 readRandom(in vec2 uv)
  35. {
  36. const vec2 tmp = vec2(float(WIDTH) / float(NOISE_MAP_SIZE), float(HEIGHT) / float(NOISE_MAP_SIZE));
  37. vec3 noise = texture(u_noiseMap, tmp * uv).xyz;
  38. // return normalize(noise * 2.0 - 1.0);
  39. return noise;
  40. }
  41. // Returns the Z of the position in view space
  42. float readZ(in vec2 uv)
  43. {
  44. float depth = texture(u_mMsDepthRt, uv).r;
  45. float z = u_uniforms.projectionParams.z / (u_uniforms.projectionParams.w + depth);
  46. return z;
  47. }
  48. // Read position in view space
  49. vec3 readPosition(in vec2 uv)
  50. {
  51. vec3 fragPosVspace;
  52. fragPosVspace.z = readZ(uv);
  53. fragPosVspace.xy = (2.0 * uv - 1.0) * u_uniforms.projectionParams.xy * fragPosVspace.z;
  54. return fragPosVspace;
  55. }
  56. void main(void)
  57. {
  58. vec3 origin = readPosition(in_texCoords);
  59. // Chose the number of samples dynamicaly
  60. float sampleCountf = max(1.0 + origin.z / MAX_DISTANCE, 0.0) * float(KERNEL_SIZE);
  61. uint sampleCount = uint(sampleCountf);
  62. vec3 normal = readNormal(in_texCoords);
  63. vec3 rvec = readRandom(in_texCoords);
  64. vec3 tangent = normalize(rvec - normal * dot(rvec, normal));
  65. vec3 bitangent = cross(normal, tangent);
  66. mat3 tbn = mat3(tangent, bitangent, normal);
  67. // Iterate kernel
  68. float factor = 0.0;
  69. for(uint i = 0U; i < sampleCount; ++i)
  70. {
  71. // get position
  72. vec3 sample_ = tbn * KERNEL[i];
  73. sample_ = sample_ * RADIUS + origin;
  74. // project sample position:
  75. vec4 offset = vec4(sample_, 1.0);
  76. offset = u_uniforms.projectionMatrix * offset;
  77. offset.xy = offset.xy / (2.0 * offset.w) + 0.5; // persp div &
  78. // to NDC -> [0, 1]
  79. // get sample depth:
  80. float sampleDepth = readZ(offset.xy);
  81. // range check & accumulate:
  82. const float ADVANCE = DARKNESS_MULTIPLIER / sampleCountf;
  83. #if 0
  84. float rangeCheck =
  85. abs(origin.z - sampleDepth) * (1.0 / (RADIUS * 10.0));
  86. rangeCheck = 1.0 - rangeCheck;
  87. factor += clamp(sampleDepth - sample_.z, 0.0, ADVANCE) * rangeCheck;
  88. #else
  89. float rangeCheck = abs(origin.z - sampleDepth) < RADIUS ? 1.0 : 0.0;
  90. factor += (sampleDepth > sample_.z ? ADVANCE : 0.0) * rangeCheck;
  91. #endif
  92. }
  93. out_color = 1.0 - factor;
  94. }