PageRenderTime 55ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://bitbucket.org/lindenlab/viewer-beta/
text | 140 lines | 111 code | 29 blank | 0 comment | 0 complexity | 775a7b6c630cbb0ffc56a9a072a23754 MD5 | raw file
Possible License(s): LGPL-2.1
  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. #extension GL_ARB_texture_multisample : enable
  26. //class 1 -- no shadow, SSAO only
  27. uniform sampler2DMS depthMap;
  28. uniform sampler2DMS normalMap;
  29. uniform sampler2D noiseMap;
  30. // Inputs
  31. uniform mat4 shadow_matrix[6];
  32. uniform vec4 shadow_clip;
  33. uniform float ssao_radius;
  34. uniform float ssao_max_radius;
  35. uniform float ssao_factor;
  36. uniform float ssao_factor_inv;
  37. varying vec2 vary_fragcoord;
  38. varying vec4 vary_light;
  39. uniform mat4 inv_proj;
  40. uniform vec2 screen_res;
  41. uniform float shadow_bias;
  42. uniform float shadow_offset;
  43. vec4 getPosition(ivec2 pos_screen, int sample)
  44. {
  45. float depth = texelFetch(depthMap, pos_screen, sample).r;
  46. vec2 sc = pos_screen.xy*2.0;
  47. sc /= screen_res;
  48. sc -= vec2(1.0,1.0);
  49. vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
  50. vec4 pos = inv_proj * ndc;
  51. pos /= pos.w;
  52. pos.w = 1.0;
  53. return pos;
  54. }
  55. //calculate decreases in ambient lighting when crowded out (SSAO)
  56. float calcAmbientOcclusion(vec4 pos, vec3 norm, int sample)
  57. {
  58. float ret = 1.0;
  59. vec2 kern[8];
  60. // exponentially (^2) distant occlusion samples spread around origin
  61. kern[0] = vec2(-1.0, 0.0) * 0.125*0.125;
  62. kern[1] = vec2(1.0, 0.0) * 0.250*0.250;
  63. kern[2] = vec2(0.0, 1.0) * 0.375*0.375;
  64. kern[3] = vec2(0.0, -1.0) * 0.500*0.500;
  65. kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625;
  66. kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750;
  67. kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875;
  68. kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000;
  69. vec2 pos_screen = vary_fragcoord.xy;
  70. vec3 pos_world = pos.xyz;
  71. vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy;
  72. float angle_hidden = 0.0;
  73. int points = 0;
  74. float scale = min(ssao_radius / -pos_world.z, ssao_max_radius);
  75. // it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations unrolling?)
  76. for (int i = 0; i < 8; i++)
  77. {
  78. ivec2 samppos_screen = ivec2(pos_screen + scale * reflect(kern[i], noise_reflect));
  79. vec3 samppos_world = getPosition(samppos_screen, sample).xyz;
  80. vec3 diff = pos_world - samppos_world;
  81. float dist2 = dot(diff, diff);
  82. // assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area
  83. // --> solid angle shrinking by the square of distance
  84. //radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2
  85. //(k should vary inversely with # of samples, but this is taken care of later)
  86. angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv);
  87. // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion"
  88. points = points + int(diff.z > -1.0);
  89. }
  90. angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0);
  91. ret = (1.0 - (float(points != 0) * angle_hidden));
  92. return min(ret, 1.0);
  93. }
  94. void main()
  95. {
  96. vec2 pos_screen = vary_fragcoord.xy;
  97. ivec2 itc = ivec2(pos_screen);
  98. float col = 0;
  99. for (int i = 0; i < samples; i++)
  100. {
  101. vec4 pos = getPosition(itc, i);
  102. vec3 norm = texelFetch(normalMap, itc, i).xyz;
  103. norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
  104. col += calcAmbientOcclusion(pos,norm,i);
  105. }
  106. col /= samples;
  107. gl_FragColor[0] = 1.0;
  108. gl_FragColor[1] = col;
  109. gl_FragColor[2] = 1.0;
  110. gl_FragColor[3] = 1.0;
  111. }