Ssao.frag.glsl 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  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. // SSAO fragment shader
  6. #include "shaders/Common.glsl"
  7. #include "shaders/Pack.glsl"
  8. #include "shaders/Functions.glsl"
  9. const vec2 KERNEL[SAMPLES] = KERNEL_ARRAY; // This will be appended in C++
  10. const float BIAS = 0.2;
  11. const float STRENGTH = 1.1;
  12. layout(location = 0) in vec2 in_uv;
  13. layout(location = 0) out float out_color;
  14. layout(ANKI_UBO_BINDING(0, 0), std140, row_major) uniform _blk
  15. {
  16. vec4 u_unprojectionParams;
  17. vec4 u_projectionMat;
  18. };
  19. layout(ANKI_TEX_BINDING(0, 0)) uniform sampler2D u_mMsDepthRt;
  20. layout(ANKI_TEX_BINDING(0, 1)) uniform sampler2D u_msRt;
  21. layout(ANKI_TEX_BINDING(0, 2)) uniform sampler2DArray u_noiseMap;
  22. // Get normal
  23. vec3 readNormal(in vec2 uv)
  24. {
  25. vec3 normal;
  26. readNormalFromGBuffer(u_msRt, uv, normal);
  27. return normal;
  28. }
  29. // Read the noise tex
  30. float readRandom(in vec2 uv)
  31. {
  32. const vec2 tmp = vec2(float(WIDTH) / float(NOISE_MAP_SIZE), float(HEIGHT) / float(NOISE_MAP_SIZE));
  33. return texture(u_noiseMap, vec3(tmp * uv, 0.0)).r;
  34. }
  35. // Returns the Z of the position in view space
  36. float readZ(in vec2 uv)
  37. {
  38. float depth = texture(u_mMsDepthRt, uv).r;
  39. float z = u_unprojectionParams.z / (u_unprojectionParams.w + depth);
  40. return z;
  41. }
  42. // Read position in view space
  43. vec3 readPosition(in vec2 uv)
  44. {
  45. vec3 fragPosVspace;
  46. fragPosVspace.z = readZ(uv);
  47. fragPosVspace.xy = (2.0 * uv - 1.0) * u_unprojectionParams.xy * fragPosVspace.z;
  48. return fragPosVspace;
  49. }
  50. vec4 project(vec4 point)
  51. {
  52. return projectPerspective(point, u_projectionMat.x, u_projectionMat.y, u_projectionMat.z, u_projectionMat.w);
  53. }
  54. void main(void)
  55. {
  56. vec2 ndc = in_uv * 2.0 - 1.0;
  57. vec3 origin = readPosition(in_uv);
  58. vec3 normal = readNormal(in_uv);
  59. float randFactor = readRandom(in_uv);
  60. float randAng = randFactor * PI * 2.0;
  61. float cosAng = cos(randAng);
  62. float sinAng = sin(randAng);
  63. // Find the projected radius
  64. vec3 sphereLimit = origin + vec3(RADIUS, 0.0, 0.0);
  65. vec4 projSphereLimit = project(vec4(sphereLimit, 1.0));
  66. vec2 projSphereLimit2 = projSphereLimit.xy / projSphereLimit.w;
  67. float projRadius = length(projSphereLimit2 - ndc);
  68. // Integrate
  69. float factor = 0.0;
  70. for(uint i = 0U; i < SAMPLES; ++i)
  71. {
  72. // Rotate the disk point
  73. vec2 diskPoint = KERNEL[i] * projRadius;
  74. vec2 rotDiskPoint;
  75. rotDiskPoint.x = diskPoint.x * cosAng - diskPoint.y * sinAng;
  76. rotDiskPoint.y = diskPoint.y * cosAng + diskPoint.x * sinAng;
  77. vec2 finalDiskPoint = ndc + rotDiskPoint;
  78. vec3 s = readPosition(NDC_TO_UV(finalDiskPoint));
  79. vec3 u = s - origin;
  80. float f = max(dot(normal, u) + BIAS, 0.0) / max(dot(u, u), EPSILON);
  81. factor += f;
  82. }
  83. out_color = 1.0 - factor / float(SAMPLES) * STRENGTH;
  84. }