diff options
| author | Dave Parks <davep@lindenlab.com> | 2012-02-17 19:40:48 -0600 | 
|---|---|---|
| committer | Dave Parks <davep@lindenlab.com> | 2012-02-17 19:40:48 -0600 | 
| commit | 48f5b69c43d4d4a2b6e272f7ac8d706ccc0c0601 (patch) | |
| tree | 5d4c1f717d110e20b866901ee3a9fb9eb846293c | |
| parent | 6ecae04d358cc27bc4890778a1493b3818236fb9 (diff) | |
SH-2915 Smoother transition between sun shadow splits.
10 files changed, 215 insertions, 63 deletions
| diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl index 73f05a5dd4..dd87ddb330 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl @@ -35,8 +35,6 @@ uniform sampler2DRect depthMap;  vec4 diffuseLookup(vec2 texcoord); -uniform mat4 shadow_matrix[6]; -uniform vec4 shadow_clip;  uniform vec2 screen_res;  vec3 atmosLighting(vec3 light); diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl index bfbd30a455..beb3290187 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl @@ -35,8 +35,6 @@ uniform sampler2DRect depthMap;  uniform sampler2D diffuseMap; -uniform mat4 shadow_matrix[6]; -uniform vec4 shadow_clip;  uniform vec2 screen_res;  vec3 atmosLighting(vec3 light); diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl index dae1131bbb..cb87b754b4 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl @@ -34,8 +34,6 @@ out vec4 frag_color;  uniform sampler2DRect depthMap;  uniform sampler2D diffuseMap; -uniform mat4 shadow_matrix[6]; -uniform vec4 shadow_clip;  uniform vec2 screen_res;  vec3 atmosLighting(vec3 light); diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl index 7fa666a739..2422d73a3e 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl @@ -39,8 +39,6 @@ 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; @@ -51,9 +49,6 @@ VARYING vec2 vary_fragcoord;  uniform mat4 inv_proj;  uniform vec2 screen_res; -uniform float shadow_bias; -uniform float shadow_offset; -  vec4 getPosition(vec2 pos_screen)  {  	float depth = texture2DRect(depthMap, pos_screen.xy).r; diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl index e5edb482a9..08f6ec63fe 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl @@ -80,7 +80,7 @@ void main()  	vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;  	frag *= screen_res; -	float shadow = 1.0; +	float shadow = 0.0;  	vec4 pos = vec4(vary_position, 1.0);  	vec4 spos = pos; @@ -89,31 +89,65 @@ void main()  	{	  		vec4 lpos; -		if (spos.z < -shadow_clip.z) +		vec4 near_split = shadow_clip*-0.75; +		vec4 far_split = shadow_clip*-1.25; +		vec4 transition_domain = near_split-far_split; +		float weight = 0.0; + +		if (spos.z < near_split.z)  		{  			lpos = shadow_matrix[3]*spos;  			lpos.xy *= shadow_res; -			shadow = pcfShadow(shadowMap3, lpos, 1.5); + +			float w = 1.0; +			w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; +			shadow += pcfShadow(shadowMap3, lpos, 0.25)*w; +			weight += w;  			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) + +		if (spos.z < near_split.y && spos.z > far_split.z)  		{  			lpos = shadow_matrix[2]*spos;  			lpos.xy *= shadow_res; -			shadow = pcfShadow(shadowMap2, lpos, 1.5); + +			float w = 1.0; +			w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; +			w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; +			shadow += pcfShadow(shadowMap2, lpos, 0.75)*w; +			weight += w;  		} -		else if (spos.z < -shadow_clip.x) + +		if (spos.z < near_split.x && spos.z > far_split.y)  		{  			lpos = shadow_matrix[1]*spos;  			lpos.xy *= shadow_res; -			shadow = pcfShadow(shadowMap1, lpos, 1.5); + +			float w = 1.0; +			w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; +			w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; +			shadow += pcfShadow(shadowMap1, lpos, 0.75)*w; +			weight += w;  		} -		else + +		if (spos.z > far_split.x)  		{  			lpos = shadow_matrix[0]*spos;  			lpos.xy *= shadow_res; -			shadow = pcfShadow(shadowMap0, lpos, 1.5); +				 +			float w = 1.0; +			w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; +				 +			shadow += pcfShadow(shadowMap0, lpos, 1.0)*w; +			weight += w;  		} +		 + +		shadow /= weight; +	} +	else +	{ +		shadow = 1.0;  	}  	vec4 diff = diffuseLookup(vary_texcoord0.xy); diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl index c467e6c5cb..aae6a070e2 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl @@ -93,7 +93,7 @@ void main()  	vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;  	frag *= screen_res; -	float shadow = 1.0; +	float shadow = 0.0;  	vec4 pos = vec4(vary_position, 1.0);  	vec4 spos = pos; @@ -102,33 +102,68 @@ void main()  	{	  		vec4 lpos; -		if (spos.z < -shadow_clip.z) +		vec4 near_split = shadow_clip*-0.75; +		vec4 far_split = shadow_clip*-1.25; +		vec4 transition_domain = near_split-far_split; +		float weight = 0.0; + +		if (spos.z < near_split.z)  		{  			lpos = shadow_matrix[3]*spos;  			lpos.xy *= shadow_res; -			shadow = pcfShadow(shadowMap3, lpos, 1.5); + +			float w = 1.0; +			w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; +			shadow += pcfShadow(shadowMap3, lpos, 0.25)*w; +			weight += w;  			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) + +		if (spos.z < near_split.y && spos.z > far_split.z)  		{  			lpos = shadow_matrix[2]*spos;  			lpos.xy *= shadow_res; -			shadow = pcfShadow(shadowMap2, lpos, 1.5); + +			float w = 1.0; +			w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; +			w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; +			shadow += pcfShadow(shadowMap2, lpos, 0.75)*w; +			weight += w;  		} -		else if (spos.z < -shadow_clip.x) + +		if (spos.z < near_split.x && spos.z > far_split.y)  		{  			lpos = shadow_matrix[1]*spos;  			lpos.xy *= shadow_res; -			shadow = pcfShadow(shadowMap1, lpos, 1.5); + +			float w = 1.0; +			w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; +			w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; +			shadow += pcfShadow(shadowMap1, lpos, 0.75)*w; +			weight += w;  		} -		else + +		if (spos.z > far_split.x)  		{  			lpos = shadow_matrix[0]*spos;  			lpos.xy *= shadow_res; -			shadow = pcfShadow(shadowMap0, lpos, 1.5); +				 +			float w = 1.0; +			w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; +				 +			shadow += pcfShadow(shadowMap0, lpos, 1.0)*w; +			weight += w;  		} +		 + +		shadow /= weight; +  	} -	 +	else +	{ +		shadow = 1.0; +	} +  	vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy);  	vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, vertex_color.a); diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl index 8aaf87a1b5..931577359e 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl @@ -92,7 +92,7 @@ void main()  	vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;  	frag *= screen_res; -	float shadow = 1.0; +	float shadow = 0.0;  	vec4 pos = vec4(vary_position, 1.0);  	vec4 spos = pos; @@ -101,31 +101,65 @@ void main()  	{	  		vec4 lpos; -		if (spos.z < -shadow_clip.z) +		vec4 near_split = shadow_clip*-0.75; +		vec4 far_split = shadow_clip*-1.25; +		vec4 transition_domain = near_split-far_split; +		float weight = 0.0; + +		if (spos.z < near_split.z)  		{  			lpos = shadow_matrix[3]*spos;  			lpos.xy *= shadow_res; -			shadow = pcfShadow(shadowMap3, lpos, 1.5); + +			float w = 1.0; +			w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; +			shadow += pcfShadow(shadowMap3, lpos, 0.25)*w; +			weight += w;  			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) + +		if (spos.z < near_split.y && spos.z > far_split.z)  		{  			lpos = shadow_matrix[2]*spos;  			lpos.xy *= shadow_res; -			shadow = pcfShadow(shadowMap2, lpos, 1.5); + +			float w = 1.0; +			w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; +			w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; +			shadow += pcfShadow(shadowMap2, lpos, 0.75)*w; +			weight += w;  		} -		else if (spos.z < -shadow_clip.x) + +		if (spos.z < near_split.x && spos.z > far_split.y)  		{  			lpos = shadow_matrix[1]*spos;  			lpos.xy *= shadow_res; -			shadow = pcfShadow(shadowMap1, lpos, 1.5); + +			float w = 1.0; +			w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; +			w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; +			shadow += pcfShadow(shadowMap1, lpos, 0.75)*w; +			weight += w;  		} -		else + +		if (spos.z > far_split.x)  		{  			lpos = shadow_matrix[0]*spos;  			lpos.xy *= shadow_res; -			shadow = pcfShadow(shadowMap0, lpos, 1.5); +				 +			float w = 1.0; +			w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; +				 +			shadow += pcfShadow(shadowMap0, lpos, 1.0)*w; +			weight += w;  		} +		 + +		shadow /= weight; +	} +	else +	{ +		shadow = 1.0;  	}  	vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy); diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl index a40b29d2c4..8c4ccf9cb3 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl @@ -135,7 +135,7 @@ void main()  		return;  	}*/ -	float shadow = 1.0; +	float shadow = 0.0;  	float dp_directional_light = max(0.0, dot(norm, sun_dir.xyz));  	vec3 shadow_pos = pos.xyz + displace*norm; @@ -154,32 +154,62 @@ void main()  		{  			vec4 lpos; -			if (spos.z < -shadow_clip.z) +			vec4 near_split = shadow_clip*-0.75; +			vec4 far_split = shadow_clip*-1.25; +			vec4 transition_domain = near_split-far_split; +			float weight = 0.0; + +			if (spos.z < near_split.z)  			{  				lpos = shadow_matrix[3]*spos;  				lpos.xy *= shadow_res; -				shadow = pcfShadow(shadowMap3, lpos, 0.25); + +				float w = 1.0; +				w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; +				shadow += pcfShadow(shadowMap3, lpos, 0.25)*w; +				weight += w;  				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) + +			if (spos.z < near_split.y && spos.z > far_split.z)  			{  				lpos = shadow_matrix[2]*spos;  				lpos.xy *= shadow_res; -				shadow = pcfShadow(shadowMap2, lpos, 0.5); + +				float w = 1.0; +				w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; +				w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; +				shadow += pcfShadow(shadowMap2, lpos, 0.75)*w; +				weight += w;  			} -			else if (spos.z < -shadow_clip.x) + +			if (spos.z < near_split.x && spos.z > far_split.y)  			{  				lpos = shadow_matrix[1]*spos;  				lpos.xy *= shadow_res; -				shadow = pcfShadow(shadowMap1, lpos, 0.75); + +				float w = 1.0; +				w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; +				w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; +				shadow += pcfShadow(shadowMap1, lpos, 0.75)*w; +				weight += w;  			} -			else + +			if (spos.z > far_split.x)  			{  				lpos = shadow_matrix[0]*spos;  				lpos.xy *= shadow_res; -				shadow = pcfShadow(shadowMap0, lpos, 1.0); +				 +				float w = 1.0; +				w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; +				 +				shadow += pcfShadow(shadowMap0, lpos, 1.0)*w; +				weight += w;  			} + +			shadow /= weight; +  			// 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 diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl index 774f70262a..02075a7687 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl @@ -196,7 +196,7 @@ void main()  		return;  	}*/ -	float shadow = 1.0; +	float shadow = 0.0;  	float dp_directional_light = max(0.0, dot(norm, sun_dir.xyz));  	vec3 shadow_pos = pos.xyz + displace*norm; @@ -214,33 +214,63 @@ void main()  		else  		{  			vec4 lpos; -			 -			if (spos.z < -shadow_clip.z) + +			vec4 near_split = shadow_clip*-0.75; +			vec4 far_split = shadow_clip*-1.25; +			vec4 transition_domain = near_split-far_split; +			float weight = 0.0; + +			if (spos.z < near_split.z)  			{  				lpos = shadow_matrix[3]*spos;  				lpos.xy *= shadow_res; -				shadow = pcfShadow(shadowMap3, lpos, 0.25); + +				float w = 1.0; +				w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; +				shadow += pcfShadow(shadowMap3, lpos, 0.25)*w; +				weight += w;  				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) + +			if (spos.z < near_split.y && spos.z > far_split.z)  			{  				lpos = shadow_matrix[2]*spos;  				lpos.xy *= shadow_res; -				shadow = pcfShadow(shadowMap2, lpos, 0.5); + +				float w = 1.0; +				w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; +				w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; +				shadow += pcfShadow(shadowMap2, lpos, 0.75)*w; +				weight += w;  			} -			else if (spos.z < -shadow_clip.x) + +			if (spos.z < near_split.x && spos.z > far_split.y)  			{  				lpos = shadow_matrix[1]*spos;  				lpos.xy *= shadow_res; -				shadow = pcfShadow(shadowMap1, lpos, 0.75); + +				float w = 1.0; +				w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; +				w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; +				shadow += pcfShadow(shadowMap1, lpos, 0.75)*w; +				weight += w;  			} -			else + +			if (spos.z > far_split.x)  			{  				lpos = shadow_matrix[0]*spos;  				lpos.xy *= shadow_res; -				shadow = pcfShadow(shadowMap0, lpos, 1.0); +				 +				float w = 1.0; +				w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; +				 +				shadow += pcfShadow(shadowMap0, lpos, 1.0)*w; +				weight += w;  			} + +			shadow /= weight; +  			// 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 diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index ce3a4893bf..d5bcfe12ab 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -8817,16 +8817,16 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  		da = powf(da, split_exp.mV[2]); -  		F32 sxp = split_exp.mV[1] + (split_exp.mV[0]-split_exp.mV[1])*da; - - +		  		for (U32 i = 0; i < 4; ++i)  		{  			F32 x = (F32)(i+1)/4.f;  			x = powf(x, sxp);  			mSunClipPlanes.mV[i] = near_clip+range*x;  		} + +		mSunClipPlanes.mV[0] *= 1.25f; //bump back first split for transition padding  	}  	// convenience array of 4 near clip plane distances @@ -8883,8 +8883,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  				delta += (frust[i+4]-frust[(i+2)%4+4])*0.05f;  				delta.normVec();  				F32 dp = delta*pn; -				frust[i] = eye + (delta*dist[j]*0.95f)/dp; -				frust[i+4] = eye + (delta*dist[j+1]*1.05f)/dp; +				frust[i] = eye + (delta*dist[j]*0.75f)/dp; +				frust[i+4] = eye + (delta*dist[j+1]*1.25f)/dp;  			}  			shadow_cam.calcAgentFrustumPlanes(frust); | 
