PageRenderTime 31ms CodeModel.GetById 20ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 1ms

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

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