diff options
Diffstat (limited to 'indra/newview/app_settings/shaders/class2/deferred')
11 files changed, 947 insertions, 62 deletions
| diff --git a/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl b/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl index 3155f3f929..30e1702e9f 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl @@ -22,7 +22,7 @@ uniform vec2 screen_res;  float getDepth(vec2 pos_screen)  { -	float z = texture2DRect(depthMap, pos_screen.xy).a; +	float z = texture2DRect(depthMap, pos_screen.xy).r;  	z = z*2.0-1.0;  	vec4 ndc = vec4(0.0, 0.0, z, 1.0);  	vec4 p = inv_proj*ndc; diff --git a/indra/newview/app_settings/shaders/class2/deferred/edgeMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/edgeMSF.glsl index a47ee678f6..38100d1523 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/edgeMSF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/edgeMSF.glsl @@ -21,8 +21,9 @@ uniform float norm_cutoff;  uniform mat4 inv_proj;  uniform vec2 screen_res; -float getDepth(float z) +float getDepth(ivec2 pos_screen, int sample)  { +	float z = texelFetch(depthMap, pos_screen, sample).r;  	z = z*2.0-1.0;  	vec4 ndc = vec4(0.0, 0.0, z, 1.0);  	vec4 p = inv_proj*ndc; @@ -31,7 +32,6 @@ float getDepth(float z)  void main()   { -  	float e = 0;  	ivec2 itc = ivec2(vary_fragcoord.xy); @@ -40,24 +40,24 @@ void main()  	{	  		vec3 norm = texelFetch(normalMap, itc, i).xyz;  		norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm -		float depth = getDepth(texelFetch(depthMap, itc, i).r); +		float depth = getDepth(itc, i);  		vec2 tc = vary_fragcoord.xy; -		float sc = 0.75; +		int sc = 1;  		vec2 de; -		de.x = (depth-getDepth(tc+vec2(sc, sc))) + (depth-getDepth(tc+vec2(-sc, -sc))); -		de.y = (depth-getDepth(tc+vec2(-sc, sc))) + (depth-getDepth(tc+vec2(sc, -sc))); +		de.x = (depth-getDepth(itc+ivec2(sc, sc),i)) + (depth-getDepth(itc+ivec2(-sc, -sc), i)); +		de.y = (depth-getDepth(itc+ivec2(-sc, sc),i)) + (depth-getDepth(itc+ivec2(sc, -sc), i));  		de /= depth;  		de *= de;  		de = step(depth_cutoff, de);  		vec2 ne; -		vec3 nexnorm = texture2DRect(normalMap, tc+vec2(-sc,-sc)).rgb; +		vec3 nexnorm = texelFetch(normalMap, itc+ivec2(-sc,-sc), i).rgb;  		nexnorm = vec3((nexnorm.xy-0.5)*2.0,nexnorm.z); // unpack norm  		ne.x = dot(nexnorm, norm); -		vec3 neynorm = texture2DRect(normalMap, tc+vec2(sc,sc)).rgb; +		vec3 neynorm = texelFetch(normalMap, itc+ivec2(sc,sc), i).rgb;  		neynorm = vec3((neynorm.xy-0.5)*2.0,neynorm.z); // unpack norm  		ne.y = dot(neynorm, norm); diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl index d6cd984ebe..de987b1233 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl @@ -91,7 +91,7 @@ vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)  vec4 getPosition(vec2 pos_screen)  { -	float depth = texture2DRect(depthMap, pos_screen.xy).a; +	float depth = texture2DRect(depthMap, pos_screen.xy).r;  	vec2 sc = pos_screen.xy*2.0;  	sc /= screen_res;  	sc -= vec2(1.0,1.0); diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightMSF.glsl new file mode 100644 index 0000000000..c6f0ea2a5d --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightMSF.glsl @@ -0,0 +1,244 @@ +/**  + * @file multiSpotLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +uniform sampler2DMS diffuseRect; +uniform sampler2DMS specularRect; +uniform sampler2DMS depthMap; +uniform sampler2DMS normalMap; +uniform sampler2DMS lightMap; +uniform sampler2D noiseMap; +uniform sampler2D lightFunc; +uniform sampler2D projectionMap; + +uniform mat4 proj_mat; //screen space to light space +uniform float proj_near; //near clip for projection +uniform vec3 proj_p; //plane projection is emitting from (in screen space) +uniform vec3 proj_n; +uniform float proj_focus; //distance from plane to begin blurring +uniform float proj_lod;  //(number of mips in proj map) +uniform float proj_range; //range between near clip and far clip plane of projection +uniform float proj_ambient_lod; +uniform float proj_ambiance; +uniform float near_clip; +uniform float far_clip; + +uniform vec3 proj_origin; //origin of projection to be used for angular attenuation +uniform float sun_wash; +uniform int proj_shadow_idx; +uniform float shadow_fade; + +varying vec4 vary_light; + +varying vec4 vary_fragcoord; +uniform vec2 screen_res; + +uniform mat4 inv_proj; + +vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod) +{ +	vec4 ret = texture2DLod(projectionMap, tc, lod); +	 +	vec2 dist = tc-vec2(0.5); +	 +	float det = max(1.0-lod/(proj_lod*0.5), 0.0); +	 +	float d = dot(dist,dist); +		 +	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0); +	 +	return ret; +} + +vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod) +{ +	vec4 ret = texture2DLod(projectionMap, tc, lod); +	 +	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); +	 +	float det = min(lod/(proj_lod*0.5), 1.0); +	 +	float d = min(dist.x, dist.y); +	 +	float edge = 0.25*det; +		 +	ret *= clamp(d/edge, 0.0, 1.0); +	 +	return ret; +} + +vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod) +{ +	vec4 ret = texture2DLod(projectionMap, tc, lod); +	 +	vec2 dist = tc-vec2(0.5); +	 +	float d = dot(dist,dist); +		 +	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0); +	 +	return ret; +} + + +vec4 getPosition(ivec2 pos_screen, int sample) +{ +	float depth = texelFetch(depthMap, pos_screen, sample).r; +	vec2 sc = vec2(pos_screen.xy)*2.0; +	sc /= screen_res; +	sc -= vec2(1.0,1.0); +	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); +	vec4 pos = inv_proj * ndc; +	pos /= pos.w; +	pos.w = 1.0; +	return pos; +} + +void main()  +{ +	int wght = 0; + +	vec3 fcol = vec3(0,0,0); + +	vec2 frag = (vary_fragcoord.xy*0.5+0.5)*screen_res; +	 +	ivec2 itc = ivec2(frag.xy); + +	for (int i = 0; i < samples; i++) +	{ +		vec3 pos = getPosition(itc, i).xyz; +		vec3 lv = vary_light.xyz-pos.xyz; +		float dist2 = dot(lv,lv); +		dist2 /= vary_light.w; +		if (dist2 <= 1.0) +		{ +			float shadow = 1.0; +	 +			if (proj_shadow_idx >= 0) +			{ +				vec4 shd = texelFetch(lightMap, itc, i); +				float sh[2]; +				sh[0] = shd.b; +				sh[1] = shd.a; +				shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0); +			} +	 +			vec3 norm = texelFetch(normalMap, itc, i).xyz; +			norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm +	 +			norm = normalize(norm); +			float l_dist = -dot(lv, proj_n); +	 +			vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); +			if (proj_tc.z >= 0.0) +			{ +				proj_tc.xyz /= proj_tc.w; +	 +				float fa = gl_Color.a+1.0; +				float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0); +				if (dist_atten > 0.0) +				{ +					lv = proj_origin-pos.xyz; +					lv = normalize(lv); +					float da = dot(norm, lv); +		 +					vec3 col = vec3(0,0,0); +		 +					vec3 diff_tex = texelFetch(diffuseRect, itc, i).rgb; +		 +					float noise = texture2D(noiseMap, frag.xy/128.0).b; +					if (proj_tc.z > 0.0 && +						proj_tc.x < 1.0 && +						proj_tc.y < 1.0 && +						proj_tc.x > 0.0 && +						proj_tc.y > 0.0) +					{ +						float lit = 0.0; +						float amb_da = proj_ambiance; +		 +						if (da > 0.0) +						{ +							float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0); +							float lod = diff * proj_lod; +			 +							vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod); +		 +							vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a; +			 +							lit = da * dist_atten * noise; +			 +							col = lcol*lit*diff_tex*shadow; +							amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance; +						} +		 +						//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); +						vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod); +							 +						amb_da += (da*da*0.5+0.5)*proj_ambiance; +				 +						amb_da *= dist_atten * noise; +			 +						amb_da = min(amb_da, 1.0-lit); +			 +						col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; +					} +	 +	 +					vec4 spec = texelFetch(specularRect, itc, i); +					if (spec.a > 0.0) +					{ +						vec3 ref = reflect(normalize(pos), norm); +		 +						//project from point pos in direction ref to plane proj_p, proj_n +						vec3 pdelta = proj_p-pos; +						float ds = dot(ref, proj_n); +		 +						if (ds < 0.0) +						{ +							vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; +			 +							vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0)); + +							if (stc.z > 0.0) +							{ +								stc.xy /= stc.w; + +								float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0); +				 +								stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); +								 +								if (stc.x < 1.0 && +									stc.y < 1.0 && +									stc.x > 0.0 && +									stc.y > 0.0) +								{ +									vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); +									col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb*shadow; +								} +							} +						} +					} + +					fcol += col; +					wght++; +				} +			} +		} +	} +	 +	if (wght <= 0) +	{ +		discard; +	} + +	gl_FragColor.rgb = fcol/wght;	 +	gl_FragColor.a = 0.0; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl index 0160e84278..dfa1964142 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -71,7 +71,7 @@ vec4 getPosition_d(vec2 pos_screen, float depth)  vec4 getPosition(vec2 pos_screen)  { //get position in screen space (world units) given window coordinate and depth map -	float depth = texture2DRect(depthMap, pos_screen.xy).a; +	float depth = texture2DRect(depthMap, pos_screen.xy).r;  	return getPosition_d(pos_screen, depth);  } @@ -258,7 +258,7 @@ vec3 scaleSoftClip(vec3 light)  void main()   {  	vec2 tc = vary_fragcoord.xy; -	float depth = texture2DRect(depthMap, tc.xy).a; +	float depth = texture2DRect(depthMap, tc.xy).r;  	vec3 pos = getPosition_d(tc, depth).xyz;  	vec3 norm = texture2DRect(normalMap, tc).xyz;  	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm @@ -288,54 +288,8 @@ void main()  		float sa = dot(refnormpersp, vary_light.xyz);  		vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*texture2D(lightFunc, vec2(sa, spec.a)).a; -		/* -		// screen-space cheap fakey reflection map -		// -		vec3 refnorm = normalize(reflect(vec3(0,0,-1), norm.xyz)); -		depth -= 0.5; // unbias depth -		// first figure out where we'll make our 2D guess from -		vec2 ref2d = (0.25 * screen_res.y) * (refnorm.xy) * abs(refnorm.z) / depth; -		// Offset the guess source a little according to a trivial -		// checkerboard dither function and spec.a. -		// This is meant to be similar to sampling a blurred version -		// of the diffuse map.  LOD would be better in that regard. -		// The goal of the blur is to soften reflections in surfaces -		// with low shinyness, and also to disguise our lameness. -		float checkerboard = floor(mod(tc.x+tc.y, 2.0)); // 0.0, 1.0 -		float checkoffset = (3.0 + (7.0*(1.0-spec.a)))*(checkerboard-0.5); -		ref2d += vec2(checkoffset, checkoffset); -		ref2d += tc.xy; // use as offset from destination -		// Get attributes from the 2D guess point. -		// We average two samples of diffuse (not of anything else) per -		// pixel to try to reduce aliasing some more. -		vec3 refcol = 0.5 * (texture2DRect(diffuseRect, ref2d + vec2(0.0, -checkoffset)).rgb + -				     texture2DRect(diffuseRect, ref2d + vec2(-checkoffset, 0.0)).rgb); -		float refdepth = texture2DRect(depthMap, ref2d).a; -		vec3 refpos = getPosition_d(ref2d, refdepth).xyz; -		float refshad = texture2DRect(lightMap, ref2d).r; -		vec3 refn = texture2DRect(normalMap, ref2d).rgb; -		refn = vec3((refn.xy-0.5)*2.0,refn.z); // unpack norm -		refn = normalize(refn); -		// figure out how appropriate our guess actually was -		float refapprop = max(0.0, dot(-refnorm, normalize(pos - refpos))); -		// darken reflections from points which face away from the reflected ray - our guess was a back-face -		//refapprop *= step(dot(refnorm, refn), 0.0); -		refapprop = min(refapprop, max(0.0, -dot(refnorm, refn))); // more conservative variant -		// get appropriate light strength for guess-point -		// reflect light direction to increase the illusion that -		// these are reflections. -		vec3 reflight = reflect(lightnorm.xyz, norm.xyz); -		float reflit = min(max(dot(refn, reflight.xyz), 0.0), refshad); -		// apply sun color to guess-point, dampen according to inappropriateness of guess -		float refmod = min(refapprop, reflit); -		vec3 refprod = vary_SunlitColor * refcol.rgb * refmod; -		vec3 ssshiny = (refprod * spec.a); -		ssshiny *= 0.3; // dampen it even more -		*/ -		vec3 ssshiny = vec3(0,0,0); -  		// add the two types of shiny together -		col += (ssshiny + dumbshiny) * spec.rgb; +		col += dumbshiny * spec.rgb;  	}  	col = atmosLighting(col); diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightMSF.glsl index 7d4548d6d9..71482d0c7b 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightMSF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightMSF.glsl @@ -252,7 +252,6 @@ vec3 scaleSoftClip(vec3 light)  void main()   { -	int samples = 4;  	vec2 tc = vary_fragcoord.xy;  	ivec2 itc = ivec2(tc); diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightMSF.glsl new file mode 100644 index 0000000000..099a45718a --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightMSF.glsl @@ -0,0 +1,245 @@ +/**  + * @file multiSpotLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +uniform sampler2DMS diffuseRect; +uniform sampler2DMS specularRect; +uniform sampler2DMS depthMap; +uniform sampler2DMS normalMap; +uniform sampler2DMS lightMap; +uniform sampler2D noiseMap; +uniform sampler2D lightFunc; +uniform sampler2D projectionMap; + +uniform mat4 proj_mat; //screen space to light space +uniform float proj_near; //near clip for projection +uniform vec3 proj_p; //plane projection is emitting from (in screen space) +uniform vec3 proj_n; +uniform float proj_focus; //distance from plane to begin blurring +uniform float proj_lod;  //(number of mips in proj map) +uniform float proj_range; //range between near clip and far clip plane of projection +uniform float proj_ambient_lod; +uniform float proj_ambiance; +uniform float near_clip; +uniform float far_clip; + +uniform vec3 proj_origin; //origin of projection to be used for angular attenuation +uniform float sun_wash; +uniform int proj_shadow_idx; +uniform float shadow_fade; + +varying vec4 vary_light; + +varying vec4 vary_fragcoord; +uniform vec2 screen_res; + +uniform mat4 inv_proj; + +vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod) +{ +	vec4 ret = texture2DLod(projectionMap, tc, lod); +	 +	vec2 dist = tc-vec2(0.5); +	 +	float det = max(1.0-lod/(proj_lod*0.5), 0.0); +	 +	float d = dot(dist,dist); +		 +	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0); +	 +	return ret; +} + +vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod) +{ +	vec4 ret = texture2DLod(projectionMap, tc, lod); +	 +	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); +	 +	float det = min(lod/(proj_lod*0.5), 1.0); +	 +	float d = min(dist.x, dist.y); +	 +	float edge = 0.25*det; +		 +	ret *= clamp(d/edge, 0.0, 1.0); +	 +	return ret; +} + +vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod) +{ +	vec4 ret = texture2DLod(projectionMap, tc, lod); +	 +	vec2 dist = tc-vec2(0.5); +	 +	float d = dot(dist,dist); +		 +	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0); +	 +	return ret; +} + + +vec4 getPosition(ivec2 pos_screen, int sample) +{ +	float depth = texelFetch(depthMap, pos_screen, sample).r; +	vec2 sc = vec2(pos_screen.xy)*2.0; +	sc /= screen_res; +	sc -= vec2(1.0,1.0); +	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); +	vec4 pos = inv_proj * ndc; +	pos /= pos.w; +	pos.w = 1.0; +	return pos; +} + +void main()  +{ +	vec4 frag = vary_fragcoord; +	frag.xyz /= frag.w; +	frag.xyz = frag.xyz*0.5+0.5; +	frag.xy *= screen_res; +	ivec2 itc = ivec2(frag.xy); +	 +	vec3 fcol = vec3(0,0,0); +	int wght = 0; + +	for (int i = 0; i < samples; i++) +	{ +		vec3 pos = getPosition(itc, i).xyz; +		vec3 lv = vary_light.xyz-pos.xyz; +		float dist2 = dot(lv,lv); +		dist2 /= vary_light.w; +		if (dist2 <= 1.0) +		{ +			float shadow = 1.0; +	 +			if (proj_shadow_idx >= 0) +			{ +				vec4 shd = texelFetch(lightMap, itc, i); +				float sh[2]; +				sh[0] = shd.b; +				sh[1] = shd.a; +				shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0); +			} +	 +			vec3 norm = texelFetch(normalMap, itc, i).xyz; +			norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm +	 +			norm = normalize(norm); +			float l_dist = -dot(lv, proj_n); +	 +			vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); +			if (proj_tc.z >= 0.0) +			{ +				proj_tc.xyz /= proj_tc.w; +	 +				float fa = gl_Color.a+1.0; +				float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0); +				if (dist_atten > 0.0) +				{ +					lv = proj_origin-pos.xyz; +					lv = normalize(lv); +					float da = dot(norm, lv); +		 +					vec3 col = vec3(0,0,0); +		 +					vec3 diff_tex = texelFetch(diffuseRect, itc, i).rgb; +		 +					float noise = texture2D(noiseMap, frag.xy/128.0).b; +					if (proj_tc.z > 0.0 && +						proj_tc.x < 1.0 && +						proj_tc.y < 1.0 && +						proj_tc.x > 0.0 && +						proj_tc.y > 0.0) +					{ +						float lit = 0.0; +						float amb_da = proj_ambiance; +		 +						if (da > 0.0) +						{ +							float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0); +							float lod = diff * proj_lod; +			 +							vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod); +		 +							vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a; +			 +							lit = da * dist_atten * noise; +			 +							col = lcol*lit*diff_tex*shadow; +							amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance; +						} +		 +						//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); +						vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod); +							 +						amb_da += (da*da*0.5+0.5)*proj_ambiance; +				 +						amb_da *= dist_atten * noise; +			 +						amb_da = min(amb_da, 1.0-lit); +			 +						col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; +					} +	 +	 +					vec4 spec = texelFetch(specularRect, itc, i); +					if (spec.a > 0.0) +					{ +						vec3 ref = reflect(normalize(pos), norm); +		 +						//project from point pos in direction ref to plane proj_p, proj_n +						vec3 pdelta = proj_p-pos; +						float ds = dot(ref, proj_n); +		 +						if (ds < 0.0) +						{ +							vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; +			 +							vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0)); + +							if (stc.z > 0.0) +							{ +								stc.xy /= stc.w; + +								float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0); +				 +								stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); +								 +								if (stc.x < 1.0 && +									stc.y < 1.0 && +									stc.x > 0.0 && +									stc.y > 0.0) +								{ +									vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); +									col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb*shadow; +								} +							} +						} +					} + +					fcol += col; +					wght++; +				} +			} +		} +	} +	 +	if (wght <= 0) +	{ +		discard; +	} + +	gl_FragColor.rgb = fcol/wght;	 +	gl_FragColor.a = 0.0; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl index 4369b3b34f..b724c134b9 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl @@ -45,7 +45,7 @@ uniform float spot_shadow_offset;  vec4 getPosition(vec2 pos_screen)  { -	float depth = texture2DRect(depthMap, pos_screen.xy).a; +	float depth = texture2DRect(depthMap, pos_screen.xy).r;  	vec2 sc = pos_screen.xy*2.0;  	sc /= screen_res;  	sc -= vec2(1.0,1.0); diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightMSF.glsl new file mode 100644 index 0000000000..dd6fa958c9 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightMSF.glsl @@ -0,0 +1,202 @@ +/**  + * @file sunLightMSF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +#version 120 + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +//class 2, shadows, no SSAO + +uniform sampler2DMS depthMap; +uniform sampler2DMS normalMap; +uniform sampler2DRectShadow shadowMap0; +uniform sampler2DRectShadow shadowMap1; +uniform sampler2DRectShadow shadowMap2; +uniform sampler2DRectShadow shadowMap3; +uniform sampler2DShadow shadowMap4; +uniform sampler2DShadow shadowMap5; + + +// Inputs +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; +uniform float ssao_radius; +uniform float ssao_max_radius; +uniform float ssao_factor; +uniform float ssao_factor_inv; + +varying vec2 vary_fragcoord; +varying vec4 vary_light; + +uniform mat4 inv_proj; +uniform vec2 screen_res; +uniform vec2 shadow_res; +uniform vec2 proj_shadow_res; + +uniform float shadow_bias; +uniform float shadow_offset; + +uniform float spot_shadow_bias; +uniform float spot_shadow_offset; + +vec4 getPosition(ivec2 pos_screen, int sample) +{ +	float depth = texelFetch(depthMap, pos_screen.xy, sample).r; +	vec2 sc = vec2(pos_screen.xy)*2.0; +	sc /= screen_res; +	sc -= vec2(1.0,1.0); +	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); +	vec4 pos = inv_proj * ndc; +	pos /= pos.w; +	pos.w = 1.0; +	return pos; +} + +float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl) +{ +	stc.xyz /= stc.w; +	stc.z += shadow_bias*scl; +	 +	float cs = shadow2DRect(shadowMap, stc.xyz).x; +	float shadow = cs; + +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, 1.5, 0.0)).x, cs); +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, -1.5, 0.0)).x, cs); +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, 1.5, 0.0)).x, cs); +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, -1.5, 0.0)).x, cs); +			 +	return shadow/5.0; +	 +	//return shadow; +} + +float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl) +{ +	stc.xyz /= stc.w; +	stc.z += spot_shadow_bias*scl; +	 +	float cs = shadow2D(shadowMap, stc.xyz).x; +	float shadow = cs; + +	vec2 off = 1.5/proj_shadow_res; +	 +	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, off.y, 0.0)).x, cs); +	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x, cs); +	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x, cs); +	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, -off.y, 0.0)).x, cs); +				 +	return shadow/5.0; +	 +	//return shadow; +} + +void main()  +{ +	vec2 pos_screen = vary_fragcoord.xy; +	ivec2 itc = ivec2(pos_screen); + +	//try doing an unproject here +	 +	vec4 fcol = vec4(0,0,0,0); + +	for (int i = 0; i < samples; i++) +	{ +		vec4 pos = getPosition(itc, i); +	 +		vec4 nmap4 = texelFetch(normalMap, itc, i); +		nmap4 = vec4((nmap4.xy-0.5)*2.0,nmap4.z,nmap4.w); // unpack norm +		float displace = nmap4.w; +		vec3 norm = nmap4.xyz; +	 +		/*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL +		{ +			gl_FragColor = vec4(0.0); // doesn't matter +			return; +		}*/ +	 +		float shadow = 1.0; +		float dp_directional_light = max(0.0, dot(norm, vary_light.xyz)); + +		vec3 shadow_pos = pos.xyz + displace*norm; +		vec3 offset = vary_light.xyz * (1.0-dp_directional_light); +	 +		vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0); +	 +		if (spos.z > -shadow_clip.w) +		{	 +			if (dp_directional_light == 0.0) +			{ +				// if we know this point is facing away from the sun then we know it's in shadow without having to do a squirrelly shadow-map lookup +				shadow = 0.0; +			} +			else +			{ +				vec4 lpos; +			 +				if (spos.z < -shadow_clip.z) +				{ +					lpos = shadow_matrix[3]*spos; +					lpos.xy *= shadow_res; +					shadow = pcfShadow(shadowMap3, lpos, 0.25); +					shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); +				} +				else if (spos.z < -shadow_clip.y) +				{ +					lpos = shadow_matrix[2]*spos; +					lpos.xy *= shadow_res; +					shadow = pcfShadow(shadowMap2, lpos, 0.5); +				} +				else if (spos.z < -shadow_clip.x) +				{ +					lpos = shadow_matrix[1]*spos; +					lpos.xy *= shadow_res; +					shadow = pcfShadow(shadowMap1, lpos, 0.75); +				} +				else +				{ +					lpos = shadow_matrix[0]*spos; +					lpos.xy *= shadow_res; +					shadow = pcfShadow(shadowMap0, lpos, 1.0); +				} +		 +				// take the most-shadowed value out of these two: +				//  * the blurred sun shadow in the light (shadow) map +				//  * an unblurred dot product between the sun and this norm +				// the goal is to err on the side of most-shadow to fill-in shadow holes and reduce artifacting +				shadow = min(shadow, dp_directional_light); +			 +				//lpos.xy /= lpos.w*32.0; +				//if (fract(lpos.x) < 0.1 || fract(lpos.y) < 0.1) +				//{ +				//	shadow = 0.0; +				//} +			 +			} +		} +		else +		{ +			// more distant than the shadow map covers +			shadow = 1.0; +		} +	 +		fcol[0] += shadow; +		fcol[1] += 1.0; + +		spos = vec4(shadow_pos+norm*spot_shadow_offset, 1.0); +	 +		//spotlight shadow 1 +		vec4 lpos = shadow_matrix[4]*spos; +		fcol[2] += pcfShadow(shadowMap4, lpos, 0.8);  +	 +		//spotlight shadow 2 +		lpos = shadow_matrix[5]*spos; +		fcol[3] += pcfShadow(shadowMap5, lpos, 0.8);  +	} + +	gl_FragColor = fcol/samples; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl index 847b36b1ac..68e18162f6 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl @@ -45,7 +45,7 @@ uniform float spot_shadow_offset;  vec4 getPosition(vec2 pos_screen)  { -	float depth = texture2DRect(depthMap, pos_screen.xy).a; +	float depth = texture2DRect(depthMap, pos_screen.xy).r;  	vec2 sc = pos_screen.xy*2.0;  	sc /= screen_res;  	sc -= vec2(1.0,1.0); diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOMSF.glsl new file mode 100644 index 0000000000..d28741f945 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOMSF.glsl @@ -0,0 +1,241 @@ +/**  + * @file sunLightSSAOF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +  +#version 120 + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +//class 2 -- shadows and SSAO + +uniform sampler2DMS depthMap; +uniform sampler2DMS normalMap; +uniform sampler2DRectShadow shadowMap0; +uniform sampler2DRectShadow shadowMap1; +uniform sampler2DRectShadow shadowMap2; +uniform sampler2DRectShadow shadowMap3; +uniform sampler2DShadow shadowMap4; +uniform sampler2DShadow shadowMap5; +uniform sampler2D noiseMap; + +// Inputs +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; +uniform float ssao_radius; +uniform float ssao_max_radius; +uniform float ssao_factor; +uniform float ssao_factor_inv; + +varying vec2 vary_fragcoord; +varying vec4 vary_light; + +uniform mat4 inv_proj; +uniform vec2 screen_res; +uniform vec2 shadow_res; +uniform vec2 proj_shadow_res; + +uniform float shadow_bias; +uniform float shadow_offset; + +uniform float spot_shadow_bias; +uniform float spot_shadow_offset; + +vec4 getPosition(ivec2 pos_screen, int sample) +{ +	float depth = texelFetch(depthMap, pos_screen, sample).r; +	vec2 sc = vec2(pos_screen.xy)*2.0; +	sc /= screen_res; +	sc -= vec2(1.0,1.0); +	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); +	vec4 pos = inv_proj * ndc; +	pos /= pos.w; +	pos.w = 1.0; +	return pos; +} + +//calculate decreases in ambient lighting when crowded out (SSAO) +float calcAmbientOcclusion(vec4 pos, vec3 norm, int sample) +{ +	float ret = 1.0; + +	vec2 kern[8]; +	// exponentially (^2) distant occlusion samples spread around origin +	kern[0] = vec2(-1.0, 0.0) * 0.125*0.125; +	kern[1] = vec2(1.0, 0.0) * 0.250*0.250; +	kern[2] = vec2(0.0, 1.0) * 0.375*0.375; +	kern[3] = vec2(0.0, -1.0) * 0.500*0.500; +	kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625; +	kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750; +	kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875; +	kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000; + +	vec2 pos_screen = vary_fragcoord.xy; +	vec3 pos_world = pos.xyz; +	vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy; +		 +	float angle_hidden = 0.0; +	int points = 0; +		 +	float scale = min(ssao_radius / -pos_world.z, ssao_max_radius); +		 +	// it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?) +	for (int i = 0; i < 8; i++) +	{ +		ivec2 samppos_screen = ivec2(pos_screen + scale * reflect(kern[i], noise_reflect)); +		vec3 samppos_world = getPosition(samppos_screen, sample).xyz;  +			 +		vec3 diff = pos_world - samppos_world; +		float dist2 = dot(diff, diff); +			 +		// assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area +		// --> solid angle shrinking by the square of distance +		//radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2 +		//(k should vary inversely with # of samples, but this is taken care of later) +			 +		angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv); +			 +		// 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion"  +		points = points + int(diff.z > -1.0); +	} +		 +	angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0); +		 +	ret = (1.0 - (float(points != 0) * angle_hidden)); +	 +	return min(ret, 1.0); +} + +float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl) +{ +	stc.xyz /= stc.w; +	stc.z += shadow_bias*scl; +	 +	float cs = shadow2DRect(shadowMap, stc.xyz).x; +	float shadow = cs; + +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, 1.5, 0.0)).x, cs); +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, -1.5, 0.0)).x, cs); +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, 1.5, 0.0)).x, cs); +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, -1.5, 0.0)).x, cs); +			 +	return shadow/5.0; +	 +	//return shadow; +} + +float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl) +{ +	stc.xyz /= stc.w; +	stc.z += spot_shadow_bias*scl; +	 +	float cs = shadow2D(shadowMap, stc.xyz).x; +	float shadow = cs; + +	vec2 off = 1.5/proj_shadow_res; +	 +	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, off.y, 0.0)).x, cs); +	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x, cs); +	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x, cs); +	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, -off.y, 0.0)).x, cs); +	 +			 +	return shadow/5.0; +	 +	//return shadow; +} + +void main()  +{ +	vec2 pos_screen = vary_fragcoord.xy; +	ivec2 itc = ivec2(pos_screen); +	vec4 fcol = vec4(0,0,0,0); + +	for (int i = 0; i < samples; i++) +	{ +		vec4 pos = getPosition(itc, i); +	 +		vec4 nmap4 = texelFetch(normalMap, itc, i); +		nmap4 = vec4((nmap4.xy-0.5)*2.0,nmap4.z,nmap4.w); // unpack norm +		float displace = nmap4.w; +		vec3 norm = nmap4.xyz; +	 +		float shadow = 1.0; +		float dp_directional_light = max(0.0, dot(norm, vary_light.xyz)); + +		vec3 shadow_pos = pos.xyz + displace*norm; +		vec3 offset = vary_light.xyz * (1.0-dp_directional_light); +	 +		vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0); +	 +		if (spos.z > -shadow_clip.w) +		{	 +			if (dp_directional_light == 0.0) +			{ +				// if we know this point is facing away from the sun then we know it's in shadow without having to do a squirrelly shadow-map lookup +				shadow = 0.0; +			} +			else +			{ +				vec4 lpos; +			 +				if (spos.z < -shadow_clip.z) +				{ +					lpos = shadow_matrix[3]*spos; +					lpos.xy *= shadow_res; +					shadow = pcfShadow(shadowMap3, lpos, 0.25); +					shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); +				} +				else if (spos.z < -shadow_clip.y) +				{ +					lpos = shadow_matrix[2]*spos; +					lpos.xy *= shadow_res; +					shadow = pcfShadow(shadowMap2, lpos, 0.5); +				} +				else if (spos.z < -shadow_clip.x) +				{ +					lpos = shadow_matrix[1]*spos; +					lpos.xy *= shadow_res; +					shadow = pcfShadow(shadowMap1, lpos, 0.75); +				} +				else +				{ +					lpos = shadow_matrix[0]*spos; +					lpos.xy *= shadow_res; +					shadow = pcfShadow(shadowMap0, lpos, 1.0); +				} +		 +				// take the most-shadowed value out of these two: +				//  * the blurred sun shadow in the light (shadow) map +				//  * an unblurred dot product between the sun and this norm +				// the goal is to err on the side of most-shadow to fill-in shadow holes and reduce artifacting +				shadow = min(shadow, dp_directional_light); +			 +			} +		} +		else +		{ +			// more distant than the shadow map covers +			shadow = 1.0; +		} +	 +		 +		fcol[0] += shadow; +		fcol[1] += calcAmbientOcclusion(pos, norm, i); + +		spos.xyz = shadow_pos+offset*spot_shadow_offset; +	 +		//spotlight shadow 1 +		vec4 lpos = shadow_matrix[4]*spos; +		fcol[2] += pcfShadow(shadowMap4, lpos, 0.8);  +	 +		//spotlight shadow 2 +		lpos = shadow_matrix[5]*spos; +		fcol[3] += pcfShadow(shadowMap5, lpos, 0.8);  +	} +		 +	gl_FragColor = fcol / samples; +} | 
