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

https://bitbucket.org/lindenlab/viewer-beta/ · GLSL · 189 lines · 125 code · 38 blank · 26 comment · 8 complexity · b9ee5645d7cbc3d249f9b36ee73cad13 MD5 · raw file

  1. /**
  2. * @file spotLightF.glsl
  3. *
  4. * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  5. * Second Life Viewer Source Code
  6. * Copyright (C) 2007, Linden Research, Inc.
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation;
  11. * version 2.1 of the License only.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with this library; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. *
  22. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  23. * $/LicenseInfo$
  24. */
  25. #extension GL_ARB_texture_rectangle : enable
  26. #ifdef DEFINE_GL_FRAGCOLOR
  27. out vec4 gl_FragColor;
  28. #endif
  29. uniform sampler2DRect diffuseRect;
  30. uniform sampler2DRect specularRect;
  31. uniform sampler2DRect depthMap;
  32. uniform sampler2DRect normalMap;
  33. uniform sampler2D noiseMap;
  34. uniform sampler2D projectionMap;
  35. uniform mat4 proj_mat; //screen space to light space
  36. uniform float proj_near; //near clip for projection
  37. uniform vec3 proj_p; //plane projection is emitting from (in screen space)
  38. uniform vec3 proj_n;
  39. uniform float proj_focus; //distance from plane to begin blurring
  40. uniform float proj_lod; //(number of mips in proj map)
  41. uniform float proj_range; //range between near clip and far clip plane of projection
  42. uniform float proj_ambiance;
  43. uniform float near_clip;
  44. uniform float far_clip;
  45. uniform vec3 proj_origin; //origin of projection to be used for angular attenuation
  46. uniform float sun_wash;
  47. uniform vec3 center;
  48. uniform vec3 color;
  49. uniform float falloff;
  50. uniform float size;
  51. VARYING vec4 vary_fragcoord;
  52. uniform vec2 screen_res;
  53. uniform mat4 inv_proj;
  54. vec4 getPosition(vec2 pos_screen)
  55. {
  56. float depth = texture2DRect(depthMap, pos_screen.xy).a;
  57. vec2 sc = pos_screen.xy*2.0;
  58. sc /= screen_res;
  59. sc -= vec2(1.0,1.0);
  60. vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
  61. vec4 pos = inv_proj * ndc;
  62. pos /= pos.w;
  63. pos.w = 1.0;
  64. return pos;
  65. }
  66. void main()
  67. {
  68. vec4 frag = vary_fragcoord;
  69. frag.xyz /= frag.w;
  70. frag.xyz = frag.xyz*0.5+0.5;
  71. frag.xy *= screen_res;
  72. vec3 pos = getPosition(frag.xy).xyz;
  73. vec3 lv = center.xyz-pos.xyz;
  74. float dist2 = dot(lv,lv);
  75. dist2 /= size;
  76. if (dist2 > 1.0)
  77. {
  78. discard;
  79. }
  80. vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
  81. norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
  82. norm = normalize(norm);
  83. float l_dist = -dot(lv, proj_n);
  84. vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
  85. if (proj_tc.z < 0.0)
  86. {
  87. discard;
  88. }
  89. proj_tc.xyz /= proj_tc.w;
  90. float fa = falloff+1.0;
  91. float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
  92. lv = proj_origin-pos.xyz;
  93. lv = normalize(lv);
  94. float da = dot(norm, lv);
  95. vec3 col = vec3(0,0,0);
  96. vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
  97. float noise = texture2D(noiseMap, frag.xy/128.0).b;
  98. if (proj_tc.z > 0.0 &&
  99. proj_tc.x < 1.0 &&
  100. proj_tc.y < 1.0 &&
  101. proj_tc.x > 0.0 &&
  102. proj_tc.y > 0.0)
  103. {
  104. float lit = 0.0;
  105. if (da > 0.0)
  106. {
  107. float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
  108. float lod = diff * proj_lod;
  109. vec4 plcol = texture2DLod(projectionMap, proj_tc.xy, lod);
  110. vec3 lcol = color.rgb * plcol.rgb * plcol.a;
  111. lit = da * dist_atten * noise;
  112. col = lcol*lit*diff_tex;
  113. }
  114. float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
  115. float lod = diff * proj_lod;
  116. vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, lod);
  117. //float amb_da = mix(proj_ambiance, proj_ambiance*max(-da, 0.0), max(da, 0.0));
  118. float amb_da = proj_ambiance;
  119. amb_da += (da*da*0.5+0.5)*proj_ambiance;
  120. amb_da *= dist_atten * noise;
  121. amb_da = min(amb_da, 1.0-lit);
  122. col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
  123. }
  124. vec4 spec = texture2DRect(specularRect, frag.xy);
  125. if (spec.a > 0.0)
  126. {
  127. vec3 ref = reflect(normalize(pos), norm);
  128. //project from point pos in direction ref to plane proj_p, proj_n
  129. vec3 pdelta = proj_p-pos;
  130. float ds = dot(ref, proj_n);
  131. if (ds < 0.0)
  132. {
  133. vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
  134. vec3 stc = (proj_mat * vec4(pfinal.xyz, 1.0)).xyz;
  135. if (stc.z > 0.0)
  136. {
  137. stc.xy /= stc.z+proj_near;
  138. if (stc.x < 1.0 &&
  139. stc.y < 1.0 &&
  140. stc.x > 0.0 &&
  141. stc.y > 0.0)
  142. {
  143. vec4 scol = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
  144. col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb;
  145. }
  146. }
  147. }
  148. }
  149. gl_FragColor.rgb = col;
  150. gl_FragColor.a = 0.0;
  151. }