/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl

https://bitbucket.org/lindenlab/viewer-beta/ · GLSL · 135 lines · 72 code · 29 blank · 34 comment · 2 complexity · 22e81bf6235dc37a18fb04776f80f230 MD5 · raw file

  1. /**
  2. * @file sunLightSSAOF.glsl
  3. * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  4. * Second Life Viewer Source Code
  5. * Copyright (C) 2007, Linden Research, Inc.
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation;
  10. * version 2.1 of the License only.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. *
  21. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  22. * $/LicenseInfo$
  23. */
  24. #extension GL_ARB_texture_rectangle : enable
  25. #ifdef DEFINE_GL_FRAGCOLOR
  26. out vec4 gl_FragColor;
  27. #endif
  28. //class 1 -- no shadow, SSAO only
  29. uniform sampler2DRect depthMap;
  30. uniform sampler2DRect normalMap;
  31. uniform sampler2D noiseMap;
  32. // Inputs
  33. uniform mat4 shadow_matrix[6];
  34. uniform vec4 shadow_clip;
  35. uniform float ssao_radius;
  36. uniform float ssao_max_radius;
  37. uniform float ssao_factor;
  38. uniform float ssao_factor_inv;
  39. VARYING vec2 vary_fragcoord;
  40. uniform mat4 inv_proj;
  41. uniform vec2 screen_res;
  42. uniform float shadow_bias;
  43. uniform float shadow_offset;
  44. vec4 getPosition(vec2 pos_screen)
  45. {
  46. float depth = texture2DRect(depthMap, pos_screen.xy).r;
  47. vec2 sc = pos_screen.xy*2.0;
  48. sc /= screen_res;
  49. sc -= vec2(1.0,1.0);
  50. vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
  51. vec4 pos = inv_proj * ndc;
  52. pos /= pos.w;
  53. pos.w = 1.0;
  54. return pos;
  55. }
  56. //calculate decreases in ambient lighting when crowded out (SSAO)
  57. float calcAmbientOcclusion(vec4 pos, vec3 norm)
  58. {
  59. float ret = 1.0;
  60. vec2 kern[8];
  61. // exponentially (^2) distant occlusion samples spread around origin
  62. kern[0] = vec2(-1.0, 0.0) * 0.125*0.125;
  63. kern[1] = vec2(1.0, 0.0) * 0.250*0.250;
  64. kern[2] = vec2(0.0, 1.0) * 0.375*0.375;
  65. kern[3] = vec2(0.0, -1.0) * 0.500*0.500;
  66. kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625;
  67. kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750;
  68. kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875;
  69. kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000;
  70. vec2 pos_screen = vary_fragcoord.xy;
  71. vec3 pos_world = pos.xyz;
  72. vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy;
  73. float angle_hidden = 0.0;
  74. int points = 0;
  75. float scale = min(ssao_radius / -pos_world.z, ssao_max_radius);
  76. // it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations unrolling?)
  77. for (int i = 0; i < 8; i++)
  78. {
  79. vec2 samppos_screen = pos_screen + scale * reflect(kern[i], noise_reflect);
  80. vec3 samppos_world = getPosition(samppos_screen).xyz;
  81. vec3 diff = pos_world - samppos_world;
  82. float dist2 = dot(diff, diff);
  83. // assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area
  84. // --> solid angle shrinking by the square of distance
  85. //radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2
  86. //(k should vary inversely with # of samples, but this is taken care of later)
  87. angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv);
  88. // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion"
  89. points = points + int(diff.z > -1.0);
  90. }
  91. angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0);
  92. ret = (1.0 - (float(points != 0) * angle_hidden));
  93. return min(ret, 1.0);
  94. }
  95. void main()
  96. {
  97. vec2 pos_screen = vary_fragcoord.xy;
  98. //try doing an unproject here
  99. vec4 pos = getPosition(pos_screen);
  100. vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
  101. norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
  102. gl_FragColor[0] = 1.0;
  103. gl_FragColor[1] = calcAmbientOcclusion(pos, norm);
  104. gl_FragColor[2] = 1.0;
  105. gl_FragColor[3] = 1.0;
  106. }