diff options
Diffstat (limited to 'indra/newview')
63 files changed, 1947 insertions, 1264 deletions
| diff --git a/indra/newview/app_settings/high_graphics.xml b/indra/newview/app_settings/high_graphics.xml index 6368f7099e..93d39c8414 100644 --- a/indra/newview/app_settings/high_graphics.xml +++ b/indra/newview/app_settings/high_graphics.xml @@ -12,8 +12,6 @@  	<RenderFlexTimeFactor value="1"/>  	<!--256... but they don't use this-->  	<RenderGlowResolutionPow value="9"/> -	<!--Sun/Moon only--> -	<RenderLightingDetail value="1"/>  	<!--Low number-->  	<RenderMaxPartCount value="4096"/>  	<!--bump okay--> @@ -31,9 +29,14 @@  	<!--Default for now-->  	<RenderVolumeLODFactor value="1.125"/>  	<!--NO SHADERS--> -	<RenderWaterReflections value="FALSE"/> -	<!--NO SHADERS-->  	<VertexShaderEnable value="TRUE"/>  	<!--NO SHADERS-->  	<WindLightUseAtmosShaders value="TRUE"/> +  <!--Deferred Shading--> +  <RenderDeferred value="TRUE"/> +  <!--SSAO Disabled--> +  <RenderDeferredSSAO value="FALSE"/> +  <!--Sun Shadows--> +  <RenderShadowDetail value="1"/> +  </settings> diff --git a/indra/newview/app_settings/keywords.ini b/indra/newview/app_settings/keywords.ini index 0805e94b10..18edce42a4 100644 --- a/indra/newview/app_settings/keywords.ini +++ b/indra/newview/app_settings/keywords.ini @@ -353,6 +353,11 @@ PRIM_BUMP_SHINY		Followed by an integer face, one of PRIM_SHINY_NONE, PRIM_SHINY  PRIM_FULLBRIGHT		Followed by an integer face, and TRUE or FALSE  PRIM_TEXGEN			Followed by an integer face, and one of PRIM_TEXGEN_DEFAULT or PRIM_TEXGEN_PLANAR  PRIM_GLOW			Followed by an integer face, and a float from 0.0 to 1.0 specifying glow amount +PRIM_PHYSICS_SHAPE_TYPE Followed by one of PRIM_PHYSICS_SHAPE_PRIM (use prim as-is for physics), PRIM_PHYSICS_SHAPE_NONE (do not use prim for physics), PRIM_PHYSICS_SHAPE_CONVEX (use convex hull of prim for physics) + +PRIM_PHYSICS_SHAPE_PRIM     Sets the physics shape type to PRIM (i.e., use the prim as-is in the physics engine) +PRIM_PHYSICS_SHAPE_NONE     Sets the physics shape type to NONE (i.e., the shape will not exist the physics engine) +PRIM_PHYSICS_SHAPE_CONVEX   Sets the physics shape type to CONVEX (i.e., use the convex hull of the prim in the physics engine)  PRIM_TYPE_BOX		Followed by integer hole shape, vector cut, float hollow, vector twist,:vector top size, and vector top shear  PRIM_TYPE_CYLINDER	Followed by integer hole shape, vector cut, float hollow, vector twist,:vector top size, and vector top shear diff --git a/indra/newview/app_settings/low_graphics.xml b/indra/newview/app_settings/low_graphics.xml index 3f67a70d7a..a300c8646c 100644 --- a/indra/newview/app_settings/low_graphics.xml +++ b/indra/newview/app_settings/low_graphics.xml @@ -12,8 +12,6 @@  	<RenderFlexTimeFactor value="0.5"/>  	<!--256... but they don't use this-->  	<RenderGlowResolutionPow value="8"/> -	<!--Sun/Moon only--> -	<RenderLightingDetail value="0"/>  	<!--Low number-->  	<RenderMaxPartCount value="1024"/>  	<!--bump okay--> @@ -31,9 +29,14 @@  	<!--Default for now-->  	<RenderVolumeLODFactor value="1.125"/>  	<!--NO SHADERS--> -	<RenderWaterReflections value="FALSE"/> -	<!--NO SHADERS-->  	<VertexShaderEnable value="FALSE"/>  	<!--NO SHADERS-->  	<WindLightUseAtmosShaders value="FALSE"/> +  <!--No Deferred Shading--> +  <RenderDeferred value="FALSE"/> +  <!--SSAO Disabled--> +  <RenderDeferredSSAO value="FALSE"/> +  <!--No Shadows--> +  <RenderShadowDetail value="0"/> +  </settings> diff --git a/indra/newview/app_settings/mid_graphics.xml b/indra/newview/app_settings/mid_graphics.xml index 12da77da40..a1430a58f9 100644 --- a/indra/newview/app_settings/mid_graphics.xml +++ b/indra/newview/app_settings/mid_graphics.xml @@ -12,8 +12,6 @@  	<RenderFlexTimeFactor value="1"/>  	<!--256... but they don't use this-->  	<RenderGlowResolutionPow value="8"/> -	<!--Sun/Moon only--> -	<RenderLightingDetail value="1"/>  	<!--Low number-->  	<RenderMaxPartCount value="2048"/>  	<!--bump okay--> @@ -31,9 +29,14 @@  	<!--Default for now-->  	<RenderVolumeLODFactor value="1.125"/>  	<!--NO SHADERS--> -	<RenderWaterReflections value="FALSE"/> -	<!--NO SHADERS-->  	<VertexShaderEnable value="TRUE"/>  	<!--NO SHADERS-->  	<WindLightUseAtmosShaders value="FALSE"/> +  <!--No Deferred Shading--> +  <RenderDeferred value="FALSE"/> +  <!--SSAO Disabled--> +  <RenderDeferredSSAO value="FALSE"/> +  <!--No Shadows--> +  <RenderShadowDetail value="0"/> +  </settings> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 8b66cce8a3..ef1a7b670f 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -6094,7 +6094,7 @@      <key>Type</key>      <string>U32</string>      <key>Value</key> -    <integer>60</integer> +    <integer>200</integer>    </map>    <key>RenderSSAOFactor</key>    <map> @@ -6618,19 +6618,7 @@      <key>Value</key>      <integer>0</integer>    </map> - -  <key>RenderDeferredShadow</key> -  <map> -    <key>Comment</key> -    <string>Enable shadows in deferred renderer.</string> -    <key>Persist</key> -    <integer>1</integer> -    <key>Type</key> -    <string>Boolean</string> -    <key>Value</key> -    <integer>1</integer> -  </map> - +      <key>RenderDeferredGI</key>    <map>      <key>Comment</key> @@ -6643,10 +6631,10 @@      <integer>0</integer>    </map> -  <key>RenderDeferredSunShadow</key> +  <key>RenderDeferredSun</key>    <map>      <key>Comment</key> -    <string>Generate shadows from the sun.</string> +    <string>Execute sunlight shader in deferred renderer.</string>      <key>Persist</key>      <integer>1</integer>      <key>Type</key> @@ -6655,10 +6643,10 @@      <integer>1</integer>    </map> -  <key>RenderDeferredSun</key> +  <key>RenderDeferredAtmospheric</key>    <map>      <key>Comment</key> -    <string>Execute sunlight shader in deferred renderer.</string> +    <string>Execute atmospheric shader in deferred renderer.</string>      <key>Persist</key>      <integer>1</integer>      <key>Type</key> @@ -6667,10 +6655,10 @@      <integer>1</integer>    </map> -  <key>RenderDeferredAtmospheric</key> +  <key>RenderDeferredSSAO</key>    <map>      <key>Comment</key> -    <string>Execute atmospheric shader in deferred renderer.</string> +    <string>Execute screen space ambient occlusion shader in deferred renderer.</string>      <key>Persist</key>      <integer>1</integer>      <key>Type</key> @@ -7201,17 +7189,6 @@        <key>Value</key>        <integer>0</integer>      </map> -    <key>RenderLightingDetail</key> -    <map> -      <key>Comment</key> -      <string>Amount of detail for lighting objects/avatars/terrain (0=sun/moon only, 1=enable local lights)</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>S32</string> -      <key>Value</key> -      <integer>1</integer> -    </map>      <key>RenderMaxPartCount</key>      <map>        <key>Comment</key> @@ -7311,7 +7288,19 @@        <key>Value</key>        <integer>2</integer>      </map> -    <key>RenderReflectionRes</key> +    <key>RenderShadowDetail</key> +    <map> +      <key>Comment</key> +      <string>Detail of shadows.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>S32</string> +      <key>Value</key> +      <integer>2</integer> +    </map> + +  <key>RenderReflectionRes</key>      <map>        <key>Comment</key>        <string>Reflection map resolution.</string> @@ -7441,7 +7430,7 @@        <key>Type</key>        <string>Boolean</string>        <key>Value</key> -      <integer>0</integer> +      <integer>1</integer>      </map>      <key>RenderUIBuffer</key>      <map> @@ -7542,6 +7531,17 @@        <key>Value</key>        <integer>1</integer>      </map> +  <key>RenderUseStreamVBO</key> +  <map> +    <key>Comment</key> +    <string>Use VBO's for stream buffers</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>1</integer> +  </map>      <key>RenderVolumeLODFactor</key>      <map>        <key>Comment</key> @@ -7586,17 +7586,6 @@        <key>Value</key>        <integer>512</integer>      </map> -    <key>RenderWaterReflections</key> -    <map> -      <key>Comment</key> -      <string>Reflect the environment in the water.</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>Boolean</string> -      <key>Value</key> -      <integer>0</integer> -    </map>      <key>RotateRight</key>      <map>        <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl index 4fb109d687..fea2e16090 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl @@ -24,8 +24,6 @@ varying vec3 vary_fragcoord;  varying vec3 vary_position;  varying vec3 vary_light; -uniform float alpha_soften; -  uniform mat4 inv_proj;  vec4 getPosition(vec2 pos_screen) @@ -57,15 +55,6 @@ void main()  	color.rgb = scaleSoftClip(color.rgb); -	if (samp_pos.z != 0.0 && gl_Color.a < 1.0) -	{ -		float dist_factor = alpha_soften; -		float a = gl_Color.a; -		a *= a; -		dist_factor *= 1.0/(1.0-a); -		color.a *= min((pos.z-samp_pos.z)*dist_factor, 1.0); -	} -	  	//gl_FragColor = gl_Color;  	gl_FragColor = color;  	//gl_FragColor = vec4(1,0,1,1); diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl index 1a7d58b07b..04e556c11a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl @@ -9,7 +9,7 @@ vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);  void calcAtmospherics(vec3 inPositionEye);  float calcDirectionalLight(vec3 n, vec3 l); -float calcPointLight(vec3 v, vec3 n, vec4 lp, float la); +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);  vec3 atmosAmbient(vec3 light);  vec3 atmosAffectDirectionalLight(float lightIntensity); @@ -41,23 +41,22 @@ void main()  	calcAtmospherics(pos.xyz);  	//vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.)); -	vec4 col; -	col.a = gl_Color.a; -	 -	// Add windlight lights -	col.rgb = atmosAmbient(vec3(0.)); -	col.rgb = scaleUpLight(col.rgb); + +	vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a);  	// Collect normal lights (need to be divided by two, as we later multiply by 2) -	col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation); -	col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation); -	col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation); -	col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].linearAttenuation); - 	col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].linearAttenuation); - 	col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].linearAttenuation); +	col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a); +	col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a); +	col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a); +	col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].specular.a); +	col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].specular.a); +	col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].specular.a);  	col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz);  	col.rgb = scaleDownLight(col.rgb); +	// Add windlight lights +	col.rgb += atmosAmbient(vec3(0.)); +	  	vary_light = gl_LightSource[0].position.xyz;  	vary_ambient = col.rgb*gl_Color.rgb; diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl index c1988d3c78..650fbcc3f5 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl @@ -10,7 +10,7 @@ mat4 getSkinnedTransform();  void calcAtmospherics(vec3 inPositionEye);  float calcDirectionalLight(vec3 n, vec3 l); -float calcPointLight(vec3 v, vec3 n, vec4 lp, float la); +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);  vec3 atmosAmbient(vec3 light);  vec3 atmosAffectDirectionalLight(float lightIntensity); @@ -47,23 +47,22 @@ void main()  	calcAtmospherics(pos.xyz);  	//vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.)); -	vec4 col; -	col.a = gl_Color.a; -	 -	// Add windlight lights -	col.rgb = atmosAmbient(vec3(0.)); -	col.rgb = scaleUpLight(col.rgb); + +	vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a);  	// Collect normal lights (need to be divided by two, as we later multiply by 2) -	col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation); -	col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation); -	col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation); -	col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].linearAttenuation); - 	col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].linearAttenuation); - 	col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].linearAttenuation); +	col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a); +	col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a); +	col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a); +	col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].specular.a); +	col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].specular.a); +	col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].specular.a);  	col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz);  	col.rgb = scaleDownLight(col.rgb); +	// Add windlight lights +	col.rgb += atmosAmbient(vec3(0.)); +	  	vary_ambient = col.rgb*gl_Color.rgb;  	vary_directional = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a))); diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl index bd5e9dd758..0fad5b4b50 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl @@ -10,13 +10,11 @@  uniform sampler2DRect depthMap;  uniform sampler2DRect normalMap;  uniform sampler2DRect lightMap; -uniform sampler2DRect giLightMap;  uniform float dist_factor;  uniform float blur_size;  uniform vec2 delta; -uniform vec3 kern[32]; -uniform int kern_length; +uniform vec3 kern[4];  uniform float kern_scale;  varying vec2 vary_fragcoord; @@ -50,7 +48,7 @@ void main()  	vec2 defined_weight = kern[0].xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free'  	vec4 col = defined_weight.xyxx * ccol; -	for (int i = 1; i < kern_length; i++) +	for (int i = 1; i < 4; i++)  	{  		vec2 tc = vary_fragcoord.xy + kern[i].z*dlt;  	        vec3 samppos = getPosition(tc).xyz;  @@ -61,12 +59,22 @@ void main()  			defined_weight += kern[i].xy;  		}  	} +	for (int i = 1; i < 4; i++) +	{ +		vec2 tc = vary_fragcoord.xy - kern[i].z*dlt; +	        vec3 samppos = getPosition(tc).xyz;  +		float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane +		if (d*d <= 0.003) +		{ +			col += texture2DRect(lightMap, tc)*kern[i].xyxx; +			defined_weight += kern[i].xy; +		} +	}  	col /= defined_weight.xyxx;  	gl_FragColor = col; -	 -	//gl_FragColor = ccol;  } + diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl index e518bddb98..0db9586a88 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl @@ -23,8 +23,6 @@ varying vec4 vary_position;  varying vec3 vary_normal;  varying vec3 vary_fragcoord; -uniform float alpha_soften; -  uniform mat4 inv_proj;  vec4 getPosition(vec2 pos_screen) @@ -56,15 +54,6 @@ void main()  	color.rgb = fullbrightScaleSoftClip(color.rgb); -	if (samp_pos.z != 0.0 && color.a < 1.0) -	{ -		float dist_factor = alpha_soften; -		float a = color.a; -		a *= a; -		dist_factor *= 1.0/(1.0-a); -		color.a *= min((pos.z-samp_pos.z)*dist_factor, 1.0); -	} -  	//gl_FragColor = gl_Color;  	gl_FragColor = color;  	//gl_FragColor = vec4(1,0,1,1); diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl index 8c140a7b4f..508bbf415e 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl @@ -11,7 +11,8 @@ uniform sampler2D specularMap;  void main()   { -	gl_FragData[0] = texture2D(diffuseMap, gl_TexCoord[0].xy); +	vec4 col = texture2D(diffuseMap, gl_TexCoord[0].xy); +	gl_FragData[0] = vec4(col.rgb, col.a <= 0.5 ? 0.0 : 0.005);  	gl_FragData[1] = texture2D(specularMap, gl_TexCoord[0].xy);  	gl_FragData[2] = vec4(texture2D(normalMap, gl_TexCoord[0].xy).xyz, 0.0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl index 28bcd720c0..82e9450e68 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl @@ -5,9 +5,10 @@   * $License$   */ -  #version 120 +//class 1 -- no shadows +  #extension GL_ARB_texture_rectangle : enable  uniform sampler2DRect diffuseRect; @@ -26,12 +27,15 @@ 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; @@ -40,6 +44,52 @@ 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(vec2 pos_screen)  {  	float depth = texture2DRect(depthMap, pos_screen.xy).a; @@ -68,7 +118,7 @@ void main()  	{  		discard;  	} -	 +		  	vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0;  	norm = normalize(norm); @@ -83,7 +133,11 @@ void main()  	proj_tc.xyz /= proj_tc.w;  	float fa = gl_Color.a+1.0; -	float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); +	float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0); +	if (dist_atten <= 0.0) +	{ +		discard; +	}  	lv = proj_origin-pos.xyz;  	lv = normalize(lv); @@ -101,32 +155,32 @@ void main()  		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 = texture2DLod(projectionMap, proj_tc.xy, 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; +			amb_da += (da*0.5)*proj_ambiance;  		} -		float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); -		float lod = diff * proj_lod; -		vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, lod); -		//float amb_da = mix(proj_ambiance, proj_ambiance*max(-da, 0.0), max(da, 0.0)); -		float amb_da = 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;  	} @@ -144,35 +198,28 @@ void main()  		{  			vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; -			vec3 stc = (proj_mat * vec4(pfinal.xyz, 1.0)).xyz; +			vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));  			if (stc.z > 0.0)  			{ -				stc.xy /= stc.z+proj_near; -					 +				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 = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); +					vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);  					col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb;  				}  			}  		}  	} -	/*if (spec.a > 0.0) -	{ -		//vec3 ref = reflect(normalize(pos), norm); -		float sa = dot(normalize(lv-normalize(pos)),norm);; -		//sa = max(sa, 0.0); -		//sa = pow(sa, 128.0 * spec.a*spec.a/dist_atten)*min(dist_atten*4.0, 1.0); -		sa = texture2D(lightFunc, vec2(sa, spec.a)).a * min(dist_atten*4.0, 1.0); -		sa *= noise; -		col += da*sa*lcol*spec.rgb; -	}*/ -	  	gl_FragColor.rgb = col;	  	gl_FragColor.a = 0.0;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl index b4b0d0ce9d..158eef9319 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl @@ -11,6 +11,7 @@ uniform sampler2DRect diffuseRect;  uniform sampler2DRect specularRect;  uniform sampler2DRect positionMap;  uniform sampler2DRect normalMap; +uniform sampler2DRect lightMap;  uniform sampler2DRect depthMap;  uniform sampler2D	  noiseMap;  uniform samplerCube environmentMap; @@ -40,7 +41,7 @@ uniform float scene_light_strength;  uniform vec3 env_mat[3];  //uniform mat4 shadow_matrix[3];  //uniform vec4 shadow_clip; -//uniform mat3 ssao_effect_mat; +uniform mat3 ssao_effect_mat;  varying vec4 vary_light;  varying vec2 vary_fragcoord; @@ -55,9 +56,8 @@ vec3 vary_AtmosAttenuation;  uniform mat4 inv_proj;  uniform vec2 screen_res; -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; +vec4 getPosition_d(vec2 pos_screen, float depth) +{  	vec2 sc = pos_screen.xy*2.0;  	sc /= screen_res;  	sc -= vec2(1.0,1.0); @@ -68,6 +68,12 @@ vec4 getPosition(vec2 pos_screen)  	return pos;  } +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; +	return getPosition_d(pos_screen, depth); +} +  vec3 getPositionEye()  {  	return vary_PositionEye; @@ -178,7 +184,17 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) {  	temp2.x += .25;  	//increase ambient when there are more clouds -	vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow.x * 0.5;	 +	vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow.x * 0.5; +	 +	/*  decrease value and saturation (that in HSV, not HSL) for occluded areas +	 * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html +	 * // The following line of code performs the equivalent of: +	 * float ambAlpha = tmpAmbient.a; +	 * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis +	 * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue); +	 * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha); +	 */ +	tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);  	//haze color  	setAdditiveColor( @@ -241,7 +257,8 @@ vec3 scaleSoftClip(vec3 light)  void main()   {  	vec2 tc = vary_fragcoord.xy; -	vec3 pos = getPosition(tc).xyz; +	float depth = texture2DRect(depthMap, tc.xy).a; +	vec3 pos = getPosition_d(tc, depth).xyz;  	vec3 norm = texture2DRect(normalMap, tc).xyz*2.0-1.0;  	//vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz; @@ -250,23 +267,74 @@ void main()  	vec4 diffuse = texture2DRect(diffuseRect, tc);  	vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); -	calcAtmospherics(pos.xyz, 0.0); +	vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg; +	float scol = max(scol_ambocc.r, diffuse.a);  +	float ambocc = scol_ambocc.g; +	 +	calcAtmospherics(pos.xyz, ambocc);  	vec3 col = atmosAmbient(vec3(0)); -	col += atmosAffectDirectionalLight(clamp(da, diffuse.a, 1.0)); +	col += atmosAffectDirectionalLight(max(min(da, scol), diffuse.a));  	col *= diffuse.rgb; -	if (spec.a > 0.0) +	if (spec.a > 0.0) // specular reflection  	{ -		vec3 ref = normalize(reflect(pos.xyz, norm.xyz)); -		float sa = dot(ref, vary_light.xyz); -		col.rgb += vary_SunlitColor*spec.rgb*texture2D(lightFunc, vec2(sa, spec.a)).a; +		// the old infinite-sky shiny reflection +		// +		vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); +		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 +		vec2 checkoffset = normalize(ref2d)*5.0*(1.0-spec.a)*(checkerboard-0.5); +		ref2d += 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. +		// --------------------- +		//     ^   ^ ^ ^   ^ +		//     a . b o c . d    check=0:avg(a,b) check=1:avg(c,d) +		vec3 refcol = 0.5 * (texture2DRect(diffuseRect, ref2d).rgb + +				     texture2DRect(diffuseRect, ref2d + checkoffset*2.0).rgb); +		float refdepth = texture2DRect(depthMap, ref2d).a; +		vec3 refpos = getPosition_d(ref2d, refdepth).xyz; +		vec3 refn = normalize(texture2DRect(normalMap, ref2d).rgb * 2.0 - 1.0); +		// 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 = max(dot(refn, reflight.xyz), 0.0); +		// 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); + +		// add the two types of shiny together +		col += (ssshiny + dumbshiny) * spec.rgb;  	}  	col = atmosLighting(col);  	col = scaleSoftClip(col); -	 +		  	gl_FragColor.rgb = col;  	gl_FragColor.a = 0.0;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl index 2a7234fd83..f320dbb400 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl @@ -161,17 +161,6 @@ void main()  		}  	} -	/*if (spec.a > 0.0) -	{ -		//vec3 ref = reflect(normalize(pos), norm); -		float sa = dot(normalize(lv-normalize(pos)),norm);; -		//sa = max(sa, 0.0); -		//sa = pow(sa, 128.0 * spec.a*spec.a/dist_atten)*min(dist_atten*4.0, 1.0); -		sa = texture2D(lightFunc, vec2(sa, spec.a)).a * min(dist_atten*4.0, 1.0); -		sa *= noise; -		col += da*sa*lcol*spec.rgb; -	}*/ -	  	gl_FragColor.rgb = col;	  	gl_FragColor.a = 0.0;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl index 22bdd2c7f3..56e4055c02 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl @@ -5,196 +5,11 @@   * $License$   */ -#extension GL_ARB_texture_rectangle : enable - -uniform sampler2DRect depthMap; -uniform sampler2DRect normalMap; -uniform sampler2DRectShadow shadowMap0; -uniform sampler2DRectShadow shadowMap1; -uniform sampler2DRectShadow shadowMap2; -uniform sampler2DRectShadow shadowMap3; -uniform sampler2DRectShadow shadowMap4; -uniform sampler2DRectShadow shadowMap5; -uniform sampler2D noiseMap; - -uniform sampler2D		lightFunc; - - -// 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 float shadow_bias; -uniform float shadow_offset; - -vec4 getPosition(vec2 pos_screen) -{ -	float depth = texture2DRect(depthMap, pos_screen.xy).a; -	vec2 sc = 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; -} +//class 1, no shadow, no SSAO, should never be called -//calculate decreases in ambient lighting when crowded out (SSAO) -float calcAmbientOcclusion(vec4 pos, vec3 norm) -{ -	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++) -	{ -		vec2 samppos_screen = pos_screen + scale * reflect(kern[i], noise_reflect); -		vec3 samppos_world = getPosition(samppos_screen).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) -		 -		//if (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0)  // -0.05*norm to shift sample point back slightly for flat surfaces -		//	angle_hidden += min(1.0/dist2, ssao_factor_inv); // dist != 0 follows from conditional.  max of 1.0 (= ssao_factor_inv * ssao_factor) -		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); -	 -	return (1.0 - (float(points != 0) * angle_hidden)); -} +#extension GL_ARB_texture_rectangle : enable  void main()   { -	vec2 pos_screen = vary_fragcoord.xy; -	 -	//try doing an unproject here -	 -	vec4 pos = getPosition(pos_screen); -	 -    vec3 norm = texture2DRect(normalMap, pos_screen).xyz*2.0-1.0; -	 -	/*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)); - -	vec4 spos = vec4(pos.xyz + norm.xyz * (-pos.z/64.0*shadow_offset+shadow_bias), 1.0); -	 -	//vec3 debug = vec3(0,0,0); -	 -	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 if (spos.z > -shadow_clip.w) -	{	 -		vec4 lpos; -		 -		if (spos.z < -shadow_clip.z) -		{ -			lpos = shadow_matrix[3]*spos; -			lpos.xy *= screen_res; -			shadow = shadow2DRectProj(shadowMap3, lpos).x; -			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 *= screen_res; -			shadow = shadow2DRectProj(shadowMap2, lpos).x; -		} -		else if (spos.z < -shadow_clip.x) -		{ -			lpos = shadow_matrix[1]*spos; -			lpos.xy *= screen_res; -			shadow = shadow2DRectProj(shadowMap1, lpos).x; -		} -		else -		{ -			lpos = shadow_matrix[0]*spos; -			lpos.xy *= screen_res; -			shadow = shadow2DRectProj(shadowMap0, lpos).x; -		} - -		// 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); -		 -		/*debug.r = lpos.y / (lpos.w*screen_res.y); -		 -		lpos.xy /= lpos.w*32.0; -		if (fract(lpos.x) < 0.1 || fract(lpos.y) < 0.1) -		{ -			debug.gb = vec2(0.5, 0.5); -		} -		 -		debug += (1.0-shadow)*0.5;*/ -		 -	} -	else -	{ -		// more distant than the shadow map covers - just use directional shading as shadow -		shadow = dp_directional_light; -	} -	 -	gl_FragColor[0] = shadow; -	gl_FragColor[1] = calcAmbientOcclusion(pos, norm); -	 -	//spotlight shadow 1 -	vec4 lpos = shadow_matrix[4]*spos; -	lpos.xy *= screen_res; -	gl_FragColor[2] = shadow2DRectProj(shadowMap4, lpos).x;  -	 -	//spotlight shadow 2 -	lpos = shadow_matrix[5]*spos; -	lpos.xy *= screen_res; -	gl_FragColor[3] = shadow2DRectProj(shadowMap5, lpos).x;  - -	//gl_FragColor.rgb = pos.xyz; -	//gl_FragColor.b = shadow; -	//gl_FragColor.rgb = debug; +	gl_FragColor = vec4(0,0,0,0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl new file mode 100644 index 0000000000..7450817ea7 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl @@ -0,0 +1,123 @@ +/**  + * @file sunLightSSAOF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#extension GL_ARB_texture_rectangle : enable + +//class 1 -- no shadow, SSAO only + +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform sampler2D noiseMap; + +uniform sampler2D		lightFunc; + + +// 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 float shadow_bias; +uniform float shadow_offset; + +vec4 getPosition(vec2 pos_screen) +{ +	float depth = texture2DRect(depthMap, pos_screen.xy).a; +	vec2 sc = 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) +{ +	float ret = 1.0; +	 +	float dist = dot(pos.xyz,pos.xyz); +	 +	if (dist < 64.0*64.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++) +		{ +			vec2 samppos_screen = pos_screen + scale * reflect(kern[i], noise_reflect); +			vec3 samppos_world = getPosition(samppos_screen).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) +			 +			//if (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0)  // -0.05*norm to shift sample point back slightly for flat surfaces +			//	angle_hidden += min(1.0/dist2, ssao_factor_inv); // dist != 0 follows from conditional.  max of 1.0 (= ssao_factor_inv * ssao_factor) +			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)); +		ret += max((dist-32.0*32.0)/(32.0*32.0), 0.0); +	} +	 +	return min(ret, 1.0); +} + +void main()  +{ +	vec2 pos_screen = vary_fragcoord.xy; +	 +	//try doing an unproject here +	 +	vec4 pos = getPosition(pos_screen); +	 +    vec3 norm = texture2DRect(normalMap, pos_screen).xyz*2.0-1.0; +		 +	gl_FragColor[0] = 1.0; +	gl_FragColor[1] = calcAmbientOcclusion(pos, norm); +	gl_FragColor[2] = 1.0;  +	gl_FragColor[3] = 1.0; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl index d21575119d..ceb7e0fb56 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl @@ -115,7 +115,7 @@ void main()  	vec4 fb = texture2D(screenTex, distort2);  	//mix with reflection -	// Note we actually want to use just df1, but multiplying by 0.999999 gets around and nvidia compiler bug +	// Note we actually want to use just df1, but multiplying by 0.999999 gets around an nvidia compiler bug  	color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999);  	float shadow = 1.0; @@ -131,11 +131,11 @@ void main()  	//color.rgb = scaleSoftClip(color.rgb);  	//color.a = spec * sunAngle2; -	//wavef.z = -0.25f; -	wavef = normalize(wavef); -	wavef = (norm_mat*vec4(wavef, 1.0)).xyz; +	//wavef.z *= 0.1f; +	//wavef = normalize(wavef); +	vec3 screenspacewavef = (norm_mat*vec4(wavef, 1.0)).xyz; -	gl_FragData[0] = vec4(color.rgb, 0.75); -	gl_FragData[1] = vec4(1,1,1, 0.8); -	gl_FragData[2] = vec4(wavef*0.5+0.5, 0.0); +	gl_FragData[0] = vec4(color.rgb, 0.5); // diffuse +	gl_FragData[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec +	gl_FragData[2] = vec4(screenspacewavef*0.5+0.5, screenspacewavef.z*0.5); // normal, displace  } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl index 3e8fdfb3e4..da49e59b89 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl @@ -12,7 +12,8 @@ float calcDirectionalLight(vec3 n, vec3 l)  	return a;  } -float calcPointLight(vec3 v, vec3 n, vec4 lp, float la) + +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight)  {  	//get light vector  	vec3 lv = lp.xyz-v; @@ -26,9 +27,13 @@ float calcPointLight(vec3 v, vec3 n, vec4 lp, float la)  	//distance attenuation  	float da = clamp(1.0/(la * d), 0.0, 1.0); +	// spotlight coefficient. +	float spot = max(dot(-ln, lv), is_pointlight); +	da *= spot*spot; // GL_SPOT_EXPONENT=2 +  	//angular attenuation  	da *= calcDirectionalLight(n, lv); -	 +  	return da;	  } diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl index ad16de6d81..665fe16b43 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl @@ -29,8 +29,6 @@ varying vec3 vary_fragcoord;  varying vec3 vary_position;  varying vec3 vary_light; -uniform float alpha_soften; -  uniform float shadow_bias;  uniform mat4 inv_proj; @@ -115,15 +113,6 @@ void main()  	color.rgb = scaleSoftClip(color.rgb); -	if (samp_pos.z != 0.0 && gl_Color.a < 1.0) -	{ -		float dist_factor = alpha_soften; -		float a = gl_Color.a; -		a *= a; -		dist_factor *= 1.0/(1.0-a); -		color.a *= min((pos.z-samp_pos.z)*dist_factor, 1.0); -	} -	  	//gl_FragColor = gl_Color;  	gl_FragColor = color;  	//gl_FragColor = vec4(1,0,1,1)*shadow; diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl index 5991e1f3b5..1fae8c4da3 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl @@ -9,7 +9,7 @@ vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);  void calcAtmospherics(vec3 inPositionEye);  float calcDirectionalLight(vec3 n, vec3 l); -float calcPointLight(vec3 v, vec3 n, vec4 lp, float la); +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);  vec3 atmosAmbient(vec3 light);  vec3 atmosAffectDirectionalLight(float lightIntensity); @@ -42,23 +42,21 @@ void main()  	calcAtmospherics(pos.xyz);  	//vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.)); -	vec4 col; -	col.a = gl_Color.a; -	 -	// Add windlight lights -	col.rgb = atmosAmbient(vec3(0.)); -	col.rgb = scaleUpLight(col.rgb); +	vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a);  	// Collect normal lights (need to be divided by two, as we later multiply by 2) -	col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation); -	col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation); -	col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation); -	col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].linearAttenuation); - 	col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].linearAttenuation); - 	col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].linearAttenuation); +	col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a); +	col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a); +	col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a); +	col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].specular.a); +	col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].specular.a); +	col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].specular.a);  	col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz);  	col.rgb = scaleDownLight(col.rgb); +	// Add windlight lights +	col.rgb += atmosAmbient(vec3(0.)); +	  	vary_light = gl_LightSource[0].position.xyz;  	vary_ambient = col.rgb*gl_Color.rgb; diff --git a/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl index a939499b17..f8dd1b7431 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl @@ -10,7 +10,7 @@ mat4 getSkinnedTransform();  void calcAtmospherics(vec3 inPositionEye);  float calcDirectionalLight(vec3 n, vec3 l); -float calcPointLight(vec3 v, vec3 n, vec4 lp, float la); +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);  vec3 atmosAmbient(vec3 light);  vec3 atmosAffectDirectionalLight(float lightIntensity); @@ -53,23 +53,22 @@ void main()  	calcAtmospherics(pos.xyz);  	//vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.)); -	vec4 col; -	col.a = gl_Color.a; -	 -	// Add windlight lights -	col.rgb = atmosAmbient(vec3(0.)); -	col.rgb = scaleUpLight(col.rgb); + +	vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a);  	// Collect normal lights (need to be divided by two, as we later multiply by 2) -	col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation); -	col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation); -	col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation); -	col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].linearAttenuation); - 	col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].linearAttenuation); - 	col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].linearAttenuation); +	col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a); +	col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a); +	col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a); +	col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].specular.a); +	col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].specular.a); +	col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].specular.a);  	col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz);  	col.rgb = scaleDownLight(col.rgb); +	// Add windlight lights +	col.rgb += atmosAmbient(vec3(0.)); +	  	vary_ambient = col.rgb*gl_Color.rgb;  	vary_directional = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a))); diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl index 651959413c..5308e5bb1e 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl @@ -43,6 +43,52 @@ 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(vec2 pos_screen)  {  	float depth = texture2DRect(depthMap, pos_screen.xy).a; @@ -126,7 +172,7 @@ void main()  			float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);  			float lod = diff * proj_lod; -			vec4 plcol = texture2DLod(projectionMap, proj_tc.xy, lod); +			vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);  			vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a; @@ -137,7 +183,7 @@ void main()  		}  		//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); -		vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, proj_ambient_lod); +		vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);  		amb_da += (da*da*0.5+0.5)*proj_ambiance; @@ -167,22 +213,23 @@ void main()  			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 = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); +					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;  				}  			}  		}  	} -	//attenuate point light contribution by SSAO component -	col *= texture2DRect(lightMap, frag.xy).g; -	  	gl_FragColor.rgb = col;	  	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 531f7376a3..dbccb7fb8b 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -11,6 +11,7 @@ uniform sampler2DRect diffuseRect;  uniform sampler2DRect specularRect;  uniform sampler2DRect normalMap;  uniform sampler2DRect lightMap; +uniform sampler2DRect depthMap;  uniform sampler2D	  noiseMap;  uniform samplerCube environmentMap;  uniform sampler2D	  lightFunc; @@ -41,7 +42,6 @@ uniform vec3 env_mat[3];  uniform vec4 shadow_clip;  uniform mat3 ssao_effect_mat; -uniform sampler2DRect depthMap;  uniform mat4 inv_proj;  uniform vec2 screen_res; @@ -55,9 +55,8 @@ vec3 vary_AmblitColor;  vec3 vary_AdditiveColor;  vec3 vary_AtmosAttenuation; -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; +vec4 getPosition_d(vec2 pos_screen, float depth) +{  	vec2 sc = pos_screen.xy*2.0;  	sc /= screen_res;  	sc -= vec2(1.0,1.0); @@ -68,6 +67,12 @@ vec4 getPosition(vec2 pos_screen)  	return pos;  } +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; +	return getPosition_d(pos_screen, depth); +} +  vec3 getPositionEye()  {  	return vary_PositionEye; @@ -251,7 +256,8 @@ vec3 scaleSoftClip(vec3 light)  void main()   {  	vec2 tc = vary_fragcoord.xy; -	vec3 pos = getPosition(tc).xyz; +	float depth = texture2DRect(depthMap, tc.xy).a; +	vec3 pos = getPosition_d(tc, depth).xyz;  	vec3 norm = texture2DRect(normalMap, tc).xyz*2.0-1.0;  	//vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz; @@ -271,24 +277,64 @@ void main()  	col *= diffuse.rgb; -	if (spec.a > 0.0) +	if (spec.a > 0.0) // specular reflection  	{ -		vec3 ref = normalize(reflect(pos.xyz, norm.xyz)); -		float sa = dot(ref, vary_light.xyz); -		col.rgb += vary_SunlitColor*scol*spec.rgb*texture2D(lightFunc, vec2(sa, spec.a)).a; +		// the old infinite-sky shiny reflection +		// +		vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); +		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 +		vec2 checkoffset = normalize(ref2d)*5.0*(1.0-spec.a)*(checkerboard-0.5); +		ref2d += 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. +		// --------------------- +		//     ^   ^ ^ ^   ^ +		//     a . b o c . d    check=0:avg(a,b) check=1:avg(c,d) +		vec3 refcol = 0.5 * (texture2DRect(diffuseRect, ref2d).rgb + +				     texture2DRect(diffuseRect, ref2d + checkoffset*2.0).rgb); +		float refdepth = texture2DRect(depthMap, ref2d).a; +		vec3 refpos = getPosition_d(ref2d, refdepth).xyz; +		float refshad = texture2DRect(lightMap, ref2d).r; +		vec3 refn = normalize(texture2DRect(normalMap, ref2d).rgb * 2.0 - 1.0); +		// 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); + +		// add the two types of shiny together +		col += (ssshiny + dumbshiny) * spec.rgb;  	}  	col = atmosLighting(col);  	col = scaleSoftClip(col);  	gl_FragColor.rgb = col; -	 -	//gl_FragColor.rgb = gi_col.rgb;  	gl_FragColor.a = 0.0; -	 -	//gl_FragColor.rg = scol_ambocc.rg; -	//gl_FragColor.rgb = texture2DRect(lightMap, vary_fragcoord.xy).rgb; -	//gl_FragColor.rgb = norm.rgb*0.5+0.5; -	//gl_FragColor.rgb = vec3(ambocc); -	//gl_FragColor.rgb = vec3(scol);  } diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl index d6534083cf..eeaecc157f 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl @@ -179,21 +179,6 @@ void main()  		}  	} -	/*if (spec.a > 0.0) -	{ -		//vec3 ref = reflect(normalize(pos), norm); -		float sa = dot(normalize(lv-normalize(pos)),norm);; -		//sa = max(sa, 0.0); -		//sa = pow(sa, 128.0 * spec.a*spec.a/dist_atten)*min(dist_atten*4.0, 1.0); -		sa = texture2D(lightFunc, vec2(sa, spec.a)).a * min(dist_atten*4.0, 1.0); -		sa *= noise; -		col += da*sa*lcol*spec.rgb; -	}*/ -	 -	//attenuate point light contribution by SSAO component -	col *= texture2DRect(lightMap, frag.xy).g; -	 -  	gl_FragColor.rgb = col;	  	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 a0026edcd2..04c9a4d19a 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl @@ -7,6 +7,8 @@  #extension GL_ARB_texture_rectangle : enable +//class 2, shadows, no SSAO +  uniform sampler2DRect depthMap;  uniform sampler2DRect normalMap;  uniform sampler2DRectShadow shadowMap0; @@ -52,56 +54,6 @@ vec4 getPosition(vec2 pos_screen)  	return pos;  } -//calculate decreases in ambient lighting when crowded out (SSAO) -float calcAmbientOcclusion(vec4 pos, vec3 norm) -{ -	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++) -	{ -		vec2 samppos_screen = pos_screen + scale * reflect(kern[i], noise_reflect); -		vec3 samppos_world = getPosition(samppos_screen).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) -		 -		//if (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0)  // -0.05*norm to shift sample point back slightly for flat surfaces -		//	angle_hidden += min(1.0/dist2, ssao_factor_inv); // dist != 0 follows from conditional.  max of 1.0 (= ssao_factor_inv * ssao_factor) -		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); -	 -	return (1.0 - (float(points != 0) * angle_hidden)); -} -  float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl)  {  	stc.xyz /= stc.w; @@ -149,7 +101,9 @@ void main()  	vec4 pos = getPosition(pos_screen); -    vec3 norm = texture2DRect(normalMap, pos_screen).xyz*2.0-1.0; +	vec4 nmap4 = texture2DRect(normalMap, pos_screen); +	float displace = nmap4.w; +	vec3 norm = nmap4.xyz*2.0-1.0;  	/*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL  	{ @@ -158,9 +112,9 @@ void main()  	}*/  	float shadow = 1.0; -    float dp_directional_light = max(0.0, dot(norm, vary_light.xyz)); +	float dp_directional_light = max(0.0, dot(norm, vary_light.xyz)); -	vec4 spos = vec4(pos.xyz + vary_light.xyz * (1.0-dp_directional_light)*shadow_offset, 1.0); +	vec4 spos = vec4(pos.xyz + displace*norm + vary_light.xyz * (1.0-dp_directional_light)*shadow_offset, 1.0);  	if (spos.z > -shadow_clip.w)  	{	 @@ -220,15 +174,15 @@ void main()  	}  	gl_FragColor[0] = shadow; -	gl_FragColor[1] = calcAmbientOcclusion(pos, norm); +	gl_FragColor[1] = 1.0;  	//spotlight shadow 1  	vec4 lpos = shadow_matrix[4]*spos; -	gl_FragColor[2] = pcfShadow(shadowMap4, lpos, 0.1).x;  +	gl_FragColor[2] = pcfShadow(shadowMap4, lpos, 0.8).x;   	//spotlight shadow 2  	lpos = shadow_matrix[5]*spos; -	gl_FragColor[3] = pcfShadow(shadowMap5, lpos, 0.1).x;  +	gl_FragColor[3] = pcfShadow(shadowMap5, lpos, 0.8).x;   	//gl_FragColor.rgb = pos.xyz;  	//gl_FragColor.b = shadow; diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl new file mode 100644 index 0000000000..d77d17942a --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl @@ -0,0 +1,248 @@ +/**  + * @file sunLightSSAOF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#extension GL_ARB_texture_rectangle : enable + +//class 2 -- shadows and SSAO + +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform sampler2DRectShadow shadowMap0; +uniform sampler2DRectShadow shadowMap1; +uniform sampler2DRectShadow shadowMap2; +uniform sampler2DRectShadow shadowMap3; +uniform sampler2DShadow shadowMap4; +uniform sampler2DShadow shadowMap5; +uniform sampler2D noiseMap; + +uniform sampler2D		lightFunc; + +// 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; + +vec4 getPosition(vec2 pos_screen) +{ +	float depth = texture2DRect(depthMap, pos_screen.xy).a; +	vec2 sc = 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) +{ +	float ret = 1.0; +	 +	float dist = dot(pos.xyz,pos.xyz); +	 +	if (dist < 64.0*64.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++) +		{ +			vec2 samppos_screen = pos_screen + scale * reflect(kern[i], noise_reflect); +			vec3 samppos_world = getPosition(samppos_screen).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) +			 +			//if (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0)  // -0.05*norm to shift sample point back slightly for flat surfaces +			//	angle_hidden += min(1.0/dist2, ssao_factor_inv); // dist != 0 follows from conditional.  max of 1.0 (= ssao_factor_inv * ssao_factor) +			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)); +		ret += max((dist-32.0*32.0)/(32.0*32.0), 0.0); +	} +	 +	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 += 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; +	 +	//try doing an unproject here +	 +	vec4 pos = getPosition(pos_screen); +	 +	vec4 nmap4 = texture2DRect(normalMap, pos_screen); +	float displace = nmap4.w; +	vec3 norm = nmap4.xyz*2.0-1.0; +	 +	/*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)); + +	vec4 spos = vec4(pos.xyz + displace*norm + vary_light.xyz * (1.0-dp_directional_light)*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; +	} +	 +	gl_FragColor[0] = shadow; +	gl_FragColor[1] = calcAmbientOcclusion(pos, norm); +	 +	//spotlight shadow 1 +	vec4 lpos = shadow_matrix[4]*spos; +	gl_FragColor[2] = pcfShadow(shadowMap4, lpos, 0.8).x;  +	 +	//spotlight shadow 2 +	lpos = shadow_matrix[5]*spos; +	gl_FragColor[3] = pcfShadow(shadowMap5, lpos, 0.8).x;  + +	//gl_FragColor.rgb = pos.xyz; +	//gl_FragColor.b = shadow; +} diff --git a/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl index f4c59734a4..19800d96dc 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl @@ -6,7 +6,7 @@   */  float calcDirectionalLight(vec3 n, vec3 l); -float calcPointLight(vec3 v, vec3 n, vec4 lp, float la); +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);  vec3 atmosAmbient(vec3 light);  vec3 atmosAffectDirectionalLight(float lightIntensity); @@ -18,9 +18,10 @@ vec4 sumLights(vec3 pos, vec3 norm, vec4 color, vec4 baseLight)  	// Collect normal lights (need to be divided by two, as we later multiply by 2)  	col.rgb += gl_LightSource[1].diffuse.rgb * calcDirectionalLight(norm, gl_LightSource[1].position.xyz); -	col.rgb += gl_LightSource[2].diffuse.rgb * calcPointLight(pos, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation); -	col.rgb += gl_LightSource[3].diffuse.rgb * calcPointLight(pos, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation); -	//col.rgb += gl_LightSource[4].diffuse.rgb * calcPointLight(pos, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation); + +	col.rgb += gl_LightSource[2].diffuse.rgb * calcPointLightOrSpotLight(pos, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a); +	col.rgb += gl_LightSource[3].diffuse.rgb * calcPointLightOrSpotLight(pos, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a); +	//col.rgb += gl_LightSource[4].diffuse.rgb * calcPointLightOrSpotLight(pos, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a);  	col.rgb = scaleDownLight(col.rgb);  	// Add windlight lights diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index 96a083b522..ef81ed1308 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -56,9 +56,8 @@ vec3 vary_AdditiveColor;  vec3 vary_AtmosAttenuation;  uniform float gi_ambiance; -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; +vec4 getPosition_d(vec2 pos_screen, float depth) +{  	vec2 sc = pos_screen.xy*2.0;  	sc /= screen_res;  	sc -= vec2(1.0,1.0); @@ -69,6 +68,12 @@ vec4 getPosition(vec2 pos_screen)  	return pos;  } +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; +	return getPosition_d(pos_screen, depth); +} +  vec3 getPositionEye()  {  	return vary_PositionEye; @@ -252,7 +257,8 @@ vec3 scaleSoftClip(vec3 light)  void main()   {  	vec2 tc = vary_fragcoord.xy; -	vec3 pos = getPosition(tc).xyz; +	float depth = texture2DRect(depthMap, tc.xy).a; +	vec3 pos = getPosition_d(tc, depth).xyz;  	vec3 norm = texture2DRect(normalMap, tc).xyz*2.0-1.0;  	//vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz; @@ -274,11 +280,59 @@ void main()  	col *= diffuse.rgb; -	if (spec.a > 0.0) +	if (spec.a > 0.0) // specular reflection  	{ -		vec3 ref = normalize(reflect(pos.xyz, norm.xyz)); -		float sa = dot(ref, vary_light.xyz); -		col.rgb += vary_SunlitColor*scol*spec.rgb*texture2D(lightFunc, vec2(sa, spec.a)).a; +		// the old infinite-sky shiny reflection +		// +		vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); +		float sa = dot(refnormpersp, vary_light.xyz); +		vec3 dumbshiny = vary_SunlitColor*scol*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 +		vec2 checkoffset = normalize(ref2d)*5.0*(1.0-spec.a)*(checkerboard-0.5); +		ref2d += 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. +		// --------------------- +		//     ^   ^ ^ ^   ^ +		//     a . b o c . d    check=0:avg(a,b) check=1:avg(c,d) +		vec3 refcol = 0.5 * (texture2DRect(diffuseRect, ref2d).rgb + +				     texture2DRect(diffuseRect, ref2d + checkoffset*2.0).rgb); +		float refdepth = texture2DRect(depthMap, ref2d).a; +		vec3 refpos = getPosition_d(ref2d, refdepth).xyz; +		float refshad = texture2DRect(lightMap, ref2d).r; +		vec3 refn = normalize(texture2DRect(normalMap, ref2d).rgb * 2.0 - 1.0); +		// 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); + +		// add the two types of shiny together +		col += (ssshiny + dumbshiny) * spec.rgb;  	}  	col = atmosLighting(col); diff --git a/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl index 1c5234c450..f129a1517b 100644 --- a/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl +++ b/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl @@ -6,7 +6,7 @@   */  float calcDirectionalLight(vec3 n, vec3 l); -float calcPointLight(vec3 v, vec3 n, vec4 lp, float la); +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);  vec3 atmosAmbient(vec3 light);  vec3 atmosAffectDirectionalLight(float lightIntensity); @@ -15,24 +15,21 @@ vec3 scaleUpLight(vec3 light);  vec4 sumLights(vec3 pos, vec3 norm, vec4 color, vec4 baseLight)  { -	vec4 col; -	col.a = color.a; +	vec4 col = vec4(0.0, 0.0, 0.0, color.a); -	// Add windlight lights -	col.rgb = atmosAffectDirectionalLight(calcDirectionalLight(norm, gl_LightSource[0].position.xyz)); -	col.rgb += atmosAmbient(baseLight.rgb); -	col.rgb = scaleUpLight(col.rgb); -  	// Collect normal lights (need to be divided by two, as we later multiply by 2) -	col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation); -	col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation); -	col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation); -	col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[5].position, gl_LightSource[5].linearAttenuation); - 	col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[6].position, gl_LightSource[6].linearAttenuation); - 	col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[7].position, gl_LightSource[7].linearAttenuation); +	col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a); +	col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a); +	col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a); +	col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].specular.a); +	col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].specular.a); +	col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].specular.a);  	col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz);  	col.rgb = scaleDownLight(col.rgb); -				 + +	// Add windlight lights +	col.rgb += atmosAffectDirectionalLight(calcDirectionalLight(norm, gl_LightSource[0].position.xyz)); +	col.rgb += atmosAmbient(baseLight.rgb);  	col.rgb = min(col.rgb*color.rgb, 1.0); diff --git a/indra/newview/app_settings/ultra_graphics.xml b/indra/newview/app_settings/ultra_graphics.xml index f16ec6c30f..f741089ca2 100644 --- a/indra/newview/app_settings/ultra_graphics.xml +++ b/indra/newview/app_settings/ultra_graphics.xml @@ -12,14 +12,12 @@  	<RenderFlexTimeFactor value="1"/>  	<!--256... but they don't use this-->  	<RenderGlowResolutionPow value="9"/> -	<!--Sun/Moon only--> -	<RenderLightingDetail value="1"/>  	<!--Low number-->  	<RenderMaxPartCount value="4096"/>  	<!--bump okay-->  	<RenderObjectBump value="TRUE"/>  	<!--NO SHADERS--> -	<RenderReflectionDetail value="3"/> +	<RenderReflectionDetail value="4"/>  	<!--Simple-->  	<RenderTerrainDetail value="1"/>  	<!--Default for now--> @@ -31,9 +29,14 @@  	<!--Default for now-->  	<RenderVolumeLODFactor value="2.0"/>  	<!--NO SHADERS--> -	<RenderWaterReflections value="TRUE"/> -	<!--NO SHADERS-->  	<VertexShaderEnable value="TRUE"/>  	<!--NO SHADERS-->  	<WindLightUseAtmosShaders value="TRUE"/> +  <!--Deferred Shading--> +  <RenderDeferred value="TRUE"/> +  <!--SSAO Enabled--> +  <RenderDeferredSSAO value="TRUE"/> +  <!--Full Shadows--> +  <RenderShadowDetail value="2"/> +  </settings> diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index 4029bf95a0..1913f52499 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -23,7 +23,7 @@ version 21  // NOTE: All settings are set to the MIN of applied values, including 'all'!  //  list all -RenderAnisotropic			1	0 +RenderAnisotropic			1	1  RenderAvatarCloth			1	1  RenderAvatarLODFactor		1	1.0  RenderAvatarVP				1	1 @@ -35,18 +35,16 @@ RenderFogRatio				1	4.0  RenderGamma					1	0  RenderGlowResolutionPow		1	9  RenderGround				1	1 -RenderLightingDetail		1	1  RenderMaxPartCount			1	8192  RenderNightBrightness		1	1.0  RenderObjectBump			1	1 -RenderReflectionDetail		1	3 +RenderReflectionDetail		1	4  RenderTerrainDetail			1	1  RenderTerrainLODFactor		1	2.0  RenderTreeLODFactor			1	1.0  RenderUseImpostors			1	1  RenderVBOEnable				1	1  RenderVolumeLODFactor		1	2.0 -RenderWaterReflections		1	1  UseStartScreen				1	1  UseOcclusion				1	1  VertexShaderEnable			1	1 @@ -56,6 +54,9 @@ Disregard128DefaultDrawDistance	1	1  Disregard96DefaultDrawDistance	1	1  RenderTextureMemoryMultiple		1	1.0  RenderShaderLightingMaxLevel	1	3 +RenderDeferred				1	1 +RenderDeferredSSAO			1	1 +RenderShadowDetail			1	2  // @@ -69,7 +70,6 @@ RenderAvatarVP				1	0  RenderFarClip				1	64  RenderFlexTimeFactor		1	0.5  RenderGlowResolutionPow		1	8 -RenderLightingDetail		1	0  RenderMaxPartCount			1	1024  RenderObjectBump			1	0  RenderReflectionDetail		1	0 @@ -78,10 +78,13 @@ RenderTerrainLODFactor		1	1  RenderTreeLODFactor			1	0.5  RenderUseImpostors			1	1  RenderVolumeLODFactor		1	1.125 -RenderWaterReflections		1	0  VertexShaderEnable			1	0  WindLightUseAtmosShaders	1	0  WLSkyDetail					1	48 +RenderDeferred				1	0 +RenderDeferredSSAO			1	0 +RenderShadowDetail			1	0 +  //  // Mid Graphics Settings @@ -94,7 +97,6 @@ RenderAvatarVP				1	1  RenderFarClip				1	96  RenderFlexTimeFactor		1	1.0  RenderGlowResolutionPow		1	8 -RenderLightingDetail		1	1  RenderMaxPartCount			1	2048  RenderObjectBump			1	1  RenderReflectionDetail		1	0 @@ -103,10 +105,13 @@ RenderTerrainLODFactor		1	1.0  RenderTreeLODFactor			1	0.5  RenderUseImpostors			1	1  RenderVolumeLODFactor		1	1.125 -RenderWaterReflections		1	0  VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	0  WLSkyDetail					1	48 +RenderDeferred				1	0 +RenderDeferredSSAO			1	0 +RenderShadowDetail			1	0 +  //  // High Graphics Settings (purty) @@ -119,7 +124,6 @@ RenderAvatarVP				1	1  RenderFarClip				1	128  RenderFlexTimeFactor		1	1.0  RenderGlowResolutionPow		1	9 -RenderLightingDetail		1	1  RenderMaxPartCount			1	4096  RenderObjectBump			1	1  RenderReflectionDetail		1	2 @@ -128,10 +132,13 @@ RenderTerrainLODFactor		1	2.0  RenderTreeLODFactor			1	0.5  RenderUseImpostors			1	1  RenderVolumeLODFactor		1	1.125 -RenderWaterReflections		1	0  VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	1  WLSkyDetail					1	48 +RenderDeferred				1	1 +RenderDeferredSSAO			1	0 +RenderShadowDetail			1	1 +  //  // Ultra graphics (REALLY PURTY!) @@ -144,19 +151,21 @@ RenderAvatarVP				1	1  RenderFarClip				1	256  RenderFlexTimeFactor		1	1.0  RenderGlowResolutionPow		1	9 -RenderLightingDetail		1	1  RenderMaxPartCount			1	8192  RenderObjectBump			1	1 -RenderReflectionDetail		1	3 +RenderReflectionDetail		1	4  RenderTerrainDetail			1	1  RenderTerrainLODFactor		1	2.0  RenderTreeLODFactor			1	1.0  RenderUseImpostors			1	1  RenderVolumeLODFactor		1	2.0 -RenderWaterReflections		1	1  VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	1  WLSkyDetail					1	128 +RenderDeferred				1	1 +RenderDeferredSSAO			1	1 +RenderShadowDetail			1	2 +  //  // Class Unknown Hardware (unknown) @@ -194,9 +203,12 @@ RenderVBOEnable				1	1  list NoPixelShaders  RenderAvatarVP				0	0  RenderAvatarCloth			0	0 -RenderWaterReflections		0	0 +RenderReflectionDetail		0	0  VertexShaderEnable			0	0  WindLightUseAtmosShaders	0	0 +RenderDeferred				0	0 +RenderDeferredSSAO			0	0 +RenderShadowDetail			0	0  //  // No Vertex Shaders available @@ -204,9 +216,13 @@ WindLightUseAtmosShaders	0	0  list NoVertexShaders  RenderAvatarVP				0	0  RenderAvatarCloth			0	0 -RenderWaterReflections		0	0 +RenderReflectionDetail		0	0  VertexShaderEnable			0	0  WindLightUseAtmosShaders	0	0 +RenderDeferred				0	0 +RenderDeferredSSAO			0	0 +RenderShadowDetail			0	0 +  // "Default" setups for safe, low, medium, high  // @@ -214,14 +230,17 @@ list safe  RenderAnisotropic			1	0  RenderAvatarCloth			0	0  RenderAvatarVP				0	0 -RenderLightingDetail		1	0  RenderObjectBump			0	0  RenderMaxPartCount			1	1024  RenderTerrainDetail 		1	0  RenderUseImpostors			0	0  RenderVBOEnable				1	0 -RenderWaterReflections		0	0 +RenderReflectionDetail		0	0  WindLightUseAtmosShaders	0	0 +RenderDeferred				0	0 +RenderDeferredSSAO			0	0 +RenderShadowDetail			0	0 +  //  // CPU based feature masks @@ -245,11 +264,9 @@ RenderVBOEnable				1	0  list Intel  RenderAnisotropic			1	0 -RenderLightingDetail		1	0  list GeForce2  RenderAnisotropic			1	0 -RenderLightingDetail		1	0  RenderMaxPartCount			1	2048  RenderTerrainDetail			1	0  RenderVBOEnable				1	1 diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt index 61a8e51c50..254b9c4ce4 100644 --- a/indra/newview/featuretable_linux.txt +++ b/indra/newview/featuretable_linux.txt @@ -23,7 +23,7 @@ version 21  // NOTE: All settings are set to the MIN of applied values, including 'all'!  //  list all -RenderAnisotropic			1	0 +RenderAnisotropic			1	1  RenderAvatarCloth			1	1  RenderAvatarLODFactor		1	1.0  RenderAvatarVP				1	1 @@ -35,18 +35,16 @@ RenderFogRatio				1	4.0  RenderGamma					1	0  RenderGlowResolutionPow		1	9  RenderGround				1	1 -RenderLightingDetail		1	1  RenderMaxPartCount			1	8192  RenderNightBrightness		1	1.0  RenderObjectBump			1	1 -RenderReflectionDetail		1	3 +RenderReflectionDetail		1	4  RenderTerrainDetail			1	1  RenderTerrainLODFactor		1	2.0  RenderTreeLODFactor			1	1.0  RenderUseImpostors			1	1  RenderVBOEnable				1	1  RenderVolumeLODFactor		1	2.0 -RenderWaterReflections		1	1  UseStartScreen				1	1  UseOcclusion				1	1  VertexShaderEnable			1	1 @@ -55,6 +53,10 @@ WLSkyDetail					1	128  Disregard128DefaultDrawDistance	1	1  Disregard96DefaultDrawDistance	1	1  RenderTextureMemoryMultiple		1	1.0 +RenderShaderLightingMaxLevel		1	3 +RenderDeferred				1	1 +RenderDeferredSSAO			1	1 +RenderShadowDetail			1	2  //  // Low Graphics Settings @@ -67,7 +69,6 @@ RenderAvatarVP				1	0  RenderFarClip				1	64  RenderFlexTimeFactor		1	0.5  RenderGlowResolutionPow		1	8 -RenderLightingDetail		1	0  RenderMaxPartCount			1	1024  RenderObjectBump			1	0  RenderReflectionDetail		1	0 @@ -76,10 +77,13 @@ RenderTerrainLODFactor		1	1  RenderTreeLODFactor			1	0.5  RenderUseImpostors			1	1  RenderVolumeLODFactor		1	1.125 -RenderWaterReflections		1	0  VertexShaderEnable			1	0  WindLightUseAtmosShaders	1	0  WLSkyDetail					1	48 +RenderDeferred				1	0 +RenderDeferredSSAO			1	0 +RenderShadowDetail			1	0 +  //  // Mid Graphics Settings @@ -92,7 +96,6 @@ RenderAvatarVP				1	1  RenderFarClip				1	96  RenderFlexTimeFactor		1	1.0  RenderGlowResolutionPow		1	8 -RenderLightingDetail		1	1  RenderMaxPartCount			1	2048  RenderObjectBump			1	1  RenderReflectionDetail		1	0 @@ -101,10 +104,13 @@ RenderTerrainLODFactor		1	1.0  RenderTreeLODFactor			1	0.5  RenderUseImpostors			1	1  RenderVolumeLODFactor		1	1.125 -RenderWaterReflections		1	0  VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	0  WLSkyDetail					1	48 +RenderDeferred				1	0 +RenderDeferredSSAO			1	0 +RenderShadowDetail			1	0 +  //  // High Graphics Settings (purty) @@ -117,7 +123,6 @@ RenderAvatarVP				1	1  RenderFarClip				1	128  RenderFlexTimeFactor		1	1.0  RenderGlowResolutionPow		1	9 -RenderLightingDetail		1	1  RenderMaxPartCount			1	4096  RenderObjectBump			1	1  RenderReflectionDetail		1	2 @@ -126,10 +131,13 @@ RenderTerrainLODFactor		1	2.0  RenderTreeLODFactor			1	0.5  RenderUseImpostors			1	1  RenderVolumeLODFactor		1	1.125 -RenderWaterReflections		1	0  VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	1  WLSkyDetail					1	48 +RenderDeferred				1	1 +RenderDeferredSSAO			1	0 +RenderShadowDetail			1	1 +  //  // Ultra graphics (REALLY PURTY!) @@ -142,19 +150,21 @@ RenderAvatarVP				1	1  RenderFarClip				1	256  RenderFlexTimeFactor		1	1.0  RenderGlowResolutionPow		1	9 -RenderLightingDetail		1	1  RenderMaxPartCount			1	8192  RenderObjectBump			1	1 -RenderReflectionDetail		1	3 +RenderReflectionDetail		1	4  RenderTerrainDetail			1	1  RenderTerrainLODFactor		1	2.0  RenderTreeLODFactor			1	1.0  RenderUseImpostors			1	1  RenderVolumeLODFactor		1	2.0 -RenderWaterReflections		1	1  VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	1  WLSkyDetail					1	128 +RenderDeferred				1	1 +RenderDeferredSSAO			1	1 +RenderShadowDetail			1	2 +  //  // Class Unknown Hardware (unknown) @@ -192,9 +202,12 @@ RenderVBOEnable				1	1  list NoPixelShaders  RenderAvatarVP				0	0  RenderAvatarCloth			0	0 -RenderWaterReflections		0	0 +RenderReflectionDetail		0	0  VertexShaderEnable			0	0  WindLightUseAtmosShaders	0	0 +RenderDeferred				0	0 +RenderDeferredSSAO			0	0 +RenderShadowDetail			0	0  //  // No Vertex Shaders available @@ -202,9 +215,13 @@ WindLightUseAtmosShaders	0	0  list NoVertexShaders  RenderAvatarVP				0	0  RenderAvatarCloth			0	0 -RenderWaterReflections		0	0 +RenderReflectionDetail		0	0  VertexShaderEnable			0	0  WindLightUseAtmosShaders	0	0 +RenderDeferred				0	0 +RenderDeferredSSAO			0	0 +RenderShadowDetail			0	0 +  // "Default" setups for safe, low, medium, high  // @@ -212,14 +229,17 @@ list safe  RenderAnisotropic			1	0  RenderAvatarCloth			0	0  RenderAvatarVP				0	0 -RenderLightingDetail		1	0  RenderObjectBump			0	0  RenderMaxPartCount			1	1024  RenderTerrainDetail 		1	0  RenderUseImpostors			0	0  RenderVBOEnable				1	0 -RenderWaterReflections		0	0 +RenderReflectionDetail		0	0  WindLightUseAtmosShaders	0	0 +RenderDeferred				0	0 +RenderDeferredSSAO			0	0 +RenderShadowDetail			0	0 +  //  // CPU based feature masks @@ -243,13 +263,11 @@ RenderVBOEnable				1	0  list Intel  RenderAnisotropic			1	0 -RenderLightingDetail		1	0  // Avoid some Intel crashes on Linux  RenderCubeMap				0	0  list GeForce2  RenderAnisotropic			1	0 -RenderLightingDetail		1	0  RenderMaxPartCount			1	2048  RenderTerrainDetail			1	0  RenderVBOEnable				1	1 @@ -461,17 +479,47 @@ list NVIDIA_GeForce_Go_6  RenderVBOEnable				1	0  Disregard128DefaultDrawDistance	1	0 +list NVIDIA_GeForce_7000 +RenderShaderLightingMaxLevel	1	2 +list NVIDIA_GeForce_7100 +RenderShaderLightingMaxLevel	1	2  list NVIDIA_GeForce_7200  Disregard128DefaultDrawDistance	1	0 +RenderShaderLightingMaxLevel	1	2  list NVIDIA_GeForce_7300  Disregard128DefaultDrawDistance	1	0 +RenderShaderLightingMaxLevel	1	2  list NVIDIA_GeForce_7400  Disregard128DefaultDrawDistance	1	0 +RenderShaderLightingMaxLevel	1	2 +list NVIDIA_GeForce_7500 +RenderShaderLightingMaxLevel	1	2 +list NVIDIA_GeForce_7600 +RenderShaderLightingMaxLevel	1	2 +list NVIDIA_GeForce_7700 +RenderShaderLightingMaxLevel	1	2 +list NVIDIA_GeForce_7800 +RenderShaderLightingMaxLevel	1	2 +list NVIDIA_GeForce_7900 +RenderShaderLightingMaxLevel	1	2  list NVIDIA_GeForce_Go_7200  Disregard128DefaultDrawDistance	1	0 +RenderShaderLightingMaxLevel	1	2  list NVIDIA_GeForce_Go_7300  Disregard128DefaultDrawDistance	1	0 +RenderShaderLightingMaxLevel	1	2 +list NVIDIA_GeForce_Go_7300_LE +RenderShaderLightingMaxLevel	1	2  list NVIDIA_GeForce_Go_7400  Disregard128DefaultDrawDistance	1	0 +RenderShaderLightingMaxLevel	1	2 +list NVIDIA_GeForce_Go_7600 +RenderShaderLightingMaxLevel	1	2 +list NVIDIA_GeForce_Go_7700 +RenderShaderLightingMaxLevel	1	2 +list NVIDIA_GeForce_Go_7800 +RenderShaderLightingMaxLevel	1	2 +list NVIDIA_GeForce_Go_7900 +RenderShaderLightingMaxLevel	1	2 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index 12d47a904c..db0252d2e7 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -366,6 +366,7 @@ list ATI_Radeon_X1500  Disregard128DefaultDrawDistance	1	0  list ATI_Radeon_X1600   Disregard128DefaultDrawDistance	1	0 +RenderUseFBO 					0	0  list ATI_Radeon_X1700   Disregard128DefaultDrawDistance	1	0  list ATI_Mobility_Radeon_X1xxx diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 8e959993fe..0e2507db5b 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -922,6 +922,11 @@ static LLFastTimer::DeclareTimer FTM_LFS("LFS Thread");  static LLFastTimer::DeclareTimer FTM_PAUSE_THREADS("Pause Threads");  static LLFastTimer::DeclareTimer FTM_IDLE("Idle");  static LLFastTimer::DeclareTimer FTM_PUMP("Pump"); +static LLFastTimer::DeclareTimer FTM_PUMP_ARES("Ares"); +static LLFastTimer::DeclareTimer FTM_PUMP_SERVICE("Service"); +static LLFastTimer::DeclareTimer FTM_SERVICE_CALLBACK("Callback"); +static LLFastTimer::DeclareTimer FTM_AGENT_AUTOPILOT("Autopilot"); +static LLFastTimer::DeclareTimer FTM_AGENT_UPDATE("Update");  bool LLAppViewer::mainLoop()  { @@ -1033,10 +1038,20 @@ bool LLAppViewer::mainLoop()  						LLMemType mt_ip(LLMemType::MTYPE_IDLE_PUMP);  						pingMainloopTimeout("Main:ServicePump");				  						LLFastTimer t4(FTM_PUMP); -						gAres->process(); -						// this pump is necessary to make the login screen show up -						gServicePump->pump(); -						gServicePump->callback(); +						{ +							LLFastTimer t(FTM_PUMP_ARES); +							gAres->process(); +						} +						{ +							LLFastTimer t(FTM_PUMP_SERVICE); +							// this pump is necessary to make the login screen show up +							gServicePump->pump(); + +							{ +								LLFastTimer t(FTM_SERVICE_CALLBACK); +								gServicePump->callback(); +							} +						}  					}  					resumeMainloopTimeout(); @@ -3512,9 +3527,12 @@ void LLAppViewer::idle()  			gAgent.moveYaw(-1.f);  		} -	    // Handle automatic walking towards points -	    gAgentPilot.updateTarget(); -	    gAgent.autoPilot(&yaw); +		{ +			LLFastTimer t(FTM_AGENT_AUTOPILOT); +			// Handle automatic walking towards points +			gAgentPilot.updateTarget(); +			gAgent.autoPilot(&yaw); +		}  	    static LLFrameTimer agent_update_timer;  	    static U32 				last_control_flags; @@ -3525,6 +3543,7 @@ void LLAppViewer::idle()  	    if (flags_changed || (agent_update_time > (1.0f / (F32) AGENT_UPDATES_PER_SECOND)))  	    { +		    LLFastTimer t(FTM_AGENT_UPDATE);  		    // Send avatar and camera info  		    last_control_flags = gAgent.getControlFlags();  		    send_agent_update(TRUE); diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index ef946ac49e..ae30af3647 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -442,7 +442,6 @@ void LLRenderPass::renderTexture(U32 type, U32 mask)  void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture)  { -	llpushcallstacks ;  	for (LLCullResult::drawinfo_list_t::iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)	  	{  		LLDrawInfo* pparams = *i; @@ -475,6 +474,7 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture)  	{  		if (params.mTexture.notNull())  		{ +			params.mTexture->addTextureStats(params.mVSize);  			gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ;  			if (params.mTextureMatrix)  			{ diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 875c9ac6a9..7fd7cd3910 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -60,7 +60,9 @@ static BOOL deferred_render = FALSE;  LLDrawPoolAlpha::LLDrawPoolAlpha(U32 type) :  		LLRenderPass(type), current_shader(NULL), target_shader(NULL), -		simple_shader(NULL), fullbright_shader(NULL) +		simple_shader(NULL), fullbright_shader(NULL), +		mColorSFactor(LLRender::BF_UNDEF), mColorDFactor(LLRender::BF_UNDEF), +		mAlphaSFactor(LLRender::BF_UNDEF), mAlphaDFactor(LLRender::BF_UNDEF)  {  } @@ -178,9 +180,16 @@ void LLDrawPoolAlpha::render(S32 pass)  	LLGLSPipelineAlpha gls_pipeline_alpha; +	gGL.setColorMask(true, true); +  	if (LLPipeline::sFastAlpha && !deferred_render)  	{ -		LLGLDisable blend_disable(GL_BLEND); +		mColorSFactor = LLRender::BF_ONE;  // } +		mColorDFactor = LLRender::BF_ZERO; // } these are like disabling blend on the color channels, but we're still blending on the alpha channel so that we can suppress glow +		mAlphaSFactor = LLRender::BF_ZERO; +		mAlphaDFactor = LLRender::BF_ZERO; // block (zero-out) glow where the alpha test succeeds +		gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); +  		gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.33f);  		if (mVertexShaderLevel > 0)  		{ @@ -204,8 +213,17 @@ void LLDrawPoolAlpha::render(S32 pass)  	}  	LLGLDepthTest depth(GL_TRUE, LLDrawPoolWater::sSkipScreenCopy ? GL_TRUE : GL_FALSE); + +	mColorSFactor = LLRender::BF_SOURCE_ALPHA;           // } regular alpha blend +	mColorDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // } +	mAlphaSFactor = LLRender::BF_ZERO;                         // } glow suppression +	mAlphaDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA;       // } +	gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); +  	renderAlpha(getVertexDataMask()); +	gGL.setColorMask(true, false); +  	if (deferred_render && current_shader != NULL)  	{  		gPipeline.unbindDeferredShader(*current_shader); @@ -283,9 +301,18 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  	for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)  	{  		LLSpatialGroup* group = *i; +		llassert(group); +		llassert(group->mSpatialPartition); +  		if (group->mSpatialPartition->mRenderByGroup && -			!group->isDead()) +		    !group->isDead())  		{ +			bool draw_glow_for_this_partition = mVertexShaderLevel > 0 && // no shaders = no glow. +				// All particle systems seem to come off the wire with texture entries which claim that they glow.  This is probably a bug in the data.  Suppress. +				group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_PARTICLE && +				group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_CLOUD && +				group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_HUD_PARTICLE; +  			LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA];  			for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)	 @@ -294,96 +321,118 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  				LLRenderPass::applyModelMatrix(params); -				if (params.mFullbright)  				{ -					// Turn off lighting if it hasn't already been so. -					if (light_enabled || !initialized_lighting) +					if (params.mFullbright) +					{ +						// Turn off lighting if it hasn't already been so. +						if (light_enabled || !initialized_lighting) +						{ +							initialized_lighting = TRUE; +							if (use_shaders)  +							{ +								target_shader = fullbright_shader; +							} +							else +							{ +								gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); +							} +							light_enabled = FALSE; +						} +					} +					// Turn on lighting if it isn't already. +					else if (!light_enabled || !initialized_lighting)  					{  						initialized_lighting = TRUE;  						if (use_shaders)   						{ -							target_shader = fullbright_shader; +							target_shader = simple_shader;  						}  						else  						{ -							gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); +							gPipeline.enableLightsDynamic();  						} -						light_enabled = FALSE; +						light_enabled = TRUE;  					} -				} -				// Turn on lighting if it isn't already. -				else if (!light_enabled || !initialized_lighting) -				{ -					initialized_lighting = TRUE; -					if (use_shaders)  -					{ -						target_shader = simple_shader; -					} -					else -					{ -						gPipeline.enableLightsDynamic(); -					} -					light_enabled = TRUE; -				} -				// If we need shaders, and we're not ALREADY using the proper shader, then bind it -				// (this way we won't rebind shaders unnecessarily). -				if(use_shaders && (current_shader != target_shader)) -				{ -					llassert(target_shader != NULL); -					if (deferred_render && current_shader != NULL) +					// If we need shaders, and we're not ALREADY using the proper shader, then bind it +					// (this way we won't rebind shaders unnecessarily). +					if(use_shaders && (current_shader != target_shader))  					{ -						gPipeline.unbindDeferredShader(*current_shader); -						diffuse_channel = 0; -					} -					current_shader = target_shader; -					if (deferred_render) -					{ -						gPipeline.bindDeferredShader(*current_shader); -						diffuse_channel = current_shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); -					} -					else -					{ -						current_shader->bind(); +						llassert(target_shader != NULL); +						if (deferred_render && current_shader != NULL) +						{ +							gPipeline.unbindDeferredShader(*current_shader); +							diffuse_channel = 0; +						} +						current_shader = target_shader; +						if (deferred_render) +						{ +							gPipeline.bindDeferredShader(*current_shader); +							diffuse_channel = current_shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); +						} +						else +						{ +							current_shader->bind(); +						}  					} -				} -				else if (!use_shaders && current_shader != NULL) -				{ -					if (deferred_render) +					else if (!use_shaders && current_shader != NULL)  					{ -						gPipeline.unbindDeferredShader(*current_shader); -						diffuse_channel = 0; +						if (deferred_render) +						{ +							gPipeline.unbindDeferredShader(*current_shader); +							diffuse_channel = 0; +						} +						LLGLSLShader::bindNoShader(); +						current_shader = NULL;  					} -					LLGLSLShader::bindNoShader(); -					current_shader = NULL; -				} - -				if (params.mGroup) -				{ -					params.mGroup->rebuildMesh(); -				} -				 -				if (params.mTexture.notNull()) -				{ -					gGL.getTexUnit(diffuse_channel)->bind(params.mTexture.get()); -					if(params.mTexture.notNull()) +					if (params.mGroup)  					{ -						params.mTexture->addTextureStats(params.mVSize); +						params.mGroup->rebuildMesh();  					} -					if (params.mTextureMatrix) + +					 +					if (params.mTexture.notNull())  					{ -						gGL.getTexUnit(0)->activate(); -						glMatrixMode(GL_TEXTURE); -						glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); -						gPipeline.mTextureMatrixOps++; +						gGL.getTexUnit(diffuse_channel)->bind(params.mTexture.get()); +						if(params.mTexture.notNull()) +						{ +							params.mTexture->addTextureStats(params.mVSize); +						} +						if (params.mTextureMatrix) +						{ +							gGL.getTexUnit(0)->activate(); +							glMatrixMode(GL_TEXTURE); +							glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); +							gPipeline.mTextureMatrixOps++; +						}  					}  				}  				params.mVertexBuffer->setBuffer(mask);  				params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);  				gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); +				 +				// If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow).  Interleaving these state-changing calls could be expensive, but glow must be drawn Z-sorted with alpha. +				if (draw_glow_for_this_partition && +				    params.mGlowColor.mV[3] > 0) +				{ +					// install glow-accumulating blend mode +					gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, // don't touch color +						      LLRender::BF_ONE, LLRender::BF_ONE); // add to alpha (glow) +					// glow doesn't use vertex colors from the mesh data +					params.mVertexBuffer->setBuffer(mask & ~LLVertexBuffer::MAP_COLOR); +					glColor4ubv(params.mGlowColor.mV); + +					// do the actual drawing, again +					params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); +					gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); + +					// restore our alpha blend mode +					gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); +				} +			  				if (params.mTextureMatrix && params.mTexture.notNull())  				{  					gGL.getTexUnit(0)->activate(); diff --git a/indra/newview/lldrawpoolalpha.h b/indra/newview/lldrawpoolalpha.h index 3aa752f72c..61f73d0b31 100644 --- a/indra/newview/lldrawpoolalpha.h +++ b/indra/newview/lldrawpoolalpha.h @@ -34,6 +34,7 @@  #define LL_LLDRAWPOOLALPHA_H  #include "lldrawpool.h" +#include "llrender.h"  #include "llframetimer.h"  class LLFace; @@ -83,6 +84,12 @@ private:  	LLGLSLShader* target_shader;  	LLGLSLShader* simple_shader;  	LLGLSLShader* fullbright_shader;	 + +	// our 'normal' alpha blend function for this pass +	LLRender::eBlendFactor mColorSFactor; +	LLRender::eBlendFactor mColorDFactor;	 +	LLRender::eBlendFactor mAlphaSFactor; +	LLRender::eBlendFactor mAlphaDFactor;  };  class LLDrawPoolAlphaPostWater : public LLDrawPoolAlpha diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 546b60f286..012e41383f 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -157,6 +157,8 @@ void LLDrawPoolAvatar::beginDeferredPass(S32 pass)  {  	LLFastTimer t(FTM_RENDER_CHARACTERS); +	sSkipTransparent = TRUE; +  	if (LLPipeline::sImpostorRender)  	{  		beginDeferredSkinned(); @@ -181,6 +183,8 @@ void LLDrawPoolAvatar::endDeferredPass(S32 pass)  {  	LLFastTimer t(FTM_RENDER_CHARACTERS); +	sSkipTransparent = FALSE; +  	if (LLPipeline::sImpostorRender)  	{  		endDeferredSkinned(); @@ -564,7 +568,6 @@ void LLDrawPoolAvatar::endSkinned()  void LLDrawPoolAvatar::beginDeferredSkinned()  { -	sSkipTransparent = TRUE;  	sShaderLevel = mVertexShaderLevel;  	sVertexProgram = &gDeferredAvatarProgram; @@ -579,7 +582,6 @@ void LLDrawPoolAvatar::beginDeferredSkinned()  void LLDrawPoolAvatar::endDeferredSkinned()  { -	sSkipTransparent = FALSE;  	// if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done  	sRenderingSkinned = FALSE;  	disable_vertex_weighting(sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT]); diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index d09d4a412f..8f3e775976 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -701,6 +701,18 @@ void LLDrawPoolBump::endBump()  	gGL.setSceneBlendType(LLRender::BT_ALPHA);  } +S32 LLDrawPoolBump::getNumDeferredPasses() +{  +	if (gSavedSettings.getBOOL("RenderObjectBump")) +	{ +		return 1; +	} +	else +	{ +		return 0; +	} +} +  void LLDrawPoolBump::beginDeferredPass(S32 pass)  {  	if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_BUMP)) @@ -825,7 +837,6 @@ void LLBumpImageList::addTextureStats(U8 bump, const LLUUID& base_image_id, F32  void LLBumpImageList::updateImages()  {	 -	llpushcallstacks ;  	for (bump_image_map_t::iterator iter = mBrightnessEntries.begin(); iter != mBrightnessEntries.end(); )  	{  		bump_image_map_t::iterator curiter = iter++; @@ -852,7 +863,7 @@ void LLBumpImageList::updateImages()  			}  		}  	} -	llpushcallstacks ; +	  	for (bump_image_map_t::iterator iter = mDarknessEntries.begin(); iter != mDarknessEntries.end(); )  	{  		bump_image_map_t::iterator curiter = iter++; @@ -879,7 +890,6 @@ void LLBumpImageList::updateImages()  			}  		}  	} -	llpushcallstacks ;  } diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h index bf940cf1e4..2019f1df26 100644 --- a/indra/newview/lldrawpoolbump.h +++ b/indra/newview/lldrawpoolbump.h @@ -79,7 +79,7 @@ public:  	void renderBump();  	void endBump(); -	virtual S32 getNumDeferredPasses() { return 1; } +	virtual S32 getNumDeferredPasses();  	/*virtual*/ void beginDeferredPass(S32 pass);  	/*virtual*/ void endDeferredPass(S32 pass);  	/*virtual*/ void renderDeferred(S32 pass); diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 9de69a8173..8d86070bdf 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -862,12 +862,14 @@ void LLFace::updateRebuildFlags()  	}  } +static LLFastTimer::DeclareTimer FTM_FACE_GET_GEOM("Face Geom"); +  BOOL LLFace::getGeometryVolume(const LLVolume& volume,  							   const S32 &f,  								const LLMatrix4& mat_vert, const LLMatrix3& mat_normal,  								const U16 &index_offset)  { -	llpushcallstacks ; +	LLFastTimer t(FTM_FACE_GET_GEOM);  	const LLVolumeFace &vf = volume.getVolumeFace(f);  	S32 num_vertices = (S32)vf.mVertices.size();  	S32 num_indices = LLPipeline::sUseTriStrips ? (S32)vf.mTriStrip.size() : (S32) vf.mIndices.size(); diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index e2c5ad6d02..00292eecb4 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -799,7 +799,7 @@ void LLFloaterPreference::buildPopupLists()  void LLFloaterPreference::refreshEnabledState()  {	 -	LLCheckBoxCtrl* ctrl_reflections = getChild<LLCheckBoxCtrl>("Reflections"); +	LLComboBox* ctrl_reflections = getChild<LLComboBox>("Reflections");  	LLRadioGroup* radio_reflection_detail = getChild<LLRadioGroup>("ReflectionDetailRadio");  	// Reflections @@ -812,7 +812,7 @@ void LLFloaterPreference::refreshEnabledState()  	bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump");  	getChild<LLCheckBoxCtrl>("BumpShiny")->setEnabled(bumpshiny ? TRUE : FALSE); -	radio_reflection_detail->setEnabled(ctrl_reflections->get() && reflections); +	radio_reflection_detail->setEnabled(reflections);  	// Avatar Mode  	// Enable Avatar Shaders @@ -858,6 +858,26 @@ void LLFloaterPreference::refreshEnabledState()  	// *HACK just checks to see if we can use shaders...   	// maybe some cards that use shaders, but don't support windlight  	ctrl_wind_light->setEnabled(ctrl_shader_enable->getEnabled() && shaders); + +	//Deferred/SSAO/Shadows +	LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders"); +	if (LLFeatureManager::getInstance()->isFeatureAvailable("RenderUseFBO") && +		shaders) +	{ +		BOOL enabled = ctrl_wind_light->get() ? TRUE : FALSE; + +		ctrl_deferred->setEnabled(enabled); +	 +		LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO"); +		LLComboBox* ctrl_shadow = getChild<LLComboBox>("ShadowDetail"); + +		enabled = enabled && (ctrl_deferred->get() ? TRUE : FALSE); +		 +		ctrl_ssao->setEnabled(enabled); +		ctrl_shadow->setEnabled(enabled); +	} + +  	// now turn off any features that are unavailable  	disableUnavailableSettings(); @@ -866,12 +886,15 @@ void LLFloaterPreference::refreshEnabledState()  void LLFloaterPreference::disableUnavailableSettings()  {	 -	LLCheckBoxCtrl* ctrl_reflections   = getChild<LLCheckBoxCtrl>("Reflections"); +	LLComboBox* ctrl_reflections   = getChild<LLComboBox>("Reflections");  	LLCheckBoxCtrl* ctrl_avatar_vp     = getChild<LLCheckBoxCtrl>("AvatarVertexProgram");  	LLCheckBoxCtrl* ctrl_avatar_cloth  = getChild<LLCheckBoxCtrl>("AvatarCloth");  	LLCheckBoxCtrl* ctrl_shader_enable = getChild<LLCheckBoxCtrl>("BasicShaders");  	LLCheckBoxCtrl* ctrl_wind_light    = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");  	LLCheckBoxCtrl* ctrl_avatar_impostors = getChild<LLCheckBoxCtrl>("AvatarImpostors"); +	LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders"); +	LLComboBox* ctrl_shadows = getChild<LLComboBox>("ShadowDetail"); +	LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO");  	// if vertex shaders off, disable all shader related products  	if(!LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable")) @@ -883,13 +906,22 @@ void LLFloaterPreference::disableUnavailableSettings()  		ctrl_wind_light->setValue(FALSE);  		ctrl_reflections->setEnabled(FALSE); -		ctrl_reflections->setValue(FALSE); +		ctrl_reflections->setValue(0);  		ctrl_avatar_vp->setEnabled(FALSE);  		ctrl_avatar_vp->setValue(FALSE);  		ctrl_avatar_cloth->setEnabled(FALSE);  		ctrl_avatar_cloth->setValue(FALSE); + +		ctrl_shadows->setEnabled(FALSE); +		ctrl_shadows->setValue(0); +		 +		ctrl_ssao->setEnabled(FALSE); +		ctrl_ssao->setValue(FALSE); + +		ctrl_deferred->setEnabled(FALSE); +		ctrl_deferred->setValue(FALSE);  	}  	// disabled windlight @@ -897,10 +929,20 @@ void LLFloaterPreference::disableUnavailableSettings()  	{  		ctrl_wind_light->setEnabled(FALSE);  		ctrl_wind_light->setValue(FALSE); + +		//deferred needs windlight, disable deferred +		ctrl_shadows->setEnabled(FALSE); +		ctrl_shadows->setValue(0); +		 +		ctrl_ssao->setEnabled(FALSE); +		ctrl_ssao->setValue(FALSE); + +		ctrl_deferred->setEnabled(FALSE); +		ctrl_deferred->setValue(FALSE);  	}  	// disabled reflections -	if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderWaterReflections")) +	if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderReflectionDetail"))  	{  		ctrl_reflections->setEnabled(FALSE);  		ctrl_reflections->setValue(FALSE); @@ -914,13 +956,25 @@ void LLFloaterPreference::disableUnavailableSettings()  		ctrl_avatar_cloth->setEnabled(FALSE);  		ctrl_avatar_cloth->setValue(FALSE); + +		//deferred needs AvatarVP, disable deferred +		ctrl_shadows->setEnabled(FALSE); +		ctrl_shadows->setValue(0); +		 +		ctrl_ssao->setEnabled(FALSE); +		ctrl_ssao->setValue(FALSE); + +		ctrl_deferred->setEnabled(FALSE); +		ctrl_deferred->setValue(FALSE);  	} +  	// disabled cloth  	if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarCloth"))  	{  		ctrl_avatar_cloth->setEnabled(FALSE);  		ctrl_avatar_cloth->setValue(FALSE);  	} +  	// disabled impostors  	if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderUseImpostors"))  	{ diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index 30221da12a..669ff3ffd6 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -137,6 +137,10 @@ BOOL	LLPanelObject::postBuild()  	// Phantom checkbox  	mCheckPhantom = getChild<LLCheckBoxCtrl>("Phantom Checkbox Ctrl");  	childSetCommitCallback("Phantom Checkbox Ctrl",onCommitPhantom,this); + +	// PhysicsShapeType combobox +	mComboPhysicsShapeType = getChild<LLComboBox>("Physics Shape Type Combo Ctrl"); +	childSetCommitCallback("Physics Shape Type Combo Ctrl", onCommitPhysicsShapeType,this);  	// Position  	mLabelPosition = getChild<LLTextBox>("label position"); @@ -320,6 +324,7 @@ LLPanelObject::LLPanelObject()  	mIsPhysical(FALSE),  	mIsTemporary(FALSE),  	mIsPhantom(FALSE), +	mPhysicsShapeType(0),  	mCastShadows(TRUE),  	mSelectedType(MI_BOX),  	mSculptTextureRevert(LLUUID::null), @@ -527,6 +532,10 @@ void LLPanelObject::getState( )  	mCheckPhantom->set( mIsPhantom );  	mCheckPhantom->setEnabled( roots_selected>0 && editable && !is_flexible ); +	mPhysicsShapeType = objectp->getPhysicsShapeType(); +	mComboPhysicsShapeType->setCurrentByIndex(mPhysicsShapeType); +	mComboPhysicsShapeType->setEnabled(editable); +  #if 0 // 1.9.2  	mCastShadows = root_objectp->flagCastShadows();  	mCheckCastShadows->set( mCastShadows ); @@ -1232,6 +1241,22 @@ void LLPanelObject::sendIsPhantom()  	}  } +void LLPanelObject::sendPhysicsShapeType() +{ +	U8 value = (U8)mComboPhysicsShapeType->getCurrentIndex(); +	if (mPhysicsShapeType != value) +	{ +		LLSelectMgr::getInstance()->selectionUpdatePhysicsShapeType(value); +		mPhysicsShapeType = value; +		 +		llinfos << "update physics shape type sent" << llendl; +	} +	else +	{ +		llinfos << "update physics shape type not changed" << llendl; +	} +} +  void LLPanelObject::sendCastShadows()  {  	BOOL value = mCheckCastShadows->get(); @@ -1905,6 +1930,8 @@ void LLPanelObject::clearCtrls()  	mCheckTemporary	->setEnabled( FALSE );  	mCheckPhantom	->set(FALSE);  	mCheckPhantom	->setEnabled( FALSE ); +	mComboPhysicsShapeType->setCurrentByIndex(0); +	mComboPhysicsShapeType->setEnabled(FALSE);  #if 0 // 1.9.2  	mCheckCastShadows->set(FALSE);  	mCheckCastShadows->setEnabled( FALSE ); @@ -2000,6 +2027,13 @@ void LLPanelObject::onCommitPhantom( LLUICtrl* ctrl, void* userdata )  }  // static +void LLPanelObject::onCommitPhysicsShapeType(LLUICtrl* ctrl, void* userdata ) +{ +	LLPanelObject* self = (LLPanelObject*) userdata; +	self->sendPhysicsShapeType(); +} + +// static  void LLPanelObject::onCommitCastShadows( LLUICtrl* ctrl, void* userdata )  {  	LLPanelObject* self = (LLPanelObject*) userdata; diff --git a/indra/newview/llpanelobject.h b/indra/newview/llpanelobject.h index 58d9fe9b76..7f368c38c7 100644 --- a/indra/newview/llpanelobject.h +++ b/indra/newview/llpanelobject.h @@ -65,13 +65,14 @@ public:  	static bool		precommitValidate(const LLSD& data);  	static void		onCommitLock(LLUICtrl *ctrl, void *data); -	static void 	onCommitPosition(		LLUICtrl* ctrl, void* userdata); -	static void 	onCommitScale(			LLUICtrl* ctrl, void* userdata); -	static void 	onCommitRotation(		LLUICtrl* ctrl, void* userdata); -	static void 	onCommitPhysics(		LLUICtrl* ctrl, void* userdata); -	static void 	onCommitTemporary(		LLUICtrl* ctrl, void* userdata); -	static void 	onCommitPhantom(		LLUICtrl* ctrl, void* userdata); -	static void 	onCommitCastShadows(	LLUICtrl* ctrl, void* userdata); +	static void 	onCommitPosition(			LLUICtrl* ctrl, void* userdata); +	static void 	onCommitScale(				LLUICtrl* ctrl, void* userdata); +	static void 	onCommitRotation(			LLUICtrl* ctrl, void* userdata); +	static void 	onCommitPhysics(			LLUICtrl* ctrl, void* userdata); +	static void 	onCommitTemporary(			LLUICtrl* ctrl, void* userdata); +	static void 	onCommitPhantom(			LLUICtrl* ctrl, void* userdata); +	static void     onCommitPhysicsShapeType(   LLUICtrl* ctrl, void* userdata); +	static void 	onCommitCastShadows(		LLUICtrl* ctrl, void* userdata);  	static void 	onCommitParametric(LLUICtrl* ctrl, void* userdata); @@ -93,6 +94,7 @@ protected:  	void			sendIsPhysical();  	void			sendIsTemporary();  	void			sendIsPhantom(); +	void            sendPhysicsShapeType();  	void			sendCastShadows();  	void            sendSculpt(); @@ -165,8 +167,9 @@ protected:  	LLCheckBoxCtrl	*mCheckPhysics;  	LLCheckBoxCtrl	*mCheckTemporary;  	LLCheckBoxCtrl	*mCheckPhantom; +	LLComboBox      *mComboPhysicsShapeType;  	LLCheckBoxCtrl	*mCheckCastShadows; - +	  	LLTextureCtrl   *mCtrlSculptTexture;  	LLTextBox       *mLabelSculptType;  	LLComboBox      *mCtrlSculptType; @@ -177,6 +180,7 @@ protected:  	BOOL			mIsPhysical;			// to avoid sending "physical" when not changed  	BOOL			mIsTemporary;			// to avoid sending "temporary" when not changed  	BOOL			mIsPhantom;				// to avoid sending "phantom" when not changed +	U8              mPhysicsShapeType;		// to avoid sending "physics shape type" when not changed  	BOOL			mCastShadows;			// to avoid sending "cast shadows" when not changed  	S32				mSelectedType;			// So we know what selected type we last were diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index fbe68b4d92..8b01637239 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -574,7 +574,7 @@ void LLPanelVolume::onCommitLight( LLUICtrl* ctrl, void* userdata )  		LLUUID id = LightTextureCtrl->getImageAssetID();  		if (id.notNull())  		{ -			if (volobjp->getLightTextureID().isNull()) +			if (!volobjp->isLightSpotlight())  			{ //this commit is making this a spot light, set UI to default params  				volobjp->setLightTextureID(id);  				LLVector3 spot_params = volobjp->getSpotLightParams(); @@ -591,7 +591,7 @@ void LLPanelVolume::onCommitLight( LLUICtrl* ctrl, void* userdata )  				volobjp->setSpotLightParams(spot_params);  			}  		} -		else if (volobjp->getLightTextureID().notNull()) +		else if (volobjp->isLightSpotlight())  		{ //no longer a spot light  			volobjp->setLightTextureID(id);  			//self->childDisable("Light FOV"); diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index d03a492cd1..d47cc06ebc 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -3931,6 +3931,28 @@ void LLSelectMgr::selectionUpdateCastShadows(BOOL cast_shadows)  	getSelection()->applyToObjects(&func);	  } +struct LLSelectMgrApplyPhysicsShapeType : public LLSelectedObjectFunctor +{ +	LLSelectMgrApplyPhysicsShapeType(U8 value) : mValue(value) {} +	U8 mValue; +	virtual bool apply(LLViewerObject* object) +	{ +		if ( object->permModify() ) 	// preemptive permissions check +		{ +			object->setPhysicsShapeType( mValue ); +			object->updateFlags(); +		} +		return true; +	} +}; + + +void LLSelectMgr::selectionUpdatePhysicsShapeType(U8 type) +{ +	llwarns << "physics shape type ->" << (U32)type << llendl; +	LLSelectMgrApplyPhysicsShapeType func(type); +	getSelection()->applyToObjects(&func);	 +}  //----------------------------------------------------------------------  // Helpful packing functions for sendObjectMessage() @@ -4620,7 +4642,6 @@ void LLSelectMgr::processForceObjectSelect(LLMessageSystem* msg, void**)  	LLSelectMgr::getInstance()->highlightObjectAndFamily(objects);  } -  extern LLGLdouble	gGLModelView[16];  void LLSelectMgr::updateSilhouettes() diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index d315f40ff3..544b1ff594 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -483,6 +483,7 @@ public:  	void selectionUpdatePhysics(BOOL use_physics);  	void selectionUpdateTemporary(BOOL is_temporary);  	void selectionUpdatePhantom(BOOL is_ghost); +	void selectionUpdatePhysicsShapeType(U8 type);  	void selectionUpdateCastShadows(BOOL cast_shadows);  	void selectionDump(); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index d6e9256fee..cf1e3bf186 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -1513,6 +1513,7 @@ void LLSpatialGroup::checkOcclusion()  {  	if (LLPipeline::sUseOcclusion > 1)  	{ +		LLFastTimer t(FTM_OCCLUSION_READBACK);  		LLSpatialGroup* parent = getParent();  		if (parent && parent->isOcclusionState(LLSpatialGroup::OCCLUDED))  		{	//if the parent has been marked as occluded, the child is implicitly occluded @@ -1520,7 +1521,6 @@ void LLSpatialGroup::checkOcclusion()  		}  		else if (isOcclusionState(QUERY_PENDING))  		{	//otherwise, if a query is pending, read it back -			LLFastTimer t(FTM_OCCLUSION_READBACK);  			GLuint res = 1;  			if (!isOcclusionState(DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID])  			{ @@ -3423,11 +3423,23 @@ LLCullResult::LLCullResult()  void LLCullResult::clear()  {  	mVisibleGroupsSize = 0; +	mVisibleGroupsEnd = mVisibleGroups.begin(); +  	mAlphaGroupsSize = 0; +	mAlphaGroupsEnd = mAlphaGroups.begin(); +  	mOcclusionGroupsSize = 0; +	mOcclusionGroupsEnd = mOcclusionGroups.begin(); +  	mDrawableGroupsSize = 0; +	mDrawableGroupsEnd = mDrawableGroups.begin(); +  	mVisibleListSize = 0; +	mVisibleListEnd = mVisibleList.begin(); +  	mVisibleBridgeSize = 0; +	mVisibleBridgeEnd = mVisibleBridge.begin(); +  	for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++)  	{ @@ -3436,6 +3448,7 @@ void LLCullResult::clear()  			mRenderMap[i][j] = 0;  		}  		mRenderMapSize[i] = 0; +		mRenderMapEnd[i] = mRenderMap[i].begin();  	}  } @@ -3446,7 +3459,7 @@ LLCullResult::sg_list_t::iterator LLCullResult::beginVisibleGroups()  LLCullResult::sg_list_t::iterator LLCullResult::endVisibleGroups()  { -	return mVisibleGroups.begin() + mVisibleGroupsSize; +	return mVisibleGroupsEnd;  }  LLCullResult::sg_list_t::iterator LLCullResult::beginAlphaGroups() @@ -3456,7 +3469,7 @@ LLCullResult::sg_list_t::iterator LLCullResult::beginAlphaGroups()  LLCullResult::sg_list_t::iterator LLCullResult::endAlphaGroups()  { -	return mAlphaGroups.begin() + mAlphaGroupsSize; +	return mAlphaGroupsEnd;  }  LLCullResult::sg_list_t::iterator LLCullResult::beginOcclusionGroups() @@ -3466,7 +3479,7 @@ LLCullResult::sg_list_t::iterator LLCullResult::beginOcclusionGroups()  LLCullResult::sg_list_t::iterator LLCullResult::endOcclusionGroups()  { -	return mOcclusionGroups.begin() + mOcclusionGroupsSize; +	return mOcclusionGroupsEnd;  }  LLCullResult::sg_list_t::iterator LLCullResult::beginDrawableGroups() @@ -3476,7 +3489,7 @@ LLCullResult::sg_list_t::iterator LLCullResult::beginDrawableGroups()  LLCullResult::sg_list_t::iterator LLCullResult::endDrawableGroups()  { -	return mDrawableGroups.begin() + mDrawableGroupsSize; +	return mDrawableGroupsEnd;  }  LLCullResult::drawable_list_t::iterator LLCullResult::beginVisibleList() @@ -3486,7 +3499,7 @@ LLCullResult::drawable_list_t::iterator LLCullResult::beginVisibleList()  LLCullResult::drawable_list_t::iterator LLCullResult::endVisibleList()  { -	return mVisibleList.begin() + mVisibleListSize; +	return mVisibleListEnd;  }  LLCullResult::bridge_list_t::iterator LLCullResult::beginVisibleBridge() @@ -3496,7 +3509,7 @@ LLCullResult::bridge_list_t::iterator LLCullResult::beginVisibleBridge()  LLCullResult::bridge_list_t::iterator LLCullResult::endVisibleBridge()  { -	return mVisibleBridge.begin() + mVisibleBridgeSize; +	return mVisibleBridgeEnd;  }  LLCullResult::drawinfo_list_t::iterator LLCullResult::beginRenderMap(U32 type) @@ -3506,7 +3519,7 @@ LLCullResult::drawinfo_list_t::iterator LLCullResult::beginRenderMap(U32 type)  LLCullResult::drawinfo_list_t::iterator LLCullResult::endRenderMap(U32 type)  { -	return mRenderMap[type].begin() + mRenderMapSize[type]; +	return mRenderMapEnd[type];  }  void LLCullResult::pushVisibleGroup(LLSpatialGroup* group) @@ -3520,6 +3533,7 @@ void LLCullResult::pushVisibleGroup(LLSpatialGroup* group)  		mVisibleGroups.push_back(group);  	}  	++mVisibleGroupsSize; +	mVisibleGroupsEnd = mVisibleGroups.begin()+mVisibleGroupsSize;  }  void LLCullResult::pushAlphaGroup(LLSpatialGroup* group) @@ -3533,6 +3547,7 @@ void LLCullResult::pushAlphaGroup(LLSpatialGroup* group)  		mAlphaGroups.push_back(group);  	}  	++mAlphaGroupsSize; +	mAlphaGroupsEnd = mAlphaGroups.begin()+mAlphaGroupsSize;  }  void LLCullResult::pushOcclusionGroup(LLSpatialGroup* group) @@ -3546,6 +3561,7 @@ void LLCullResult::pushOcclusionGroup(LLSpatialGroup* group)  		mOcclusionGroups.push_back(group);  	}  	++mOcclusionGroupsSize; +	mOcclusionGroupsEnd = mOcclusionGroups.begin()+mOcclusionGroupsSize;  }  void LLCullResult::pushDrawableGroup(LLSpatialGroup* group) @@ -3559,6 +3575,7 @@ void LLCullResult::pushDrawableGroup(LLSpatialGroup* group)  		mDrawableGroups.push_back(group);  	}  	++mDrawableGroupsSize; +	mDrawableGroupsEnd = mDrawableGroups.begin()+mDrawableGroupsSize;  }  void LLCullResult::pushDrawable(LLDrawable* drawable) @@ -3572,6 +3589,7 @@ void LLCullResult::pushDrawable(LLDrawable* drawable)  		mVisibleList.push_back(drawable);  	}  	++mVisibleListSize; +	mVisibleListEnd = mVisibleList.begin()+mVisibleListSize;  }  void LLCullResult::pushBridge(LLSpatialBridge* bridge) @@ -3585,6 +3603,7 @@ void LLCullResult::pushBridge(LLSpatialBridge* bridge)  		mVisibleBridge.push_back(bridge);  	}  	++mVisibleBridgeSize; +	mVisibleBridgeEnd = mVisibleBridge.begin()+mVisibleBridgeSize;  }  void LLCullResult::pushDrawInfo(U32 type, LLDrawInfo* draw_info) @@ -3598,6 +3617,7 @@ void LLCullResult::pushDrawInfo(U32 type, LLDrawInfo* draw_info)  		mRenderMap[type].push_back(draw_info);  	}  	++mRenderMapSize[type]; +	mRenderMapEnd[type] = mRenderMap[type].begin() + mRenderMapSize[type];  } diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 7896488379..2c09a25e04 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -346,11 +346,11 @@ public:  	F32 mBuilt;  	OctreeNode* mOctreeNode;  	LLSpatialPartition* mSpatialPartition; -	LLVector3 mBounds[2]; -	LLVector3 mExtents[2]; +	LLVector3 mBounds[2]; // bounding box (center, size) of this node and all its children (tight fit to objects) +	LLVector3 mExtents[2]; // extents (min, max) of this node and all its children -	LLVector3 mObjectExtents[2]; -	LLVector3 mObjectBounds[2]; +	LLVector3 mObjectExtents[2]; // extents (min, max) of objects in this node +	LLVector3 mObjectBounds[2]; // bounding box (center, size) of objects in this node  	LLPointer<LLVertexBuffer> mVertexBuffer;  	F32*					mOcclusionVerts; @@ -534,12 +534,19 @@ private:  	U32					mRenderMapSize[LLRenderPass::NUM_RENDER_TYPES];  	sg_list_t			mVisibleGroups; +	sg_list_t::iterator mVisibleGroupsEnd;  	sg_list_t			mAlphaGroups; +	sg_list_t::iterator mAlphaGroupsEnd;  	sg_list_t			mOcclusionGroups; +	sg_list_t::iterator	mOcclusionGroupsEnd;  	sg_list_t			mDrawableGroups; +	sg_list_t::iterator mDrawableGroupsEnd;  	drawable_list_t		mVisibleList; +	drawable_list_t::iterator mVisibleListEnd;  	bridge_list_t		mVisibleBridge; +	bridge_list_t::iterator mVisibleBridgeEnd;  	drawinfo_list_t		mRenderMap[LLRenderPass::NUM_RENDER_TYPES]; +	drawinfo_list_t::iterator mRenderMapEnd[LLRenderPass::NUM_RENDER_TYPES];  }; @@ -606,14 +613,15 @@ public:  //class for wrangling geometry out of volumes (implemented in LLVOVolume.cpp)  class LLVolumeGeometryManager: public LLGeometryManager  { -public: + public:  	virtual ~LLVolumeGeometryManager() { }  	virtual void rebuildGeom(LLSpatialGroup* group);  	virtual void rebuildMesh(LLSpatialGroup* group);  	virtual void getGeometry(LLSpatialGroup* group);  	void genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort = FALSE);  	void registerFace(LLSpatialGroup* group, LLFace* facep, U32 type); - + private: +	bool canRenderAsMask(LLFace* facep); // logic helper  };  //spatial partition that uses volume geometry manager (implemented in LLVOVolume.cpp) diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 874995a09e..3fa6b0c8c2 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -299,15 +299,6 @@ static bool handleWLSkyDetailChanged(const LLSD&)  	return true;  } -static bool handleRenderLightingDetailChanged(const LLSD& newvalue) -{ -	if (gPipeline.isInit()) -	{ -		gPipeline.setLightingDetail(newvalue.asInteger()); -	} -	return true; -} -  static bool handleResetVertexBuffersChanged(const LLSD&)  {  	if (gPipeline.isInit()) @@ -520,6 +511,7 @@ void settings_setup_listeners()  	gSavedSettings.getControl("RenderAvatarVP")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));  	gSavedSettings.getControl("VertexShaderEnable")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));  	gSavedSettings.getControl("RenderUIBuffer")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); +	gSavedSettings.getControl("RenderFSAASamples")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));  	gSavedSettings.getControl("RenderShadowResolutionScale")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));  	gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));  	gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); @@ -550,7 +542,8 @@ void settings_setup_listeners()  	gSavedSettings.getControl("RenderDebugPipeline")->getSignal()->connect(boost::bind(&handleRenderDebugPipelineChanged, _2));  	gSavedSettings.getControl("RenderResolutionDivisor")->getSignal()->connect(boost::bind(&handleRenderResolutionDivisorChanged, _2));  	gSavedSettings.getControl("RenderDeferred")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); -	gSavedSettings.getControl("RenderDeferredShadow")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); +	gSavedSettings.getControl("RenderShadowDetail")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); +	gSavedSettings.getControl("RenderDeferredSSAO")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));  	gSavedSettings.getControl("RenderDeferredGI")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));  	gSavedSettings.getControl("TextureMemory")->getSignal()->connect(boost::bind(&handleVideoMemoryChanged, _2));  	gSavedSettings.getControl("AuditTexture")->getSignal()->connect(boost::bind(&handleAuditTextureChanged, _2)); @@ -575,8 +568,8 @@ void settings_setup_listeners()  	gSavedSettings.getControl("MuteAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));  	gSavedSettings.getControl("MuteUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));  	gSavedSettings.getControl("RenderVBOEnable")->getSignal()->connect(boost::bind(&handleRenderUseVBOChanged, _2)); +	gSavedSettings.getControl("RenderUseStreamVBO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));  	gSavedSettings.getControl("WLSkyDetail")->getSignal()->connect(boost::bind(&handleWLSkyDetailChanged, _2)); -	gSavedSettings.getControl("RenderLightingDetail")->getSignal()->connect(boost::bind(&handleRenderLightingDetailChanged, _2));  	gSavedSettings.getControl("NumpadControl")->getSignal()->connect(boost::bind(&handleNumpadControlChanged, _2));  	gSavedSettings.getControl("JoystickAxis0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));  	gSavedSettings.getControl("JoystickAxis1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 823466e33e..8e2e2283bf 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -869,12 +869,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  			}  		} -		/// We copy the frame buffer straight into a texture here, -		/// and then display it again with compositor effects. -		/// Using render to texture would be faster/better, but I don't have a  -		/// grasp of their full display stack just yet. -		// gPostProcess->apply(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw()); -		  		if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)  		{  			gPipeline.renderDeferredLighting(); @@ -1117,7 +1111,7 @@ void render_ui(F32 zoom_factor, int subfield)  		{  			gPipeline.renderBloom(gSnapshot, zoom_factor, subfield);  		} - +		  		render_hud_elements();  		render_hud_attachments();  	} diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index c542459cdb..cb3f3c8edd 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3316,6 +3316,7 @@ const F32 THRESHOLD_HEAD_ROT_QDOT = 0.9997f;	// ~= 2.5 degrees -- if its less th  const F32 MAX_HEAD_ROT_QDOT = 0.99999f;			// ~= 0.5 degrees -- if its greater than this then no need to update head_rot  												// between these values we delay the updates (but no more than one second) +static LLFastTimer::DeclareTimer FTM_AGENT_UPDATE_SEND("Send Message");  void send_agent_update(BOOL force_send, BOOL send_reliable)  { @@ -3474,6 +3475,7 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)  	if (duplicate_count < DUP_MSGS && !gDisconnected)  	{ +		LLFastTimer t(FTM_AGENT_UPDATE_SEND);  		// Build the message  		msg->newMessageFast(_PREHASH_AgentUpdate);  		msg->nextBlockFast(_PREHASH_AgentData); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index bb7933c10e..620e270177 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -53,6 +53,7 @@  #include "llprimitive.h"  #include "llquantize.h"  #include "llregionhandle.h" +#include "llsdserialize.h"  #include "lltree_common.h"  #include "llxfermanager.h"  #include "message.h" @@ -199,6 +200,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe  	mGLName(0),  	mbCanSelect(TRUE),  	mFlags(0), +	mPhysicsShapeType(0),  	mDrawable(),  	mCreateSelected(FALSE),  	mRenderMedia(FALSE), @@ -4961,7 +4963,14 @@ void LLViewerObject::updateFlags()  	gMessageSystem->addBOOL("IsTemporary", flagTemporaryOnRez() );  	gMessageSystem->addBOOL("IsPhantom", flagPhantom() );  	gMessageSystem->addBOOL("CastsShadows", flagCastShadows() ); +	gMessageSystem->nextBlock("ExtraPhysics"); +	gMessageSystem->addU8("PhysicsShapeType", getPhysicsShapeType() );  	gMessageSystem->sendReliable( regionp->getHost() ); + +	if (getPhysicsShapeType() != 0) +	{ +		llwarns << "sent non default physics rep" << llendl; +	}  }  BOOL LLViewerObject::setFlags(U32 flags, BOOL state) @@ -4993,6 +5002,12 @@ BOOL LLViewerObject::setFlags(U32 flags, BOOL state)  	return setit;  } +void LLViewerObject::setPhysicsShapeType(U8 type) +{ +	mPhysicsShapeType = type; +	updateFlags(); +} +  void LLViewerObject::applyAngularVelocity(F32 dt)  {  	//do target omega here @@ -5204,3 +5219,48 @@ void LLViewerObject::resetChildrenPosition(const LLVector3& offset, BOOL simplif  	return ;  } +class ObjectPhysicsProperties : public LLHTTPNode +{ +public: +	virtual void post( +		ResponsePtr responder, +		const LLSD& context, +		const LLSD& input) const +	{ +		LLSD objectData = input["body"]["ObjectData"]; +		S32 numEntries = objectData.size(); +		 +		for ( S32 i = 0; i < numEntries; i++ ) +		{ +			LLSD& currObjectData = objectData[i]; +			U32 localID = currObjectData["LocalID"].asInteger(); + +			// Iterate through nodes at end, since it can be on both the regular AND hover list +			struct f : public LLSelectedNodeFunctor +			{ +				U32 mID; +				f(const U32& id) : mID(id) {} +				virtual bool apply(LLSelectNode* node) +				{ +					return (node->getObject() && node->getObject()->mLocalID == mID ); +				} +			} func(localID); + +			LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(&func); + +			if (node) +			{ +				// The LLSD message builder doesn't know how to handle U8, so we need to send as S8 and cast +				U8 physicsShapeType = (U8)currObjectData["PhysicsShapeType"].asInteger(); + +				node->getObject()->setPhysicsShapeType(physicsShapeType); +			}	 +		} +		 +		dialog_refresh_all(); +	}; +}; + +LLHTTPRegistration<ObjectPhysicsProperties> +	gHTTPRegistrationObjectPhysicsProperties("/message/ObjectPhysicsProperties"); + diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index be83fb7ef8..de7bfc0e07 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -459,6 +459,8 @@ public:  	inline BOOL		flagCameraDecoupled() const		{ return ((mFlags & FLAGS_CAMERA_DECOUPLED) != 0); }  	inline BOOL		flagObjectMove() const			{ return ((mFlags & FLAGS_OBJECT_MOVE) != 0); } +	inline U8       getPhysicsShapeType() const     { return mPhysicsShapeType; } +	  	bool getIncludeInSearch() const;  	void setIncludeInSearch(bool include_in_search); @@ -474,6 +476,7 @@ public:  	void updateFlags();  	BOOL setFlags(U32 flag, BOOL state); +	void setPhysicsShapeType(U8 type);  	virtual void dump() const;  	static U32		getNumZombieObjects()			{ return sNumZombieObjects; } @@ -553,6 +556,9 @@ public:  	// Grabbed from UPDATE_FLAGS  	U32				mFlags; +	// Sent to sim in UPDATE_FLAGS, received in ObjectPhysicsProperties +	U8              mPhysicsShapeType; +  	// Pipeline classes  	LLPointer<LLDrawable> mDrawable; diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 86b1a8c910..a0d0b9d490 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -317,10 +317,16 @@ S32 LLViewerShaderMgr::getVertexShaderLevel(S32 type)  void LLViewerShaderMgr::setShaders()  { -	if (!gPipeline.mInitialized || !sInitialized) +	//setShaders might be called redundantly by gSavedSettings, so return on reentrance +	static bool reentrance = false; +	 +	if (!gPipeline.mInitialized || !sInitialized || reentrance)  	{  		return;  	} + +	reentrance = true; +  	// Make sure the compiled shader map is cleared before we recompile shaders.  	mShaderObjects.clear(); @@ -368,17 +374,10 @@ void LLViewerShaderMgr::setShaders()  		S32 wl_class = 2;  		S32 water_class = 2;  		S32 deferred_class = 0; -		if (!(LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders") -			  && gSavedSettings.getBOOL("WindLightUseAtmosShaders"))) -		{ -			// user has disabled WindLight in their settings, downgrade -			// windlight shaders to stub versions. -			wl_class = 1; -		} - -		if (LLPipeline::sRenderDeferred) +		 +		if (gSavedSettings.getBOOL("RenderDeferred"))  		{ -			if (gSavedSettings.getBOOL("RenderDeferredShadow")) +			if (gSavedSettings.getS32("RenderShadowDetail") > 0)  			{  				if (gSavedSettings.getBOOL("RenderDeferredGI"))  				{ //shadows + gi @@ -393,6 +392,24 @@ void LLViewerShaderMgr::setShaders()  			{ //no shadows  				deferred_class = 1;  			} + +			//make sure framebuffer objects are enabled +			gSavedSettings.setBOOL("RenderUseFBO", TRUE); + +			//make sure hardware skinning is enabled +			gSavedSettings.setBOOL("RenderAvatarVP", TRUE); +			 +			//make sure atmospheric shaders are enabled +			gSavedSettings.setBOOL("WindLightUseAtmosShaders", TRUE); +		} + + +		if (!(LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders") +			  && gSavedSettings.getBOOL("WindLightUseAtmosShaders"))) +		{ +			// user has disabled WindLight in their settings, downgrade +			// windlight shaders to stub versions. +			wl_class = 1;  		}  		if(!gSavedSettings.getBOOL("EnableRippleWater")) @@ -517,6 +534,8 @@ void LLViewerShaderMgr::setShaders()  		gViewerWindow->setCursor(UI_CURSOR_ARROW);  	}  	gPipeline.createGLBuffers(); + +	reentrance = false;  }  void LLViewerShaderMgr::unloadShaders() @@ -973,10 +992,21 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{ +		std::string fragment; + +		if (gSavedSettings.getBOOL("RenderDeferredSSAO")) +		{ +			fragment = "deferred/sunLightSSAOF.glsl"; +		} +		else +		{ +			fragment = "deferred/sunLightF.glsl"; +		} +  		gDeferredSunProgram.mName = "Deferred Sun Shader";  		gDeferredSunProgram.mShaderFiles.clear();  		gDeferredSunProgram.mShaderFiles.push_back(make_pair("deferred/sunLightV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredSunProgram.mShaderFiles.push_back(make_pair("deferred/sunLightF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredSunProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));  		gDeferredSunProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredSunProgram.createShader(NULL, NULL);  	} diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index b7c265be59..b0c4b6fc8a 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -592,7 +592,7 @@ void update_statistics(U32 frame_count)  		}  	}  	LLViewerStats::getInstance()->setStat(LLViewerStats::ST_ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable")); -	LLViewerStats::getInstance()->setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gSavedSettings.getS32("RenderLightingDetail")); +	LLViewerStats::getInstance()->setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gPipeline.getLightingDetail());  	LLViewerStats::getInstance()->setStat(LLViewerStats::ST_DRAW_DIST, (F64)gSavedSettings.getF32("RenderFarClip"));  	LLViewerStats::getInstance()->setStat(LLViewerStats::ST_CHAT_BUBBLES, (F64)gSavedSettings.getBOOL("UseChatBubbles"));  #if 0 // 1.9.2 diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index a96a6bf1b3..0fc38e8561 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1377,7 +1377,7 @@ LLViewerWindow::LLViewerWindow(  		gSavedSettings.getBOOL("DisableVerticalSync"),  		!gNoRender,  		ignore_pixel_depth, -		gSavedSettings.getU32("RenderFSAASamples")); +		0); //gSavedSettings.getU32("RenderFSAASamples"));  	if (!LLAppViewer::instance()->restoreErrorTrap())  	{ @@ -3835,140 +3835,6 @@ void LLViewerWindow::playSnapshotAnimAndSound()  BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type)  {  	return rawSnapshot(raw, preview_width, preview_height, FALSE, FALSE, show_ui, do_rebuild, type); -	 -	// *TODO below code was broken in deferred pipeline -	/* -	if ((!raw) || preview_width < 10 || preview_height < 10) -	{ -		return FALSE; -	} - -	if(gResizeScreenTexture) //the window is resizing -	{ -		return FALSE ; -	} - -	setCursor(UI_CURSOR_WAIT); - -	// Hide all the UI widgets first and draw a frame -	BOOL prev_draw_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI); - -	if ( prev_draw_ui != show_ui) -	{ -		LLPipeline::toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI); -	} - -	BOOL hide_hud = !gSavedSettings.getBOOL("RenderHUDInSnapshot") && LLPipeline::sShowHUDAttachments; -	if (hide_hud) -	{ -		LLPipeline::sShowHUDAttachments = FALSE; -	} - -	S32 render_name = gSavedSettings.getS32("RenderName"); -	gSavedSettings.setS32("RenderName", 0); -	LLVOAvatar::updateFreezeCounter(1) ; //pause avatar updating for one frame -	 -	S32 w = preview_width ; -	S32 h = preview_height ; -	LLVector2 display_scale = mDisplayScale ; -	mDisplayScale.setVec((F32)w / mWindowRectRaw.getWidth(), (F32)h / mWindowRectRaw.getHeight()) ; -	LLRect window_rect = mWindowRectRaw; -	mWindowRectRaw.set(0, h, w, 0); -	 -	gDisplaySwapBuffers = FALSE; -	gDepthDirty = TRUE; -	glClearColor(0.f, 0.f, 0.f, 0.f); -	glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); -	setup3DRender(); - -	LLFontGL::setFontDisplay(FALSE) ; -	LLHUDText::setDisplayText(FALSE) ; -	if (type == SNAPSHOT_TYPE_OBJECT_ID) -	{ -		gObjectList.renderPickList(gViewerWindow->getWindowRectScaled(), FALSE, FALSE); -	} -	else -	{ -		display(do_rebuild, 1.0f, 0, TRUE); -		render_ui(); -	} - -	S32 glformat, gltype, glpixel_length ; -	if(SNAPSHOT_TYPE_DEPTH == type) -	{ -		glpixel_length = 4 ; -		glformat = GL_DEPTH_COMPONENT ;  -		gltype = GL_FLOAT ; -	} -	else -	{ -		glpixel_length = 3 ; -		glformat = GL_RGB ; -		gltype = GL_UNSIGNED_BYTE ; -	} - -	raw->resize(w, h, glpixel_length); -	glReadPixels(0, 0, w, h, glformat, gltype, raw->getData()); - -	if(SNAPSHOT_TYPE_DEPTH == type) -	{ -		LLViewerCamera* camerap = LLViewerCamera::getInstance(); -		F32 depth_conversion_factor_1 = (camerap->getFar() + camerap->getNear()) / (2.f * camerap->getFar() * camerap->getNear()); -		F32 depth_conversion_factor_2 = (camerap->getFar() - camerap->getNear()) / (2.f * camerap->getFar() * camerap->getNear()); - -		//calculate the depth  -		for (S32 y = 0 ; y < h ; y++) -		{ -			for(S32 x = 0 ; x < w ; x++) -			{ -				S32 i = (w * y + x) << 2 ; -				 -				F32 depth_float_i = *(F32*)(raw->getData() + i); -				 -				F32 linear_depth_float = 1.f / (depth_conversion_factor_1 - (depth_float_i * depth_conversion_factor_2)); -				U8 depth_byte = F32_to_U8(linear_depth_float, camerap->getNear(), camerap->getFar()); -				*(raw->getData() + i + 0) = depth_byte; -				*(raw->getData() + i + 1) = depth_byte; -				*(raw->getData() + i + 2) = depth_byte; -				*(raw->getData() + i + 3) = 255; -			} -		}		 -	} - -	LLFontGL::setFontDisplay(TRUE) ; -	LLHUDText::setDisplayText(TRUE) ; -	mDisplayScale.setVec(display_scale) ; -	mWindowRectRaw = window_rect;	 -	setup3DRender(); -	gDisplaySwapBuffers = FALSE; -	gDepthDirty = TRUE; - -	// POST SNAPSHOT -	if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) -	{ -		LLPipeline::toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI); -	} - -	if (hide_hud) -	{ -		LLPipeline::sShowHUDAttachments = TRUE; -	} - -	setCursor(UI_CURSOR_ARROW); - -	if (do_rebuild) -	{ -		// If we had to do a rebuild, that means that the lists of drawables to be rendered -		// was empty before we started. -		// Need to reset these, otherwise we call state sort on it again when render gets called the next time -		// and we stand a good chance of crashing on rebuild because the render drawable arrays have multiple copies of -		// objects on them. -		gPipeline.resetDrawOrders(); -	} -	 -	gSavedSettings.setS32("RenderName", render_name);	 -	 -	return TRUE;*/  }  // Saves the image from the screen to the specified filename and path. @@ -4728,8 +4594,9 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size,  		return TRUE;  	} -	U32 fsaa = gSavedSettings.getU32("RenderFSAASamples"); -	U32 old_fsaa = mWindow->getFSAASamples(); +	//U32 fsaa = gSavedSettings.getU32("RenderFSAASamples"); +	//U32 old_fsaa = mWindow->getFSAASamples(); +  	// going from windowed to windowed  	if (!old_fullscreen && !fullscreen)  	{ @@ -4739,7 +4606,7 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size,  			mWindow->setSize(size);  		} -		if (fsaa == old_fsaa) +		//if (fsaa == old_fsaa)  		{  			return TRUE;  		} @@ -4768,13 +4635,13 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size,  		gSavedSettings.setS32("WindowY", old_pos.mY);  	} -	mWindow->setFSAASamples(fsaa); +	//mWindow->setFSAASamples(fsaa);  	result_first_try = mWindow->switchContext(fullscreen, size, disable_vsync);  	if (!result_first_try)  	{  		// try to switch back -		mWindow->setFSAASamples(old_fsaa); +		//mWindow->setFSAASamples(old_fsaa);  		result_second_try = mWindow->switchContext(old_fullscreen, old_size, disable_vsync);  		if (!result_second_try) diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 6b052b8e99..49c0c4d4e0 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2451,6 +2451,17 @@ void LLVOVolume::updateSpotLightPriority()  } +bool LLVOVolume::isLightSpotlight() const +{ +	LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); +	if (params) +	{ +		return params->isLightSpotlight(); +	} +	return false; +} + +  LLViewerTexture* LLVOVolume::getLightTexture()  {  	LLUUID id = getLightTextureID(); @@ -3188,11 +3199,10 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  	S32 idx = draw_vec.size()-1; -  	BOOL fullbright = (type == LLRenderPass::PASS_FULLBRIGHT) || -					  (type == LLRenderPass::PASS_INVISIBLE) || -					  (type == LLRenderPass::PASS_ALPHA ? facep->isState(LLFace::FULLBRIGHT) : FALSE); - +		(type == LLRenderPass::PASS_INVISIBLE) || +		(type == LLRenderPass::PASS_ALPHA && facep->isState(LLFace::FULLBRIGHT)); +	  	if (!fullbright && type != LLRenderPass::PASS_GLOW && !facep->mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL))  	{  		llwarns << "Non fullbright face has no normals!" << llendl; @@ -3221,12 +3231,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  	LLViewerTexture* tex = facep->getTexture(); -	U8 glow = 0; -		 -	if (type == LLRenderPass::PASS_GLOW) -	{ -		glow = (U8) (facep->getTextureEntry()->getGlow() * 255); -	} +	U8 glow = (U8) (facep->getTextureEntry()->getGlow() * 255);  	if (facep->mVertexBuffer.isNull())  	{ @@ -3291,9 +3296,22 @@ void LLVolumeGeometryManager::getGeometry(LLSpatialGroup* group)  static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_VB("Volume");  static LLFastTimer::DeclareTimer FTM_REBUILD_VBO("VBO Rebuilt"); +bool LLVolumeGeometryManager::canRenderAsMask(LLFace* facep) +{ +	const LLTextureEntry* te = facep->getTextureEntry(); +	return ( +		LLPipeline::sFastAlpha && // do we want masks at all? + +		(te->getColor().mV[3] == 1.0f) && // can't treat as mask if we have face alpha +		!(LLPipeline::sRenderDeferred && te->getFullbright()) && // hack: alpha masking renders fullbright faces invisible in deferred rendering mode, need to figure out why - for now, avoid +		(te->getGlow() == 0.f) && // glowing masks are hard to implement - don't mask + +		facep->getTexture()->getIsAlphaMask() // texture actually qualifies for masking (lazily calculated but expensive) +		); +} +  void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  { -	llpushcallstacks ;  	if (group->changeLOD())  	{  		group->mLastUpdateDistance = group->mDistance; @@ -3417,10 +3435,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  				if (type == LLDrawPool::POOL_ALPHA)  				{ -					if (LLPipeline::sFastAlpha && -					    (te->getColor().mV[VW] == 1.0f) && -					    (!te->getFullbright()) && // hack: alpha masking renders fullbright faces invisible, need to figure out why - for now, avoid -					    facep->getTexture()->getIsAlphaMask()) +					if (canRenderAsMask(facep))  					{ //can be treated as alpha mask  						simple_faces.push_back(facep);  					} @@ -3522,9 +3537,10 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  }  static LLFastTimer::DeclareTimer FTM_VOLUME_GEOM("Volume Geometry"); +static LLFastTimer::DeclareTimer FTM_VOLUME_GEOM_PARTIAL("Terse Rebuild"); +  void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)  { -	llpushcallstacks ;  	llassert(group);  	if (group && group->isState(LLSpatialGroup::MESH_DIRTY) && !group->isState(LLSpatialGroup::GEOM_DIRTY))  	{ @@ -3535,6 +3551,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)  		for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)  		{ +			LLFastTimer t(FTM_VOLUME_GEOM_PARTIAL);  			LLDrawable* drawablep = *drawable_iter;  			if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) ) @@ -3616,7 +3633,6 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)  void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort)  { -	llpushcallstacks ;  	//calculate maximum number of vertices to store in a single buffer  	U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcStride(group->mSpatialPartition->mVertexDataMask);  	max_vertices = llmin(max_vertices, (U32) 65535); @@ -3763,15 +3779,12 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  			const LLTextureEntry* te = facep->getTextureEntry(); -			BOOL is_alpha = facep->getPoolType() == LLDrawPool::POOL_ALPHA ? TRUE : FALSE; +			BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) ? TRUE : FALSE;  			if (is_alpha)  			{  				// can we safely treat this as an alpha mask? -				if (LLPipeline::sFastAlpha && -				    (te->getColor().mV[VW] == 1.0f) && -				    (!te->getFullbright()) && // hack: alpha masking renders fullbright faces invisible, need to figure out why - for now, avoid -				    facep->getTexture()->getIsAlphaMask()) +				if (canRenderAsMask(facep))  				{  					if (te->getFullbright())  					{ @@ -3839,7 +3852,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  				}  				else  				{ -					if (LLPipeline::sRenderDeferred && te->getBumpmap()) +					if (LLPipeline::sRenderDeferred && LLPipeline::sRenderBump && te->getBumpmap())  					{  						registerFace(group, facep, LLRenderPass::PASS_BUMP);  					} @@ -3867,7 +3880,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  				}  			} -			if (LLPipeline::sRenderGlow && te->getGlow() > 0.f) +			if (!is_alpha && LLPipeline::sRenderGlow && te->getGlow() > 0.f)  			{  				registerFace(group, facep, LLRenderPass::PASS_GLOW);  			} diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index a8bb597f93..fbae011ffc 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -215,6 +215,7 @@ public:  	LLColor3 getLightBaseColor() const; // not scaled by intensity  	LLColor3 getLightColor() const; // scaled by intensity  	LLUUID	getLightTextureID() const; +	bool isLightSpotlight() const;  	LLVector3 getSpotLightParams() const;  	void	updateSpotLightPriority();  	F32		getSpotLightPriority() const; diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 0b63f5efbd..c7148f8826 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -1028,9 +1028,11 @@ void LLWorld::disconnectRegions()  	}  } +static LLFastTimer::DeclareTimer FTM_ENABLE_SIMULATOR("Enable Sim");  void process_enable_simulator(LLMessageSystem *msg, void **user_data)  { +	LLFastTimer t(FTM_ENABLE_SIMULATOR);  	// enable the appropriate circuit for this simulator and   	// add its values into the gSimulator structure  	U64		handle; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 4ca251af3e..efb99061ab 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -361,6 +361,7 @@ void LLPipeline::init()  	sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD");  	sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");  	sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips"); +	LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO");  	sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights");  	sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles"); @@ -407,6 +408,8 @@ void LLPipeline::init()  	{  		mSpotLightFade[i] = 1.f;  	} + +	setLightingDetail(-1);  }  LLPipeline::~LLPipeline() @@ -509,6 +512,7 @@ void LLPipeline::destroyGL()  }  static LLFastTimer::DeclareTimer FTM_RESIZE_SCREEN_TEXTURE("Resize Screen Texture"); +  void LLPipeline::resizeScreenTexture()  {  	LLFastTimer ft(FTM_RESIZE_SCREEN_TEXTURE); @@ -902,13 +906,18 @@ S32 LLPipeline::setLightingDetail(S32 level)  	if (level < 0)  	{ -		level = gSavedSettings.getS32("RenderLightingDetail"); +		if (gSavedSettings.getBOOL("VertexShaderEnable")) +		{ +			level = 1; +		} +		else +		{ +			level = 0; +		}  	}  	level = llclamp(level, 0, getMaxLightingDetail());  	if (level != mLightingDetail)  	{ -		gSavedSettings.setS32("RenderLightingDetail", level); -		  		mLightingDetail = level;  		if (mVertexShadersLoaded == 1) @@ -1799,7 +1808,6 @@ void LLPipeline::rebuildPriorityGroups()  void LLPipeline::rebuildGroups()  { -	llpushcallstacks ;  	// Iterate through some drawables on the non-priority build queue  	S32 size = (S32) mGroupQ2.size();  	S32 min_count = llclamp((S32) ((F32) (size * size)/4096*0.25f), 1, size); @@ -1947,6 +1955,7 @@ void LLPipeline::updateGeom(F32 max_dtime)  void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera)  {  	LLMemType mt(LLMemType::MTYPE_PIPELINE_MARK_VISIBLE); +  	if(!drawablep || drawablep->isDead())  	{  		return; @@ -3404,26 +3413,14 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)  	gGLLastMatrix = NULL;  	glLoadMatrixd(gGLModelView); -	renderHighlights(); -	mHighlightFaces.clear(); - -	renderDebug(); - -	LLVertexBuffer::unbind(); - -	if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) -	{ -		// Render debugging beacons. -		gObjectList.renderObjectBeacons(); -		gObjectList.resetObjectBeacons(); -	} -  	if (occlude)  	{  		occlude = FALSE;  		gGLLastMatrix = NULL;  		glLoadMatrixd(gGLModelView);  		doOcclusion(camera); +		gGLLastMatrix = NULL; +		glLoadMatrixd(gGLModelView);  	}  } @@ -4267,7 +4264,7 @@ void LLPipeline::setupAvatarLights(BOOL for_edit)  		glLightf (GL_LIGHT1, GL_LINEAR_ATTENUATION, 	 0.0f);  		glLightf (GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.0f);  		glLightf (GL_LIGHT1, GL_SPOT_EXPONENT, 		 0.0f); -		glLightf (GL_LIGHT1, GL_SPOT_CUTOFF, 			 180.0f); +		glLightf (GL_LIGHT1, GL_SPOT_CUTOFF,		 180.0f);  	}  	else if (gAvatarBacklight) // Always true (unless overridden in a devs .ini)  	{ @@ -4555,32 +4552,41 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)  			LLVector4 light_pos_gl(light_pos, 1.0f);  			F32 light_radius = llmax(light->getLightRadius(), 0.001f); -			F32 atten, quad; -#if 0 //1.9.1 -			if (pool->getVertexShaderLevel() > 0) -			{ -				atten = light_radius; -				quad = llmax(light->getLightFalloff(), 0.0001f); -			} -			else -#endif -			{ -				F32 x = (3.f * (1.f + light->getLightFalloff())); -				atten = x / (light_radius); // % of brightness at radius -				quad = 0.0f; -			} +			F32 x = (3.f * (1.f + light->getLightFalloff())); // why this magic?  probably trying to match a historic behavior. +			float linatten = x / (light_radius); // % of brightness at radius +  			mHWLightColors[cur_light] = light_color;  			S32 gllight = GL_LIGHT0+cur_light;  			glLightfv(gllight, GL_POSITION, light_pos_gl.mV);  			glLightfv(gllight, GL_DIFFUSE,  light_color.mV);  			glLightfv(gllight, GL_AMBIENT,  LLColor4::black.mV); -			glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV);  			glLightf (gllight, GL_CONSTANT_ATTENUATION,   0.0f); -			glLightf (gllight, GL_LINEAR_ATTENUATION,     atten); -			glLightf (gllight, GL_QUADRATIC_ATTENUATION,  quad); -			glLightf (gllight, GL_SPOT_EXPONENT,          0.0f); -			glLightf (gllight, GL_SPOT_CUTOFF,            180.0f); +			glLightf (gllight, GL_LINEAR_ATTENUATION,     linatten); +			glLightf (gllight, GL_QUADRATIC_ATTENUATION,  0.0f); +			if (light->isLightSpotlight()) // directional (spot-)light +			{ +				LLVector3 spotparams = light->getSpotLightParams(); +				LLQuaternion quat = light->getRenderRotation(); +				LLVector3 at_axis(0,0,-1); // this matches deferred rendering's object light direction +				at_axis *= quat; +				//llinfos << "SPOT!!!!!!! fov: " << spotparams.mV[0] << " focus: " << spotparams.mV[1] << " dir: " << at_axis << llendl; +				glLightfv(gllight, GL_SPOT_DIRECTION, at_axis.mV); +				glLightf (gllight, GL_SPOT_EXPONENT,  2.0f); // 2.0 = good old dot product ^ 2 +				glLightf (gllight, GL_SPOT_CUTOFF,    90.0f); // hemisphere +				const float specular[] = {0.f, 0.f, 0.f, 0.f}; +				glLightfv(gllight, GL_SPECULAR, specular); +			} +			else // omnidirectional (point) light +			{ +				glLightf (gllight, GL_SPOT_EXPONENT, 0.0f); +				glLightf (gllight, GL_SPOT_CUTOFF,   180.0f); + +				// we use specular.w = 1.0 as a cheap hack for the shaders to know that this is omnidirectional rather than a spotlight +				const float specular[] = {0.f, 0.f, 0.f, 1.f}; +				glLightfv(gllight, GL_SPECULAR, specular); +				//llinfos << "boring light" << llendl; +			}  			cur_light++;  			if (cur_light >= 8)  			{ @@ -4607,13 +4613,10 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)  		LLVector4 light_pos_gl(light_pos, 1.0f);  		F32 light_radius = 16.f; -		F32 atten, quad; -		{ -			F32 x = 3.f; -			atten = x / (light_radius); // % of brightness at radius -			quad = 0.0f; -		} +		F32 x = 3.f; +		float linatten = x / (light_radius); // % of brightness at radius +  		mHWLightColors[2] = light_color;  		S32 gllight = GL_LIGHT2;  		glLightfv(gllight, GL_POSITION, light_pos_gl.mV); @@ -4621,8 +4624,8 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)  		glLightfv(gllight, GL_AMBIENT,  LLColor4::black.mV);  		glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV);  		glLightf (gllight, GL_CONSTANT_ATTENUATION,   0.0f); -		glLightf (gllight, GL_LINEAR_ATTENUATION,     atten); -		glLightf (gllight, GL_QUADRATIC_ATTENUATION,  quad); +		glLightf (gllight, GL_LINEAR_ATTENUATION,     linatten); +		glLightf (gllight, GL_QUADRATIC_ATTENUATION,  0.0f);  		glLightf (gllight, GL_SPOT_EXPONENT,          0.0f);  		glLightf (gllight, GL_SPOT_CUTOFF,            180.0f);  	} @@ -4743,16 +4746,16 @@ void LLPipeline::enableLightsFullbright(const LLColor4& color)  	enableLights(mask);  	glLightModelfv(GL_LIGHT_MODEL_AMBIENT,color.mV); -	if (mLightingDetail >= 2) +	/*if (mLightingDetail >= 2)  	{  		glColor4f(0.f, 0.f, 0.f, 1.f); // no local lighting by default -	} +	}*/  }  void LLPipeline::disableLights()  {  	enableLights(0); // no lighting (full bright) -	glColor4f(1.f, 1.f, 1.f, 1.f); // lighting color = white by default +	//glColor4f(1.f, 1.f, 1.f, 1.f); // lighting color = white by default  }  //============================================================================ @@ -5355,6 +5358,7 @@ void LLPipeline::resetVertexBuffers()  {  	sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");  	sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips"); +	LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO");  	for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();   			iter != LLWorld::getInstance()->getRegionList().end(); ++iter) @@ -5490,6 +5494,7 @@ void LLPipeline::bindScreenToTexture()  }  static LLFastTimer::DeclareTimer FTM_RENDER_BLOOM("Bloom"); +  void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  {  	LLMemType mt_ru(LLMemType::MTYPE_PIPELINE_RENDER_BLOOM); @@ -5812,6 +5817,12 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  		gGL.getTexUnit(0)->activate();  		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); + +		if (LLRenderTarget::sUseFBO) +		{ //copy depth buffer from mScreen to framebuffer +			LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(),  +				0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); +		}  	} @@ -6169,7 +6180,6 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen  	shader.uniform2f("screen_res", mDeferredScreen.getWidth(), mDeferredScreen.getHeight());  	shader.uniform1f("near_clip", LLViewerCamera::getInstance()->getNear()*2.f); -	shader.uniform1f("alpha_soften", gSavedSettings.getF32("RenderDeferredAlphaSoften"));  	shader.uniform1f ("shadow_offset", gSavedSettings.getF32("RenderShadowOffset"));  	shader.uniform1f("shadow_bias", gSavedSettings.getF32("RenderShadowBias"));  	shader.uniform1f("lum_scale", gSavedSettings.getF32("RenderLuminanceScale")); @@ -6265,16 +6275,16 @@ void LLPipeline::renderDeferredLighting()  			glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], 0);  		} -		if (gSavedSettings.getBOOL("RenderDeferredShadow")) -		{ -			glPushMatrix(); -			glLoadIdentity(); -			glMatrixMode(GL_PROJECTION); -			glPushMatrix(); -			glLoadIdentity(); +		glPushMatrix(); +		glLoadIdentity(); +		glMatrixMode(GL_PROJECTION); +		glPushMatrix(); +		glLoadIdentity(); -			mDeferredLight[0].bindTarget(); -			if (gSavedSettings.getBOOL("RenderDeferredSun")) +		mDeferredLight[0].bindTarget(); + +		if (gSavedSettings.getBOOL("RenderDeferredSSAO") || gSavedSettings.getS32("RenderShadowDetail") > 0) +		{  			{ //paint shadow/SSAO light map (direct lighting lightmap)  				LLFastTimer ftm(FTM_SUN_SHADOW);  				bindDeferredShader(gDeferredSunProgram, 0); @@ -6315,18 +6325,22 @@ void LLPipeline::renderDeferredLighting()  				unbindDeferredShader(gDeferredSunProgram);  			} -			else -			{ -				mDeferredLight[0].clear(GL_COLOR_BUFFER_BIT); -			} +		} +		else +		{ +			glClearColor(1,1,1,1); +			mDeferredLight[0].clear(GL_COLOR_BUFFER_BIT); +			glClearColor(0,0,0,0); +		} -			mDeferredLight[0].flush(); +		mDeferredLight[0].flush(); +		{ //global illumination specific block (still experimental)  			if (gSavedSettings.getBOOL("RenderDeferredBlurLight") && -			    gSavedSettings.getBOOL("RenderDeferredGI")) -			{ +				gSavedSettings.getBOOL("RenderDeferredGI")) +			{   				LLFastTimer ftm(FTM_EDGE_DETECTION); -				//get edge map +				//generate edge map  				LLGLDisable blend(GL_BLEND);  				LLGLDisable test(GL_ALPHA_TEST);  				LLGLDepthTest depth(GL_FALSE); @@ -6423,79 +6437,79 @@ void LLPipeline::renderDeferredLighting()  					unbindDeferredShader(gDeferredPostGIProgram);  				}  			} +		} -			if (gSavedSettings.getBOOL("RenderDeferredBlurLight")) -			{ //soften direct lighting lightmap -				LLFastTimer ftm(FTM_SOFTEN_SHADOW); -				//blur lightmap -				mDeferredLight[1].bindTarget(); +		if (gSavedSettings.getBOOL("RenderDeferredSSAO")) +		{ //soften direct lighting lightmap +			LLFastTimer ftm(FTM_SOFTEN_SHADOW); +			//blur lightmap +			mDeferredLight[1].bindTarget(); -				glClearColor(1,1,1,1); -				mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT); -				glClearColor(0,0,0,0); -				 -				bindDeferredShader(gDeferredBlurLightProgram); +			glClearColor(1,1,1,1); +			mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT); +			glClearColor(0,0,0,0); +			 +			bindDeferredShader(gDeferredBlurLightProgram); -				LLVector3 go = gSavedSettings.getVector3("RenderShadowGaussian"); -				const U32 kern_length = 4; -				F32 blur_size = gSavedSettings.getF32("RenderShadowBlurSize"); -				F32 dist_factor = gSavedSettings.getF32("RenderShadowBlurDistFactor"); +			LLVector3 go = gSavedSettings.getVector3("RenderShadowGaussian"); +			const U32 kern_length = 4; +			F32 blur_size = gSavedSettings.getF32("RenderShadowBlurSize"); +			F32 dist_factor = gSavedSettings.getF32("RenderShadowBlurDistFactor"); -				// sample symmetrically with the middle sample falling exactly on 0.0 -				F32 x = 0.f; +			// sample symmetrically with the middle sample falling exactly on 0.0 +			F32 x = 0.f; -				LLVector3 gauss[32]; // xweight, yweight, offset +			LLVector3 gauss[32]; // xweight, yweight, offset -				for (U32 i = 0; i < kern_length; i++) -				{ -					gauss[i].mV[0] = llgaussian(x, go.mV[0]); -					gauss[i].mV[1] = llgaussian(x, go.mV[1]); -					gauss[i].mV[2] = x; -					x += 1.f; -				} +			for (U32 i = 0; i < kern_length; i++) +			{ +				gauss[i].mV[0] = llgaussian(x, go.mV[0]); +				gauss[i].mV[1] = llgaussian(x, go.mV[1]); +				gauss[i].mV[2] = x; +				x += 1.f; +			} -				gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f); -				gDeferredBlurLightProgram.uniform1f("dist_factor", dist_factor); -				gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); -				gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); -				gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); +			gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f); +			gDeferredBlurLightProgram.uniform1f("dist_factor", dist_factor); +			gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); +			gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); +			gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); +		 +			{ +				LLGLDisable blend(GL_BLEND); +				LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); +				stop_glerror(); +				glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); +				stop_glerror(); +			} -				{ -					LLGLDisable blend(GL_BLEND); -					LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); -					stop_glerror(); -					glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); -					stop_glerror(); -				} -				 -				mDeferredLight[1].flush(); -				unbindDeferredShader(gDeferredBlurLightProgram); +			mDeferredLight[1].flush(); +			unbindDeferredShader(gDeferredBlurLightProgram); -				bindDeferredShader(gDeferredBlurLightProgram, 1); -				mDeferredLight[0].bindTarget(); +			bindDeferredShader(gDeferredBlurLightProgram, 1); +			mDeferredLight[0].bindTarget(); -				gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f); +			gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f); -				{ -					LLGLDisable blend(GL_BLEND); -					LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); -					stop_glerror(); -					glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); -					stop_glerror(); -				} -				mDeferredLight[0].flush(); -				unbindDeferredShader(gDeferredBlurLightProgram); +			{ +				LLGLDisable blend(GL_BLEND); +				LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); +				stop_glerror(); +				glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); +				stop_glerror();  			} - -			stop_glerror(); -			glPopMatrix(); -			stop_glerror(); -			glMatrixMode(GL_MODELVIEW); -			stop_glerror(); -			glPopMatrix(); -			stop_glerror(); +			mDeferredLight[0].flush(); +			unbindDeferredShader(gDeferredBlurLightProgram);  		} +		stop_glerror(); +		glPopMatrix(); +		stop_glerror(); +		glMatrixMode(GL_MODELVIEW); +		stop_glerror(); +		glPopMatrix(); +		stop_glerror(); +  		//copy depth and stencil from deferred screen  		//mScreen.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(),  		//					0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); @@ -6647,7 +6661,7 @@ void LLPipeline::renderDeferredLighting()  					{ //draw box if camera is outside box  						if (render_local)  						{ -							if (volume->getLightTexture()) +							if (volume->isLightSpotlight())  							{  								drawablep->getVOVolume()->updateSpotLightPriority();  								spot_lights.push_back(drawablep); @@ -6664,7 +6678,7 @@ void LLPipeline::renderDeferredLighting()  					}  					else if (render_fullscreen)  					{	 -						if (volume->getLightTexture()) +						if (volume->isLightSpotlight())  						{  							drawablep->getVOVolume()->updateSpotLightPriority();  							fullscreen_spot_lights.push_back(drawablep); @@ -6890,6 +6904,24 @@ void LLPipeline::renderDeferredLighting()  		mRenderTypeMask = render_mask;  	} +	{ +		//render highlights, etc. +		renderHighlights(); +		mHighlightFaces.clear(); + +		renderDebug(); + +		LLVertexBuffer::unbind(); + +		if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) +		{ +			// Render debugging beacons. +			gObjectList.renderObjectBeacons(); +			LLHUDObject::renderAll(); +			gObjectList.resetObjectBeacons(); +		} +	} +  	mScreen.flush();  } @@ -7217,17 +7249,16 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  									  (1<<LLPipeline::RENDER_TYPE_SKY) |  									  (1<<LLPipeline::RENDER_TYPE_CLOUDS));	 -				if (gSavedSettings.getBOOL("RenderWaterReflections")) +				S32 detail = gSavedSettings.getS32("RenderReflectionDetail"); +				if (detail > 0)  				{ //mask out selected geometry based on reflection detail - -					S32 detail = gSavedSettings.getS32("RenderReflectionDetail"); -					if (detail < 3) +					if (detail < 4)  					{  						mRenderTypeMask &= ~(1 << LLPipeline::RENDER_TYPE_PARTICLES); -						if (detail < 2) +						if (detail < 3)  						{  							mRenderTypeMask &= ~(1 << LLPipeline::RENDER_TYPE_AVATAR); -							if (detail < 1) +							if (detail < 2)  							{  								mRenderTypeMask &= ~(1 << LLPipeline::RENDER_TYPE_VOLUME);  							} @@ -7247,7 +7278,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  			if (LLDrawPoolWater::sNeedsDistortionUpdate)  			{  				mRenderTypeMask = ref_mask; -				if (gSavedSettings.getBOOL("RenderWaterReflections")) +				if (gSavedSettings.getS32("RenderReflectionDetail") > 0)  				{  					gPipeline.grabReferences(ref_result);  					LLGLUserClipPlane clip_plane(plane, mat, projection); @@ -7885,30 +7916,11 @@ void LLPipeline::generateHighlight(LLCamera& camera)  void LLPipeline::generateSunShadow(LLCamera& camera)  { -	if (!sRenderDeferred || !gSavedSettings.getBOOL("RenderDeferredShadow")) +	if (!sRenderDeferred || gSavedSettings.getS32("RenderShadowDetail") <= 0)  	{  		return;  	} -	//temporary hack to disable shadows but keep local lights -	static BOOL clear = TRUE; -	BOOL gen_shadow = gSavedSettings.getBOOL("RenderDeferredSunShadow"); -	if (!gen_shadow) -	{ -		if (clear) -		{ -			clear = FALSE; -			for (U32 i = 0; i < 6; i++) -			{ -				mShadow[i].bindTarget(); -				mShadow[i].clear(); -				mShadow[i].flush(); -			} -		} -		return; -	} -	clear = TRUE; -  	F64 last_modelview[16];  	F64 last_projection[16];  	for (U32 i = 0; i < 16; i++) @@ -8424,135 +8436,155 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  		}  	} -	 - -	F32 fade_amt = gFrameIntervalSeconds * llmax(LLViewerCamera::getInstance()->getVelocityStat()->getCurrentPerSec(), 1.f); -	//update shadow targets -	for (U32 i = 0; i < 2; i++) -	{ //for each current shadow -		LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW4+i; +	//hack to disable projector shadows  +	static bool clear = true; +	bool gen_shadow = gSavedSettings.getS32("RenderShadowDetail") > 1; +	 +	if (gen_shadow) +	{ +		clear = true; +		F32 fade_amt = gFrameIntervalSeconds * llmax(LLViewerCamera::getInstance()->getVelocityStat()->getCurrentPerSec(), 1.f); -		if (mShadowSpotLight[i].notNull() &&  -			(mShadowSpotLight[i] == mTargetShadowSpotLight[0] || -			mShadowSpotLight[i] == mTargetShadowSpotLight[1])) -		{ //keep this spotlight -			mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f); -		} -		else -		{ //fade out this light -			mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f); -			 -			if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull()) -			{ //faded out, grab one of the pending spots (whichever one isn't already taken) -				if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2]) -				{ -					mShadowSpotLight[i] = mTargetShadowSpotLight[0]; -				} -				else -				{ -					mShadowSpotLight[i] = mTargetShadowSpotLight[1]; +		//update shadow targets +		for (U32 i = 0; i < 2; i++) +		{ //for each current shadow +			LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW4+i; + +			if (mShadowSpotLight[i].notNull() &&  +				(mShadowSpotLight[i] == mTargetShadowSpotLight[0] || +				mShadowSpotLight[i] == mTargetShadowSpotLight[1])) +			{ //keep this spotlight +				mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f); +			} +			else +			{ //fade out this light +				mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f); +				 +				if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull()) +				{ //faded out, grab one of the pending spots (whichever one isn't already taken) +					if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2]) +					{ +						mShadowSpotLight[i] = mTargetShadowSpotLight[0]; +					} +					else +					{ +						mShadowSpotLight[i] = mTargetShadowSpotLight[1]; +					}  				}  			}  		} -	} - -	for (S32 i = 0; i < 2; i++) -	{ -		glh_set_current_modelview(saved_view); -		glh_set_current_projection(saved_proj); - -		if (mShadowSpotLight[i].isNull()) +		 +		for (S32 i = 0; i < 2; i++)  		{ -			continue; -		} +			glh_set_current_modelview(saved_view); +			glh_set_current_projection(saved_proj); -		LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume(); +			if (mShadowSpotLight[i].isNull()) +			{ +				continue; +			} -		if (!volume) -		{ -			mShadowSpotLight[i] = NULL; -			continue; -		} +			LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume(); -		LLDrawable* drawable = mShadowSpotLight[i]; +			if (!volume) +			{ +				mShadowSpotLight[i] = NULL; +				continue; +			} -		LLVector3 params = volume->getSpotLightParams(); -		F32 fov = params.mV[0]; +			LLDrawable* drawable = mShadowSpotLight[i]; -		//get agent->light space matrix (modelview) -		LLVector3 center = drawable->getPositionAgent(); -		LLQuaternion quat = volume->getRenderRotation(); +			LLVector3 params = volume->getSpotLightParams(); +			F32 fov = params.mV[0]; -		//get near clip plane -		LLVector3 scale = volume->getScale(); -		LLVector3 at_axis(0,0,-scale.mV[2]*0.5f); -		at_axis *= quat; +			//get agent->light space matrix (modelview) +			LLVector3 center = drawable->getPositionAgent(); +			LLQuaternion quat = volume->getRenderRotation(); -		LLVector3 np = center+at_axis; -		at_axis.normVec(); +			//get near clip plane +			LLVector3 scale = volume->getScale(); +			LLVector3 at_axis(0,0,-scale.mV[2]*0.5f); +			at_axis *= quat; -		//get origin that has given fov for plane np, at_axis, and given scale -		F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f); +			LLVector3 np = center+at_axis; +			at_axis.normVec(); -		LLVector3 origin = np - at_axis*dist; +			//get origin that has given fov for plane np, at_axis, and given scale +			F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f); -		LLMatrix4 mat(quat, LLVector4(origin, 1.f)); +			LLVector3 origin = np - at_axis*dist; -		view[i+4] = glh::matrix4f((F32*) mat.mMatrix); +			LLMatrix4 mat(quat, LLVector4(origin, 1.f)); -		view[i+4] = view[i+4].inverse(); +			view[i+4] = glh::matrix4f((F32*) mat.mMatrix); -		//get perspective matrix -		F32 near_clip = dist+0.01f; -		F32 width = scale.mV[VX]; -		F32 height = scale.mV[VY]; -		F32 far_clip = dist+volume->getLightRadius()*1.5f; +			view[i+4] = view[i+4].inverse(); -		F32 fovy = fov * RAD_TO_DEG; -		F32 aspect = width/height; -		 -		proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip); +			//get perspective matrix +			F32 near_clip = dist+0.01f; +			F32 width = scale.mV[VX]; +			F32 height = scale.mV[VY]; +			F32 far_clip = dist+volume->getLightRadius()*1.5f; -		//translate and scale to from [-1, 1] to [0, 1] -		glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, -						0.f, 0.5f, 0.f, 0.5f, -						0.f, 0.f, 0.5f, 0.5f, -						0.f, 0.f, 0.f, 1.f); +			F32 fovy = fov * RAD_TO_DEG; +			F32 aspect = width/height; +			 +			proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip); -		glh_set_current_modelview(view[i+4]); -		glh_set_current_projection(proj[i+4]); +			//translate and scale to from [-1, 1] to [0, 1] +			glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, +							0.f, 0.5f, 0.f, 0.5f, +							0.f, 0.f, 0.5f, 0.5f, +							0.f, 0.f, 0.f, 1.f); -		mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view; -		 -		for (U32 j = 0; j < 16; j++) -		{ -			gGLLastModelView[j] = mShadowModelview[i+4].m[j]; -			gGLLastProjection[j] = mShadowProjection[i+4].m[j]; -		} +			glh_set_current_modelview(view[i+4]); +			glh_set_current_projection(proj[i+4]); -		mShadowModelview[i+4] = view[i+4]; -		mShadowProjection[i+4] = proj[i+4]; +			mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view; +			 +			for (U32 j = 0; j < 16; j++) +			{ +				gGLLastModelView[j] = mShadowModelview[i+4].m[j]; +				gGLLastProjection[j] = mShadowProjection[i+4].m[j]; +			} -		LLCamera shadow_cam = camera; -		shadow_cam.setFar(far_clip); -		shadow_cam.setOrigin(origin); +			mShadowModelview[i+4] = view[i+4]; +			mShadowProjection[i+4] = proj[i+4]; -		LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); +			LLCamera shadow_cam = camera; +			shadow_cam.setFar(far_clip); +			shadow_cam.setOrigin(origin); -		stop_glerror(); +			LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); + +			stop_glerror(); -		mShadow[i+4].bindTarget(); -		mShadow[i+4].getViewport(gGLViewport); +			mShadow[i+4].bindTarget(); +			mShadow[i+4].getViewport(gGLViewport); -		static LLCullResult result[2]; +			static LLCullResult result[2]; -		LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+i+4; +			LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+i+4; -		renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE); +			renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE); -		mShadow[i+4].flush(); - 	} +			mShadow[i+4].flush(); + 		} +	} +	else +	{ +		if (clear) +		{ +			clear = false; +			for (U32 i = 4; i < 6; i++) +			{ +				mShadow[i].bindTarget(); +				mShadow[i].clear(); +				mShadow[i].flush(); +			} +		} +	}  	if (!gSavedSettings.getBOOL("CameraOffset"))  	{ diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index cc9e72cfb5..f5054cf206 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -1418,6 +1418,39 @@ even though the user gets a free copy.               text_enabled_color="1 1 1 1"               top_pad="3"               width="87" /> +            <text +             type="string" +             length="1" +             follows="left|top" +             height="10" +             layout="topleft" +             left_delta="0" +             name="label physicsshapetype" +             top_pad="10" +             width="121"> +                Physics Shape Type: +            </text> +			<combo_box +			   height="23" +			   layout="topleft" +			   follows="left|top" +			   name="Physics Shape Type Combo Ctrl" +			   tool_tip="Choose the physics shape type" +			   left_pad="0" +			   width="108"> +			  <combo_box.item +				 label="Prim" +				 name="Prim" +				 value="Prim" /> +			  <combo_box.item +				 label="None" +				 name="None" +				 value="None" /> +			  <combo_box.item +				 label="Convex Hull" +				 name="Convex Hull" +				 value="Convex Hull" /> +			</combo_box>   <!--           <text               type="string" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml index 44c44f5f59..9e48f11de5 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml @@ -155,12 +155,12 @@  	 visiblity_control="ShowAdvancedGraphicsSettings"       border="false"  	 follows="top|left" -     height="260" +     height="283"       label="CustomGraphics"       layout="topleft"       left="5"       name="CustomGraphics Panel" -     top="124" +     top="101"       width="485">  		<text  		type="string" @@ -211,119 +211,111 @@  			<check_box.commit_callback  			function="Pref.VertexShaderEnable" />  		</check_box> -		<check_box -		control_name="RenderWaterReflections" +    <check_box +		control_name="RenderDeferred"  		height="16"  		initial_value="true" -		label="Water reflections" +		label="Lighting and Shadows"  		layout="topleft"  		left_delta="0" -		name="Reflections" +		name="UseLightShaders"  		top_pad="1"  		width="256"> -			<check_box.commit_callback +      <check_box.commit_callback  			function="Pref.VertexShaderEnable" /> -		</check_box> -		<text -		type="string" -		length="1" -		follows="left|top" -		height="12" -		layout="topleft" -		left_delta="0" -		name="ReflectionDetailText" -		top_pad="7" -		width="128"> -			Reflection detail: -		</text> -		<radio_group -		control_name="RenderReflectionDetail" -		draw_border="false" -		height="70" -		layout="topleft" -		left_delta="-2" -		name="ReflectionDetailRadio" -		top_pad="3" -		width="321"> -			<radio_item -			height="16" -			label="Terrain and trees" -			layout="topleft" -			left="3" -			name="0" -			top="3" -			width="315" /> -			<radio_item -			height="16" -			label="All static objects" -			layout="topleft" -			left_delta="0" -			name="1" -			top_delta="16" -			width="315" /> -			<radio_item -			height="16" -			label="All avatars and objects" -			layout="topleft" -			left_delta="0" -			name="2" -			top_delta="16" -			width="315" /> -			<radio_item -			height="16" -			label="Everything" -			layout="topleft" -			left_delta="0" -			name="3" -			top_delta="16" -			width="315" /> -		</radio_group> -		<text -		type="string" -		length="1" -		follows="left|top" -		height="12" -		layout="topleft" -		left_delta="2" -		name="AvatarRenderingText" -		top_pad="5" -		width="128"> -			Avatar rendering: -		</text> -		<check_box -		control_name="RenderUseImpostors" -		height="16" -		initial_value="true" -		label="Avatar impostors" -		layout="topleft" -		left_delta="0" -		name="AvatarImpostors" -		top_pad="7" -		width="256" /> -		<check_box -		control_name="RenderAvatarVP" +    </check_box> +    <check_box +		control_name="RenderDeferredSSAO"  		height="16"  		initial_value="true" -		label="Hardware skinning" +		label="Ambient Occlusion"  		layout="topleft"  		left_delta="0" -		name="AvatarVertexProgram" +		name="UseSSAO"  		top_pad="1"  		width="256"> -			<check_box.commit_callback +      <check_box.commit_callback  			function="Pref.VertexShaderEnable" /> -		</check_box> -		<check_box -		control_name="RenderAvatarCloth" -		height="16" -		initial_value="true" -		label="Avatar cloth" -		layout="topleft" -		left_delta="0" -		name="AvatarCloth" -		top_pad="1" -		width="256" /> +    </check_box> +     <text +    type="string" +    length="1" +    top_pad="8" +    follows="top|left" +    height="23" +    width="110" +    word_wrap="true" +    layout="topleft" +    left="10" +    name="shadows_label"> +        Shadows: +      </text> +      <combo_box +      control_name="RenderShadowDetail" +      height="23" +      layout="topleft" +      left="10" +      top_pad="0"  +      name="ShadowDetail" +      width="150"> +        <combo_box.item +        label="None" +        name="0" +        value="0"/> +        <combo_box.item +        label="Sun/Moon" +        name="1" +        value="1"/> +        <combo_box.item +        label="Sun/Moon + Projectors" +        name="2" +        value="2"/> +      </combo_box> + +      <text +  type="string" +  length="1" +  top_pad="8" +  follows="top|left" +  height="23" +  width="110" +  word_wrap="true" +  layout="topleft" +  left="10" +  name="reflection_label"> +        Water Reflections: +      </text> +      <combo_box +      control_name="RenderReflectionDetail" +      height="23" +      layout="topleft" +      left_="10" +      top_pad ="0" +      name="Reflections" +      width="150"> +        <combo_box.item +        label="Minimal" +        name="0" +        value="0"/> +        <combo_box.item +        label="Terrain and trees" +        name="1" +        value="1"/> +        <combo_box.item +        label="All static objects" +        name="2" +        value="2"/> +        <combo_box.item +        label="All avatars and objects" +        name="3" +        value="3"/> +        <combo_box.item +        label="Everything" +        name="4" +        value="4"/> +      </combo_box> +      		<slider  		control_name="RenderFarClip"  		decimal_digits="0" @@ -522,7 +514,7 @@          layout="topleft"          left="444"          name="PostProcessText" -        top="305" +        top="328"          width="128">             Low          </text> @@ -599,46 +591,51 @@          width="128">             Low          </text> -        <text -        type="string" -        length="1" -        follows="left|top" -        height="12" -        layout="topleft" -        left_delta="-230" -        name="LightingDetailText" -        top_pad="8" -        width="140"> -           Lighting detail: -        </text> -        <radio_group -        control_name="RenderLightingDetail" -        draw_border="false" -        height="38" -        layout="topleft" -        left_delta="0" -        name="LightingDetailRadio" -        top_pad="5" -        width="321"> -           <radio_item -            height="16" -            label="Sun and moon only" -            layout="topleft" -            left="3" -            name="SunMoon" -            value="0" -            top="3" -            width="156" /> -           <radio_item -            height="16" -            label="Nearby local lights" -            layout="topleft" -            left_delta="0" -            name="LocalLights" -            value="1" -            top_delta="16" -            width="156" /> -        </radio_group> +      <text +      type="string" +      length="1" +      follows="left|top" +      height="12" +      layout="topleft" +      left_delta="-230" +      name="AvatarRenderingText" +      top_pad="8" +      width="128"> +        Avatar rendering: +      </text> +      <check_box +      control_name="RenderUseImpostors" +      height="16" +      initial_value="true" +      label="Avatar impostors" +      layout="topleft" +      left_delta="0" +      name="AvatarImpostors" +      top_pad="7" +      width="256" /> +      <check_box +      control_name="RenderAvatarVP" +      height="16" +      initial_value="true" +      label="Hardware skinning" +      layout="topleft" +      left_delta="0" +      name="AvatarVertexProgram" +      top_pad="1" +      width="256"> +        <check_box.commit_callback +        function="Pref.VertexShaderEnable" /> +      </check_box> +      <check_box +      control_name="RenderAvatarCloth" +      height="16" +      initial_value="true" +      label="Avatar cloth" +      layout="topleft" +      left_delta="0" +      name="AvatarCloth" +      top_pad="1" +      width="256" />          <text          type="string"          length="1" @@ -647,7 +644,7 @@          layout="topleft"          left="358"          name="TerrainDetailText" -        top="465" +        top="488"          width="155">             Terrain detail:          </text> @@ -676,7 +673,7 @@              name="2"              top_delta="16"              width="315" /> -        </radio_group> +        </radio_group> -->  	</panel>          <button | 
