/indra/newview/app_settings/shaders/class3/deferred/giF.glsl

https://bitbucket.org/lindenlab/viewer-beta/ · GLSL · 211 lines · 141 code · 44 blank · 26 comment · 8 complexity · e04e664a6ac570dc67d28803e5df671b MD5 · raw file

  1. /**
  2. * @file giF.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. uniform sampler2DRect depthMap;
  27. uniform sampler2DRect normalMap;
  28. uniform sampler2DRect lightMap;
  29. uniform sampler2DRect specularRect;
  30. uniform sampler2D noiseMap;
  31. uniform sampler2D diffuseGIMap;
  32. uniform sampler2D specularGIMap;
  33. uniform sampler2D normalGIMap;
  34. uniform sampler2D depthGIMap;
  35. uniform sampler2D lightFunc;
  36. // Inputs
  37. varying vec2 vary_fragcoord;
  38. uniform vec2 screen_res;
  39. uniform vec4 sunlight_color;
  40. uniform mat4 inv_proj;
  41. uniform mat4 gi_mat; //gPipeline.mGIMatrix - eye space to sun space
  42. uniform mat4 gi_mat_proj; //gPipeline.mGIMatrixProj - eye space to projected sun space
  43. uniform mat4 gi_norm_mat; //gPipeline.mGINormalMatrix - eye space normal to sun space normal matrix
  44. uniform mat4 gi_inv_proj; //gPipeline.mGIInvProj - projected sun space to sun space
  45. uniform float gi_sample_width;
  46. uniform float gi_noise;
  47. uniform float gi_attenuation;
  48. uniform float gi_range;
  49. vec4 getPosition(vec2 pos_screen)
  50. {
  51. float depth = texture2DRect(depthMap, pos_screen.xy).a;
  52. vec2 sc = pos_screen.xy*2.0;
  53. sc /= screen_res;
  54. sc -= vec2(1.0,1.0);
  55. vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
  56. vec4 pos = inv_proj * ndc;
  57. pos /= pos.w;
  58. pos.w = 1.0;
  59. return pos;
  60. }
  61. vec4 getGIPosition(vec2 gi_tc)
  62. {
  63. float depth = texture2D(depthGIMap, gi_tc).a;
  64. vec2 sc = gi_tc*2.0;
  65. sc -= vec2(1.0, 1.0);
  66. vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
  67. vec4 pos = gi_inv_proj*ndc;
  68. pos.xyz /= pos.w;
  69. pos.w = 1.0;
  70. return pos;
  71. }
  72. vec3 giAmbient(vec3 pos, vec3 norm)
  73. {
  74. vec4 gi_c = gi_mat_proj * vec4(pos, 1.0);
  75. gi_c.xyz /= gi_c.w;
  76. vec4 gi_pos = gi_mat*vec4(pos,1.0);
  77. vec3 gi_norm = (gi_norm_mat*vec4(norm,1.0)).xyz;
  78. gi_norm = normalize(gi_norm);
  79. vec4 c_spec = texture2DRect(specularRect, vary_fragcoord.xy);
  80. vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).rgb;
  81. gi_pos.xyz += nz.x*gi_noise*gi_norm.xyz;
  82. vec2 tcx = gi_norm.xy;
  83. vec2 tcy = gi_norm.yx;
  84. vec4 eye_pos = gi_mat*vec4(0,0,0,1.0);
  85. vec3 eye_dir = normalize(gi_pos.xyz-eye_pos.xyz);
  86. vec3 eye_ref = reflect(eye_dir, gi_norm);
  87. float da = 0.0; //texture2DRect(lightMap, vary_fragcoord.xy).r*0.5;
  88. vec3 fdiff = vec3(da);
  89. float fda = da;
  90. vec3 rcol = vec3(0,0,0);
  91. float fsa = 0.0;
  92. for (int i = -1; i <= 1; i += 2 )
  93. {
  94. for (int j = -1; j <= 1; j+= 2)
  95. {
  96. vec2 tc = vec2(i, j)*0.75+gi_norm.xy*nz.z;
  97. tc += nz.xy*2.0;
  98. tc *= gi_sample_width*0.25;
  99. tc += gi_c.xy;
  100. vec3 lnorm = -(texture2D(normalGIMap, tc.xy).xyz*2.0-1.0);
  101. vec3 lpos = getGIPosition(tc.xy).xyz;
  102. vec3 at = lpos-gi_pos.xyz;
  103. float dist = length(at);
  104. float dist_atten = clamp(1.0/(gi_attenuation*dist), 0.0, 1.0);
  105. if (dist_atten > 0.01)
  106. { //possible contribution of indirect light to this surface
  107. vec3 ldir = at;
  108. float ld = -dot(ldir, lnorm);
  109. if (ld < 0.0)
  110. {
  111. float ang_atten = dot(ldir, gi_norm);
  112. if (ang_atten > 0.0)
  113. {
  114. vec4 spec = texture2D(specularGIMap, tc.xy);
  115. at = normalize(at);
  116. vec3 diff;
  117. float da = 0.0;
  118. //contribution from indirect source to visible pixel
  119. vec3 ha = at;
  120. ha.z -= 1.0;
  121. ha = normalize(ha);
  122. if (spec.a > 0.0)
  123. {
  124. float sa = dot(ha,lnorm);
  125. da = texture2D(lightFunc, vec2(sa, spec.a)).a;
  126. }
  127. else
  128. {
  129. da = -lnorm.z;
  130. }
  131. diff = texture2D(diffuseGIMap, tc.xy).rgb+spec.rgb*spec.a*2.0;
  132. if (da > 0.0)
  133. { //contribution from visible pixel to eye
  134. vec3 ha = normalize(at-eye_dir);
  135. if (c_spec.a > 0.0)
  136. {
  137. float sa = dot(ha, gi_norm);
  138. da = dist_atten*texture2D(lightFunc, vec2(sa, c_spec.a)).a;
  139. }
  140. else
  141. {
  142. da = dist_atten*dot(gi_norm, normalize(ldir));
  143. }
  144. fda += da;
  145. fdiff += da*(c_spec.rgb*c_spec.a*2.0+vec3(1,1,1))*diff.rgb;
  146. }
  147. }
  148. }
  149. }
  150. }
  151. }
  152. fdiff *= sunlight_color.rgb;
  153. vec3 ret = fda*fdiff;
  154. return clamp(ret,vec3(0.0), vec3(1.0));
  155. }
  156. void main()
  157. {
  158. vec2 pos_screen = vary_fragcoord.xy;
  159. vec4 pos = getPosition(pos_screen);
  160. float rad = gi_range*0.5;
  161. vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
  162. norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
  163. float dist = max(length(pos.xyz)-rad, 0.0);
  164. float da = clamp(1.0-dist/rad, 0.0, 1.0);
  165. vec3 ambient = da > 0.0 ? giAmbient(pos.xyz, norm) : vec3(0);
  166. gl_FragData[0].xyz = mix(vec3(0), ambient, da);
  167. }