PageRenderTime 329ms CodeModel.GetById 124ms app.highlight 9ms RepoModel.GetById 187ms app.codeStats 0ms

/indra/newview/app_settings/shaders/class2/deferred/spotLightMSF.glsl

https://bitbucket.org/lindenlab/viewer-beta/
text | 263 lines | 201 code | 62 blank | 0 comment | 0 complexity | 80c871a697abe2eb3a81e6469056921b MD5 | raw file
  1/** 
  2 * @file multiSpotLightF.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
 26
 27
 28#extension GL_ARB_texture_rectangle : enable
 29#extension GL_ARB_texture_multisample : enable
 30
 31uniform sampler2DMS diffuseRect;
 32uniform sampler2DMS specularRect;
 33uniform sampler2DMS depthMap;
 34uniform sampler2DMS normalMap;
 35uniform sampler2DRect lightMap;
 36uniform sampler2D noiseMap;
 37uniform sampler2D lightFunc;
 38uniform sampler2D projectionMap;
 39
 40uniform mat4 proj_mat; //screen space to light space
 41uniform float proj_near; //near clip for projection
 42uniform vec3 proj_p; //plane projection is emitting from (in screen space)
 43uniform vec3 proj_n;
 44uniform float proj_focus; //distance from plane to begin blurring
 45uniform float proj_lod;  //(number of mips in proj map)
 46uniform float proj_range; //range between near clip and far clip plane of projection
 47uniform float proj_ambient_lod;
 48uniform float proj_ambiance;
 49uniform float near_clip;
 50uniform float far_clip;
 51
 52uniform vec3 proj_origin; //origin of projection to be used for angular attenuation
 53uniform float sun_wash;
 54uniform int proj_shadow_idx;
 55uniform float shadow_fade;
 56
 57varying vec4 vary_light;
 58
 59varying vec4 vary_fragcoord;
 60uniform vec2 screen_res;
 61
 62uniform mat4 inv_proj;
 63
 64vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
 65{
 66	vec4 ret = texture2DLod(projectionMap, tc, lod);
 67	
 68	vec2 dist = tc-vec2(0.5);
 69	
 70	float det = max(1.0-lod/(proj_lod*0.5), 0.0);
 71	
 72	float d = dot(dist,dist);
 73		
 74	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0);
 75	
 76	return ret;
 77}
 78
 79vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
 80{
 81	vec4 ret = texture2DLod(projectionMap, tc, lod);
 82	
 83	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
 84	
 85	float det = min(lod/(proj_lod*0.5), 1.0);
 86	
 87	float d = min(dist.x, dist.y);
 88	
 89	float edge = 0.25*det;
 90		
 91	ret *= clamp(d/edge, 0.0, 1.0);
 92	
 93	return ret;
 94}
 95
 96vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
 97{
 98	vec4 ret = texture2DLod(projectionMap, tc, lod);
 99	
100	vec2 dist = tc-vec2(0.5);
101	
102	float d = dot(dist,dist);
103		
104	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0);
105	
106	return ret;
107}
108
109
110vec4 getPosition(ivec2 pos_screen, int sample)
111{
112	float depth = texelFetch(depthMap, pos_screen, sample).r;
113	vec2 sc = vec2(pos_screen.xy)*2.0;
114	sc /= screen_res;
115	sc -= vec2(1.0,1.0);
116	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
117	vec4 pos = inv_proj * ndc;
118	pos /= pos.w;
119	pos.w = 1.0;
120	return pos;
121}
122
123void main() 
124{
125	vec4 frag = vary_fragcoord;
126	frag.xyz /= frag.w;
127	frag.xyz = frag.xyz*0.5+0.5;
128	frag.xy *= screen_res;
129	ivec2 itc = ivec2(frag.xy);
130	
131	vec3 fcol = vec3(0,0,0);
132	int wght = 0;
133
134	float shadow = 1.0;
135	
136	if (proj_shadow_idx >= 0)
137	{
138		vec4 shd = texture2DRect(lightMap, frag.xy);
139		float sh[2];
140		sh[0] = shd.b;
141		sh[1] = shd.a;
142		shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0);
143	}
144	
145	for (int i = 0; i < samples; i++)
146	{
147		vec3 pos = getPosition(itc, i).xyz;
148		vec3 lv = vary_light.xyz-pos.xyz;
149		float dist2 = dot(lv,lv);
150		dist2 /= vary_light.w;
151		if (dist2 <= 1.0)
152		{
153			vec3 norm = texelFetch(normalMap, itc, i).xyz;
154			norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
155	
156			norm = normalize(norm);
157			float l_dist = -dot(lv, proj_n);
158	
159			vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
160			if (proj_tc.z >= 0.0)
161			{
162				proj_tc.xyz /= proj_tc.w;
163	
164				float fa = gl_Color.a+1.0;
165				float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0);
166				if (dist_atten > 0.0)
167				{
168					lv = proj_origin-pos.xyz;
169					lv = normalize(lv);
170					float da = dot(norm, lv);
171		
172					vec3 col = vec3(0,0,0);
173		
174					vec3 diff_tex = texelFetch(diffuseRect, itc, i).rgb;
175		
176					float noise = texture2D(noiseMap, frag.xy/128.0).b;
177					if (proj_tc.z > 0.0 &&
178						proj_tc.x < 1.0 &&
179						proj_tc.y < 1.0 &&
180						proj_tc.x > 0.0 &&
181						proj_tc.y > 0.0)
182					{
183						float lit = 0.0;
184						float amb_da = proj_ambiance;
185		
186						if (da > 0.0)
187						{
188							float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
189							float lod = diff * proj_lod;
190			
191							vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
192		
193							vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a;
194			
195							lit = da * dist_atten * noise;
196			
197							col = lcol*lit*diff_tex*shadow;
198							amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;
199						}
200		
201						//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
202						vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
203							
204						amb_da += (da*da*0.5+0.5)*proj_ambiance;
205				
206						amb_da *= dist_atten * noise;
207			
208						amb_da = min(amb_da, 1.0-lit);
209			
210						col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
211					}
212	
213	
214					vec4 spec = texelFetch(specularRect, itc, i);
215					if (spec.a > 0.0)
216					{
217						vec3 ref = reflect(normalize(pos), norm);
218		
219						//project from point pos in direction ref to plane proj_p, proj_n
220						vec3 pdelta = proj_p-pos;
221						float ds = dot(ref, proj_n);
222		
223						if (ds < 0.0)
224						{
225							vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
226			
227							vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
228
229							if (stc.z > 0.0)
230							{
231								stc.xy /= stc.w;
232
233								float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0);
234				
235								stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
236								
237								if (stc.x < 1.0 &&
238									stc.y < 1.0 &&
239									stc.x > 0.0 &&
240									stc.y > 0.0)
241								{
242									vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
243									col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb*shadow;
244								}
245							}
246						}
247					}
248
249					fcol += col;
250					wght++;
251				}
252			}
253		}
254	}
255	
256	if (wght <= 0)
257	{
258		discard;
259	}
260
261	gl_FragColor.rgb = fcol/wght;	
262	gl_FragColor.a = 0.0;
263}