ssao.glslf 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #version GLSL_VERSION
  2. /*==============================================================================
  3. VARS
  4. ==============================================================================*/
  5. #var PRECISION highp
  6. #var SSAO_WHITE 0
  7. #var SSAO_QUALITY SSAO_QUALITY_8
  8. #var SSAO_HEMISPHERE 0
  9. /*============================================================================*/
  10. precision PRECISION sampler2D;
  11. #include <precision_statement.glslf>
  12. #include <std.glsl>
  13. #include <depth_fetch.glslf>
  14. uniform sampler2D u_color;
  15. uniform sampler2D u_depth;
  16. uniform sampler2D u_ssao_special_tex;
  17. uniform vec2 u_camera_range;
  18. uniform vec2 u_texel_size;
  19. uniform float u_ssao_radius_increase; // sampling radius increase
  20. uniform float u_ssao_influence; // how much ao affects final rendering
  21. uniform float u_ssao_dist_factor; // how much ao decreases with distance
  22. /*==============================================================================
  23. SHADER INTERFACE
  24. ==============================================================================*/
  25. GLSL_IN vec2 v_texcoord;
  26. //------------------------------------------------------------------------------
  27. GLSL_OUT vec4 GLSL_OUT_FRAG_COLOR;
  28. /*============================================================================*/
  29. float read_depth(in vec2 coord) {
  30. return depth_fetch(u_depth, coord, u_camera_range);
  31. }
  32. /*==============================================================================
  33. MAIN
  34. ==============================================================================*/
  35. void main(void) {
  36. // TODO replace this by rendering to one channel using color mask
  37. vec3 tex_input = GLSL_TEXTURE(u_color, v_texcoord).rgb;
  38. #if SSAO_WHITE
  39. GLSL_OUT_FRAG_COLOR = vec4(tex_input, 1.0);
  40. return;
  41. #endif
  42. vec3 rot = normalize(2.0 * GLSL_TEXTURE(u_ssao_special_tex, v_texcoord * 0.25 / u_texel_size).rgb - 1.0);
  43. float depth = read_depth(v_texcoord);
  44. float kdepth = depth * (u_camera_range.y - u_camera_range.x);
  45. #if SSAO_QUALITY == SSAO_QUALITY_8
  46. const float snum = 8.0;
  47. const int csize= 1;
  48. #elif SSAO_QUALITY == SSAO_QUALITY_16
  49. const float snum = 16.0;
  50. const int csize= 2;
  51. #elif SSAO_QUALITY == SSAO_QUALITY_24
  52. const float snum = 24.0;
  53. const int csize= 3;
  54. #elif SSAO_QUALITY == SSAO_QUALITY_32
  55. const float snum = 32.0;
  56. const int csize= 4;
  57. #endif
  58. float offsc = u_ssao_radius_increase * 0.001; // was 0.01
  59. const float scstep = 1.0 + 2.4 / snum;
  60. float res = 0.0;
  61. for (int i = 0; i < csize; i++)
  62. for (int x = -1; x <= 1; x += 2)
  63. for (int y = -1; y <= 1; y += 2)
  64. for (int z = -1; z <= 1; z += 2) {
  65. vec3 rotoff = reflect(normalize(vec3(x,y,z)), rot) * (offsc *= scstep);
  66. vec3 spos = vec3(v_texcoord, kdepth);
  67. spos += vec3(rotoff.xy, rotoff.z * kdepth * 2.0);
  68. #if SSAO_HEMISPHERE
  69. // 1.4 - more samples close to kernel
  70. spos.z -= 1.4 * (spos.z - kdepth) * step(kdepth, spos.z);
  71. #endif
  72. float sdepth = read_depth(spos.xy) * (u_camera_range.y - u_camera_range.x);
  73. float rfuncf = clamp((kdepth - sdepth) / sdepth, 0.0, 1.0);
  74. #if SSAO_HEMISPHERE
  75. res += mix(1.0, rfuncf, step(sdepth, spos.z));
  76. #else
  77. res += mix(step(spos.z, sdepth), 0.5, rfuncf);
  78. #endif
  79. }
  80. res = res / snum;
  81. // amplification function
  82. #if SSAO_HEMISPHERE
  83. res = clamp(res * res + 0.6 * res, 0.0, 1.0);
  84. #else
  85. res = clamp(res * res + res, 0.0, 1.0);
  86. #endif
  87. float ssao_influence = u_ssao_influence * (1.0 - u_ssao_dist_factor * depth);
  88. res = mix(1.0, res, ssao_influence);
  89. GLSL_OUT_FRAG_COLOR = vec4(tex_input, res);
  90. }