diff options
Diffstat (limited to 'indra')
79 files changed, 5068 insertions, 3399 deletions
diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp index 231077c217..fb7f5e5c1c 100644 --- a/indra/llinventory/llsettingssky.cpp +++ b/indra/llinventory/llsettingssky.cpp @@ -999,7 +999,6 @@ LLColor3 LLSettingsSky::getLightDiffuse() const  LLColor3 LLSettingsSky::getAmbientColor() const  { -    // Todo: this causes complications, preferably to get rid of this duality      if (mSettings.has(SETTING_LEGACY_HAZE) && mSettings[SETTING_LEGACY_HAZE].has(SETTING_AMBIENT))      {          return LLColor3(mSettings[SETTING_LEGACY_HAZE][SETTING_AMBIENT]); diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 15a018a0bb..4dae61e185 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -84,6 +84,7 @@ LLShaderFeatures::LLShaderFeatures()      , isDeferred(false)      , hasIndirect(false)      , hasShadows(false) +    , hasAmbientOcclusion(false)      , mIndexedTextureChannels(0)      , disableTextureIndex(false)      , hasAlphaMask(false) diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index ed13106bfd..56d322fe6c 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -49,6 +49,7 @@ public:  	bool hasAtmospherics;  	bool hasGamma;      bool hasShadows; +    bool hasAmbientOcclusion;  	bool hasSrgb;      bool encodesNormal;      bool decodesNormal; diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 3a80ff0144..29d120a135 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -196,8 +196,8 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)  		}  	} -#if USE_DEFERRED_SHADER_API -    if (features->isDeferred || features->hasShadows) +    // we want this BEFORE shadows and AO because those facilities use pos/norm access +    if (features->isDeferred || features->hasShadows || features->hasAmbientOcclusion)  	{  		if (!shader->attachObject("deferred/deferredUtil.glsl"))  		{ @@ -205,6 +205,22 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)  		}  	} +    if (features->hasShadows) +	{ +		if (!shader->attachObject("deferred/shadowUtil.glsl")) +		{ +			return FALSE; +		} +	} + +    if (features->hasAmbientOcclusion) +	{ +		if (!shader->attachObject("deferred/aoUtil.glsl")) +		{ +			return FALSE; +		} +	} +      if (features->hasIndirect)  	{  		if (!shader->attachObject("deferred/indirect.glsl")) @@ -212,7 +228,6 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)  			return FALSE;  		}  	} -#endif  	if (features->hasGamma)  	{ diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 94ce4f6df7..bb5ff19176 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -8995,6 +8995,17 @@        <key>Value</key>        <integer>0</integer>      </map> +  <key>RenderDebugSH</key> +    <map> +      <key>Comment</key> +      <string>Enable SH indirect lighting visualization.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>    <key>RenderMaxTextureIndex</key>    <map>      <key>Comment</key> @@ -11959,6 +11970,21 @@        <key>Value</key>        <real>0.300000011921</real>      </map> +    <key>SkyMoonDefaultPosition</key> +    <map> +      <key>Comment</key> +      <string>Default position of sun in sky (direction in world coordinates)</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Vector3</string> +      <key>Value</key> +      <array> +        <real>-1.0</real> +        <real>0.0</real> +        <real>-0.1</real> +      </array> +    </map>      <key>SkyNightColorShift</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 07b0f2a98a..33e61f2062 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl @@ -84,11 +84,8 @@ uniform vec3 light_diffuse[8];  vec4 applyWaterFogView(vec3 pos, vec4 color);  #endif -vec3 srgb_to_linear(vec3 cs); -vec3 linear_to_srgb(vec3 cl);  vec2 encode_normal (vec3 n);  vec3 decode_normal (vec2 enc); -  vec3 scaleSoftClip(vec3 l);  vec3 atmosFragAmbient(vec3 light, vec3 sunlit);  vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten); @@ -97,46 +94,46 @@ void calcFragAtmospherics(vec3 inPositionEye, float ambFactor, out vec3 sunlit,  vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)  { -	//get light vector -	vec3 lv = lp.xyz-v; -	 -	//get distance -	float d = length(lv); -	 -	float da = 1.0; - -	vec3 col = vec3(0); - -	if (d > 0.0 && la > 0.0 && fa > 0.0) -	{ -		//normalize light vector -		lv = normalize(lv); -	 -		//distance attenuation -		float dist = d/la; -		float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0); -		dist_atten *= dist_atten; -		dist_atten *= 2.0; - -		// spotlight coefficient. -		float spot = max(dot(-ln, lv), is_pointlight); -		da *= spot*spot; // GL_SPOT_EXPONENT=2 - -		//angular attenuation -		da *= max(dot(n, lv), 0.0);		 - -		float lit = max(da * dist_atten,0.0); - -		col = light_col * lit * diffuse; - -		// no spec for alpha shader... -	} - -	return max(col, vec3(0.0,0.0,0.0)); +    //get light vector +    vec3 lv = lp.xyz-v; +     +    //get distance +    float d = length(lv); +     +    float da = 1.0; + +    vec3 col = vec3(0); + +    if (d > 0.0 && la > 0.0 && fa > 0.0) +    { +        //normalize light vector +        lv = normalize(lv); +     +        //distance attenuation +        float dist = d/la; +        float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0); +        dist_atten *= dist_atten; +        dist_atten *= 2.0; + +        // spotlight coefficient. +        float spot = max(dot(-ln, lv), is_pointlight); +        da *= spot*spot; // GL_SPOT_EXPONENT=2 + +        //angular attenuation +        da *= max(dot(n, lv), 0.0);      + +        float lit = max(da * dist_atten,0.0); + +        col = light_col * lit * diffuse; + +        // no spec for alpha shader... +    } + +    return max(col, vec3(0.0,0.0,0.0));  }  #if HAS_SHADOW -float pcfShadow(sampler2DShadow shadowMap, vec4 stc) +float pcfShadowLegacy(sampler2DShadow shadowMap, vec4 stc)  {  	stc.xyz /= stc.w;  	stc.z += shadow_bias; @@ -155,186 +152,175 @@ float pcfShadow(sampler2DShadow shadowMap, vec4 stc)  }  #endif +float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float bias_scale, vec2 pos_screen);  void main()   { -	vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; -	frag *= screen_res; -	 -	vec4 pos = vec4(vary_position, 1.0); -	 -	float shadow = 1.0; +    vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; +    frag *= screen_res; +     +    vec4 pos = vec4(vary_position, 1.0); +    vec3 norm = vary_norm; -#if HAS_SHADOW -	vec4 spos = pos; -		 -	if (spos.z > -shadow_clip.w) -	{	 -		shadow = 0.0; - -		vec4 lpos; -		 -		vec4 near_split = shadow_clip*-0.75; -		vec4 far_split = shadow_clip*-1.25; -		vec4 transition_domain = near_split-far_split; -		float weight = 0.0; - -		if (spos.z < near_split.z) -		{ -			lpos = shadow_matrix[3]*spos; -			 -			float w = 1.0; -			w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; -			shadow += pcfShadow(shadowMap3, lpos)*w; -			weight += w; -			shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); -		} - -		if (spos.z < near_split.y && spos.z > far_split.z) -		{ -			lpos = shadow_matrix[2]*spos; -			 -			float w = 1.0; -			w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; -			w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; -			shadow += pcfShadow(shadowMap2, lpos)*w; -			weight += w; -		} - -		if (spos.z < near_split.x && spos.z > far_split.y) -		{ -			lpos = shadow_matrix[1]*spos; -			 -			float w = 1.0; -			w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; -			w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; -			shadow += pcfShadow(shadowMap1, lpos)*w; -			weight += w; -		} - -		if (spos.z > far_split.x) -		{ -			lpos = shadow_matrix[0]*spos; -							 -			float w = 1.0; -			w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; -				 -			shadow += pcfShadow(shadowMap0, lpos)*w; -			weight += w; -		} -		 +    float shadow = 1.0; -		shadow /= weight; -	} -	else -	{ -		shadow = 1.0; -	} +#if HAS_SHADOW +    vec4 spos = pos; +         +    if (spos.z > -shadow_clip.w) +    {    +        shadow = 0.0; + +        vec4 lpos; +         +        vec4 near_split = shadow_clip*-0.75; +        vec4 far_split = shadow_clip*-1.25; +        vec4 transition_domain = near_split-far_split; +        float weight = 0.0; + +        if (spos.z < near_split.z) +        { +            lpos = shadow_matrix[3]*spos; +             +            float w = 1.0; +            w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; +            shadow += pcfShadowLegacy(shadowMap3, lpos)*w; +            weight += w; +            shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); +        } + +        if (spos.z < near_split.y && spos.z > far_split.z) +        { +            lpos = shadow_matrix[2]*spos; +             +            float w = 1.0; +            w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; +            w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; +            shadow += pcfShadowLegacy(shadowMap2, lpos)*w; +            weight += w; +        } + +        if (spos.z < near_split.x && spos.z > far_split.y) +        { +            lpos = shadow_matrix[1]*spos; +             +            float w = 1.0; +            w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; +            w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; +            shadow += pcfShadowLegacy(shadowMap1, lpos)*w; +            weight += w; +        } + +        if (spos.z > far_split.x) +        { +            lpos = shadow_matrix[0]*spos; +                             +            float w = 1.0; +            w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; +                 +            shadow += pcfShadowLegacy(shadowMap0, lpos)*w; +            weight += w; +        } +         + +        shadow /= weight; +    } +    else +    { +        shadow = 1.0; +    }  #endif  #ifdef USE_INDEXED_TEX -	vec4 diff = diffuseLookup(vary_texcoord0.xy); +    vec4 diff = diffuseLookup(vary_texcoord0.xy);  #else -	vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy); +    vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy);  #endif  #ifdef FOR_IMPOSTOR -	vec4 color; -	color.rgb = diff.rgb; -	color.a = 1.0; +    vec4 color; +    color.rgb = diff.rgb; +    color.a = 1.0;  #ifdef USE_VERTEX_COLOR -	float final_alpha = diff.a * vertex_color.a; -	diff.rgb *= vertex_color.rgb; +    float final_alpha = diff.a * vertex_color.a; +    diff.rgb *= vertex_color.rgb;  #else -	float final_alpha = diff.a; +    float final_alpha = diff.a;  #endif -	 -	// Insure we don't pollute depth with invis pixels in impostor rendering -	// -	if (final_alpha < 0.01) -	{ -		discard; -	} +     +    // Insure we don't pollute depth with invis pixels in impostor rendering +    // +    if (final_alpha < 0.01) +    { +        discard; +    }  #else -	 +      #ifdef USE_VERTEX_COLOR -	float final_alpha = diff.a * vertex_color.a; -	diff.rgb *= vertex_color.rgb; +    float final_alpha = diff.a * vertex_color.a; +    diff.rgb *= vertex_color.rgb;  #else -	float final_alpha = diff.a; +    float final_alpha = diff.a;  #endif +    vec3 sunlit; +    vec3 amblit; +    vec3 additive; +    vec3 atten; +    calcFragAtmospherics(pos.xyz, 1.0, sunlit, amblit, additive, atten); -	vec4 gamma_diff = diff;	 -	diff.rgb = srgb_to_linear(diff.rgb); +    vec2 abnormal   = encode_normal(norm.xyz); +         norm.xyz   = decode_normal(abnormal.xy); -	vec3 norm = vary_norm;  - -        vec3 sunlit; -        vec3 amblit; -        vec3 additive; -        vec3 atten; - -	calcFragAtmospherics(pos.xyz, 1.0, sunlit, amblit, additive, atten); - -	vec2 abnormal	= encode_normal(norm.xyz); -		 norm.xyz   = decode_normal(abnormal.xy); - -	float sun_da  = dot(norm.xyz, sun_dir.xyz); -	float moon_da = dot(norm.xyz, moon_dir.xyz); +    float sun_da  = dot(norm.xyz, sun_dir.xyz); +    float moon_da = dot(norm.xyz, moon_dir.xyz);      float final_da = max(sun_da, moon_da);            final_da = min(final_da, shadow);            final_da = clamp(final_da, 0.0f, 1.0f); -	  final_da = pow(final_da, 1.0/1.3); +      final_da = pow(final_da, display_gamma); -	vec4 color = vec4(0,0,0,0); +    vec4 color = vec4(0,0,0,0); -	color.rgb = atmosFragAmbient(color.rgb, amblit); -	color.a   = final_alpha; +    color.rgb = atmosFragAmbient(color.rgb, amblit); +    color.a   = final_alpha; -	float ambient = abs(final_da); -	ambient *= 0.5; -	ambient *= ambient; -	ambient = (1.0-ambient); +    float ambient = abs(final_da); +    ambient *= 0.5; +    ambient *= ambient; +    ambient = (1.0-ambient); -	color.rgb *= ambient; -	color.rgb += atmosFragAffectDirectionalLight(final_da, sunlit); -	color.rgb *= gamma_diff.rgb; +    color.rgb *= ambient; +    color.rgb += (final_da * sunlit); +    color.rgb *= diff.rgb; -	//color.rgb = mix(diff.rgb, color.rgb, final_alpha); -	 -	color.rgb = atmosFragLighting(color.rgb, additive, atten); -	color.rgb = scaleSoftClip(color.rgb); +    //color.rgb = mix(diff.rgb, color.rgb, final_alpha); +     +    color.rgb = atmosFragLighting(color.rgb, additive, atten); +    color.rgb = scaleSoftClip(color.rgb); -	vec4 light = vec4(0,0,0,0); +    vec4 light = vec4(0,0,0,0); -	color.rgb = srgb_to_linear(color.rgb); -	     #define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, diff.rgb, pos.xyz, norm, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z); -	LIGHT_LOOP(1) -	LIGHT_LOOP(2) -	LIGHT_LOOP(3) -	LIGHT_LOOP(4) -	LIGHT_LOOP(5) -	LIGHT_LOOP(6) -	LIGHT_LOOP(7) - -	// keep it linear -	// -	color.rgb += light.rgb; +    LIGHT_LOOP(1) +    LIGHT_LOOP(2) +    LIGHT_LOOP(3) +    LIGHT_LOOP(4) +    LIGHT_LOOP(5) +    LIGHT_LOOP(6) +    LIGHT_LOOP(7) -	// straight to display gamma, we're post-deferred -	// -	color.rgb = linear_to_srgb(color.rgb); +    // keep it linear +    // +    color.rgb += light.rgb;  #ifdef WATER_FOG -	color = applyWaterFogView(pos.xyz, color); +    color = applyWaterFogView(pos.xyz, color);  #endif  #endif -	frag_color = color; +    frag_color = color;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/aoUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/aoUtil.glsl new file mode 100644 index 0000000000..3bb59dd7f9 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/aoUtil.glsl @@ -0,0 +1,93 @@ +/**  + * @file class1/deferred/aoUtil.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +uniform sampler2D       noiseMap; + +uniform float ssao_radius; +uniform float ssao_max_radius; +uniform float ssao_factor; +uniform float ssao_factor_inv; + +vec4 getPosition(vec2 pos_screen); + +vec2 getKern(int i) +{ +    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; +        +    return kern[i]; +} + +//calculate decreases in ambient lighting when crowded out (SSAO) +float calcAmbientOcclusion(vec4 pos, vec3 norm, vec2 pos_screen) +{ +    float ret = 1.0; +    vec3 pos_world = pos.xyz; +    vec2 noise_reflect = texture2D(noiseMap, pos_screen.xy/128.0).xy; +         +    float angle_hidden = 0.0; +    float 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(getKern(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) +         +        float funky_val = (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) ? 1.0 : 0.0; +        angle_hidden = angle_hidden + funky_val * min(1.0/dist2, ssao_factor_inv); +             +        // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion"  +        float diffz_val = (diff.z > -1.0) ? 1.0 : 0.0; +        points = points + diffz_val; +    } +         +    angle_hidden = min(ssao_factor*angle_hidden/points, 1.0); +     +    float points_val = (points > 0.0) ? 1.0 : 0.0; +    ret = (1.0 - (points_val * angle_hidden)); + +    ret = max(ret, 0.0); +    return min(ret, 1.0); +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl index b56abb66d1..868eec3926 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl @@ -48,82 +48,69 @@ VARYING vec2 vary_fragcoord;  uniform mat4 inv_proj;  uniform vec2 screen_res; -vec4 getPosition(vec2 pos_screen) -{ -	float depth = texture2DRect(depthMap, pos_screen.xy).r; -	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; -} - +vec4 getPosition(vec2 pos_screen); +vec3 getNorm(vec2 pos_screen);  vec3 decode_normal (vec2 enc);  void main()   {      vec2 tc = vary_fragcoord.xy; -	vec3 norm = texture2DRect(normalMap, tc).xyz; -	norm = decode_normal(norm.xy); // unpack norm - -	vec3 pos = getPosition(tc).xyz; -	vec4 ccol = texture2DRect(lightMap, tc).rgba; -	 -	vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy); -	dlt /= max(-pos.z*dist_factor, 1.0); -	 -	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; - -	// relax tolerance according to distance to avoid speckling artifacts, as angles and distances are a lot more abrupt within a small screen area at larger distances -	float pointplanedist_tolerance_pow2 = pos.z*pos.z*0.00005; - -	// perturb sampling origin slightly in screen-space to hide edge-ghosting artifacts where smoothing radius is quite large -	float tc_mod = 0.5*(tc.x + tc.y); // mod(tc.x+tc.y,2) -	tc_mod -= floor(tc_mod); -	tc_mod *= 2.0; -	tc += ( (tc_mod - 0.5) * kern[1].z * dlt * 0.5 ); - -	for (int i = 1; i < 4; i++) -	{ -		vec2 samptc = tc + kern[i].z*dlt; -	    vec3 samppos = getPosition(samptc).xyz;  - -		float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane -		 -		if (d*d <= pointplanedist_tolerance_pow2) -		{ -			col += texture2DRect(lightMap, samptc)*kern[i].xyxx; -			defined_weight += kern[i].xy; -		} -	} - -	for (int i = 1; i < 4; i++) -	{ -		vec2 samptc = tc - kern[i].z*dlt; -	    vec3 samppos = getPosition(samptc).xyz;  - -		float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane -		 -		if (d*d <= pointplanedist_tolerance_pow2) -		{ -			col += texture2DRect(lightMap, samptc)*kern[i].xyxx; -			defined_weight += kern[i].xy; -		} -	} - -	col /= defined_weight.xyxx; -	col.y *= col.y; -	 -	frag_color = col; +    vec3 norm = getNorm(tc); +    vec3 pos = getPosition(tc).xyz; +    vec4 ccol = texture2DRect(lightMap, tc).rgba; +     +    vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy); +    dlt /= max(-pos.z*dist_factor, 1.0); +     +    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; + +    // relax tolerance according to distance to avoid speckling artifacts, as angles and distances are a lot more abrupt within a small screen area at larger distances +    float pointplanedist_tolerance_pow2 = pos.z*pos.z*0.00005; + +    // perturb sampling origin slightly in screen-space to hide edge-ghosting artifacts where smoothing radius is quite large +    float tc_mod = 0.5*(tc.x + tc.y); // mod(tc.x+tc.y,2) +    tc_mod -= floor(tc_mod); +    tc_mod *= 2.0; +    tc += ( (tc_mod - 0.5) * kern[1].z * dlt * 0.5 ); + +    for (int i = 1; i < 4; i++) +    { +        vec2 samptc = tc + kern[i].z*dlt; +        vec3 samppos = getPosition(samptc).xyz;  + +        float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane +         +        if (d*d <= pointplanedist_tolerance_pow2) +        { +            col += texture2DRect(lightMap, samptc)*kern[i].xyxx; +            defined_weight += kern[i].xy; +        } +    } + +    for (int i = 1; i < 4; i++) +    { +        vec2 samptc = tc - kern[i].z*dlt; +        vec3 samppos = getPosition(samptc).xyz;  + +        float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane +         +        if (d*d <= pointplanedist_tolerance_pow2) +        { +            col += texture2DRect(lightMap, samptc)*kern[i].xyxx; +            defined_weight += kern[i].xy; +        } +    } + +    col /= defined_weight.xyxx; +    col.y *= col.y; +     +    frag_color = col;  #ifdef IS_AMD_CARD -	// If it's AMD make sure the GLSL compiler sees the arrays referenced once by static index. Otherwise it seems to optimise the storage awawy which leads to unfun crashes and artifacts. -	vec3 dummy1 = kern[0]; -	vec3 dummy2 = kern[3]; +    // If it's AMD make sure the GLSL compiler sees the arrays referenced once by static index. Otherwise it seems to optimise the storage awawy which leads to unfun crashes and artifacts. +    vec3 dummy1 = kern[0]; +    vec3 dummy2 = kern[3];  #endif  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl index fef1c5a584..380d382020 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl @@ -50,14 +50,7 @@ uniform vec2 screen_res;  VARYING vec2 vary_fragcoord; -float getDepth(vec2 pos_screen) -{ -	float z = texture2DRect(depthMap, pos_screen.xy).r; -	z = z*2.0-1.0; -	vec4 ndc = vec4(0.0, 0.0, z, 1.0); -	vec4 p = inv_proj*ndc; -	return p.z/p.w; -} +float getDepth(vec2 pos_screen);  float calc_cof(float depth)  { diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl index ec05dab57f..9d7a7f6556 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl @@ -25,29 +25,6 @@  uniform sampler2DRect   normalMap;  uniform sampler2DRect   depthMap; -uniform sampler2D       noiseMap; -uniform sampler2DShadow shadowMap0; -uniform sampler2DShadow shadowMap1; -uniform sampler2DShadow shadowMap2; -uniform sampler2DShadow shadowMap3; -uniform sampler2DShadow shadowMap4; -uniform sampler2DShadow shadowMap5; - -uniform float ssao_radius; -uniform float ssao_max_radius; -uniform float ssao_factor; -uniform float ssao_factor_inv; - -uniform vec3 sun_dir; -uniform vec3 moon_dir; -uniform vec2 shadow_res; -uniform vec2 proj_shadow_res; -uniform mat4 shadow_matrix[6]; -uniform vec4 shadow_clip; -uniform float shadow_bias; - -uniform float spot_shadow_bias; -uniform float spot_shadow_offset;  uniform mat4 inv_proj;  uniform vec2 screen_res; @@ -87,8 +64,6 @@ vec4 getPosition(vec2 pos_screen)      return pos;  } -#if USE_DEFERRED_SHADER_API -  vec4 getPositionWithDepth(vec2 pos_screen, float depth)  {      vec2 sc = getScreenCoordinate(pos_screen); @@ -98,200 +73,3 @@ vec4 getPositionWithDepth(vec2 pos_screen, float depth)      pos.w = 1.0;      return pos;  } - -float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float bias_scale, vec2 pos_screen) -{ -    stc.xyz /= stc.w; -    stc.z += shadow_bias * bias_scale; -         -    stc.x = floor(stc.x*pos_screen.x + fract(stc.y*shadow_res.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here -     -    float cs = shadow2D(shadowMap, stc.xyz).x; -    float shadow = cs; -    shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; -    shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; -    shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; -    shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; -    return shadow*0.2; -} - -float pcfSpotShadow(sampler2DShadow shadowMap, vec4 stc, float bias_scale, vec2 pos_screen) -{ -    stc.xyz /= stc.w; -    stc.z += spot_shadow_bias * bias_scale; -    stc.x = floor(proj_shadow_res.x * stc.x + fract(pos_screen.y*0.666666666)) / proj_shadow_res.x; // snap - -    float cs = shadow2D(shadowMap, stc.xyz).x; -    float shadow = cs; - -    vec2 off = 1.0/proj_shadow_res; -    off.y *= 1.5; -     -    shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x*2.0, off.y, 0.0)).x; -    shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x; -    shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x; -    shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x*2.0, -off.y, 0.0)).x; -    return shadow*0.2; -} - -float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen) -{ -    float dp_sun = max(0.0, dot(sun_dir.xyz, norm)); -    float dp_moon = max(0.0, dot(moon_dir.xyz, norm)); -    float dp_directional_light = max(dp_sun,dp_moon); -          dp_directional_light = clamp(dp_directional_light, 0.0, 1.0); - -        vec3 light_dir = (dp_moon > dp_sun) ? moon_dir : sun_dir; -    vec3 offset = light_dir * (1.0-dp_directional_light); -    vec3 shadow_pos = pos.xyz + (offset * shadow_bias); - -    float shadow = 0.0f; -    vec4 spos = vec4(shadow_pos,1.0); -    if (spos.z > -shadow_clip.w) -    {    -        vec4 lpos; -        vec4 near_split = shadow_clip*-0.75; -        vec4 far_split = shadow_clip*-1.25; -        vec4 transition_domain = near_split-far_split; -        float weight = 0.0; - -        if (spos.z < near_split.z) -        { -            lpos = shadow_matrix[3]*spos; -             -            float w = 1.0; -            w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; -            shadow += pcfShadow(shadowMap3, lpos, 0.5, pos_screen)*w; -            weight += w; -            shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); -        } - -        if (spos.z < near_split.y && spos.z > far_split.z) -        { -            lpos = shadow_matrix[2]*spos; -             -            float w = 1.0; -            w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; -            w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; -            shadow += pcfShadow(shadowMap2, lpos, 0.75, pos_screen)*w; -            weight += w; -        } - -        if (spos.z < near_split.x && spos.z > far_split.y) -        { -            lpos = shadow_matrix[1]*spos; -             -            float w = 1.0; -            w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; -            w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; -            shadow += pcfShadow(shadowMap1, lpos, 0.88, pos_screen)*w; -            weight += w; -        } - -        if (spos.z > far_split.x) -        { -            lpos = shadow_matrix[0]*spos; -                             -            float w = 1.0; -            w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; -                 -            shadow += pcfShadow(shadowMap0, lpos, 1.0, pos_screen)*w; -            weight += w; -        } - -        shadow /= weight; -    } -    return shadow; -} - -float sampleSpotShadow(vec3 pos, vec3 norm, int index, vec2 pos_screen) -{ -    float shadow = 0.0f; -    pos += norm * spot_shadow_offset; - -    vec4 spos = vec4(pos,1.0); -    if (spos.z > -shadow_clip.w) -    {    -        vec4 lpos; -         -        vec4 near_split = shadow_clip*-0.75; -        vec4 far_split = shadow_clip*-1.25; -        vec4 transition_domain = near_split-far_split; -        float weight = 0.0; - -        { -            lpos = shadow_matrix[4 + index]*spos; -            float w = 1.0; -            w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; -         -            shadow += pcfSpotShadow((index == 0) ? shadowMap4 : shadowMap5, lpos, 0.8, spos.xy)*w; -            weight += w; -            shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); -        } - -        shadow /= weight; -    } -    return shadow; -} - -vec2 getKern(int i) -{ -    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; -        -    return kern[i]; -} - -//calculate decreases in ambient lighting when crowded out (SSAO) -float calcAmbientOcclusion(vec4 pos, vec3 norm, vec2 pos_screen) -{ -    float ret = 1.0; -    vec3 pos_world = pos.xyz; -    vec2 noise_reflect = texture2D(noiseMap, pos_screen.xy/128.0).xy; -         -    float angle_hidden = 0.0; -    float 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(getKern(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) -         -        float funky_val = (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) ? 1.0 : 0.0; -        angle_hidden = angle_hidden + funky_val * min(1.0/dist2, ssao_factor_inv); -             -        // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion"  -        float diffz_val = (diff.z > -1.0) ? 1.0 : 0.0; -        points = points + diffz_val; -    } -         -    angle_hidden = min(ssao_factor*angle_hidden/points, 1.0); -     -    float points_val = (points > 0.0) ? 1.0 : 0.0; -    ret = (1.0 - (points_val * angle_hidden)); - -    ret = max(ret, 0.0); -    return min(ret, 1.0); -} - -#endif - diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl index 0e21e5925d..2db737a427 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl @@ -45,9 +45,6 @@ VARYING vec2 vary_texcoord0;  vec4 applyWaterFogView(vec3 pos, vec4 color);  #endif -vec3 srgb_to_linear(vec3 cs); -vec3 linear_to_srgb(vec3 cl); -  vec3 fullbrightAtmosTransportDeferred(vec3 light)  {  	return light; @@ -81,12 +78,9 @@ void main()  #endif  	color.rgb *= vertex_color.rgb; -	color.rgb = srgb_to_linear(color.rgb);  	color.rgb = fullbrightAtmosTransportDeferred(color.rgb);  	color.rgb = fullbrightScaleSoftClipDeferred(color.rgb); -	color.rgb = linear_to_srgb(color.rgb); -  #ifdef WATER_FOG  	vec3 pos = vary_position;  	vec4 fogged = applyWaterFogView(pos, vec4(color.rgb, final_alpha)); diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl index 6ba16b169c..d29e8a9423 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl @@ -40,8 +40,6 @@ uniform sampler2D specularMap;  VARYING vec2 vary_texcoord0; -vec3 linear_to_srgb(vec3 cl); -  void main()   {  	vec4 col = texture2D(diffuseMap, vary_texcoord0.xy); @@ -54,8 +52,6 @@ void main()  	vec4 norm = texture2D(normalMap,   vary_texcoord0.xy);  	vec4 spec = texture2D(specularMap, vary_texcoord0.xy); -	col.rgb = linear_to_srgb(col.rgb); -  	frag_data[0] = vec4(col.rgb, 0.0);  	frag_data[1] = spec;  	frag_data[2] = vec4(norm.xy,0,0); diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl index 7d5ae7c2e7..a0da8563a2 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl @@ -25,9 +25,9 @@  /*[EXTRA_CODE_HERE]*/ -#define DIFFUSE_ALPHA_MODE_IGNORE	0 -#define DIFFUSE_ALPHA_MODE_BLEND	1 -#define DIFFUSE_ALPHA_MODE_MASK		2 +#define DIFFUSE_ALPHA_MODE_IGNORE   0 +#define DIFFUSE_ALPHA_MODE_BLEND    1 +#define DIFFUSE_ALPHA_MODE_MASK     2  #define DIFFUSE_ALPHA_MODE_EMISSIVE 3  uniform float emissive_brightness; @@ -37,10 +37,6 @@ uniform float display_gamma;  vec4 applyWaterFogView(vec3 pos, vec4 color);  #endif -vec3 srgb_to_linear(vec3 cs); -vec3 linear_to_srgb(vec3 cl); - -vec3 atmosFragAmbient(vec3 l, vec3 ambient);  vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten);  vec3 scaleSoftClipFrag(vec3 l); @@ -66,7 +62,7 @@ uniform vec4 shadow_clip;  uniform vec2 shadow_res;  uniform float shadow_bias; -float pcfShadow(sampler2DShadow shadowMap, vec4 stc) +float pcfShadowLegacy(sampler2DShadow shadowMap, vec4 stc)  {  	stc.xyz /= stc.w;  	stc.z += shadow_bias; @@ -84,10 +80,11 @@ float pcfShadow(sampler2DShadow shadowMap, vec4 stc)      return shadow*0.2;  } +float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float bias_scale, vec2 pos_screen);  #endif  uniform samplerCube environmentMap; -uniform sampler2D	  lightFunc; +uniform sampler2D     lightFunc;  // Inputs  uniform vec4 morphFactor; @@ -113,80 +110,80 @@ uniform vec3 light_diffuse[8];  vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spec, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, inout float glare)  { -	//get light vector -	vec3 lv = lp.xyz-v; -	 -	//get distance -	float d = length(lv); -	 -	float da = 1.0; - -	vec3 col = vec3(0,0,0); - -	if (d > 0.0 && la > 0.0 && fa > 0.0) -	{ -		//normalize light vector -		lv = normalize(lv); -	 -		//distance attenuation -		float dist = d/la; -		float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0); -		dist_atten *= dist_atten; -		dist_atten *= 2.0; - -		// spotlight coefficient. -		float spot = max(dot(-ln, lv), is_pointlight); -		da *= spot*spot; // GL_SPOT_EXPONENT=2 - -		//angular attenuation -		da *= max(dot(n, lv), 0.0);		 -		 -		float lit = max(da * dist_atten, 0.0); - -		col = light_col*lit*diffuse; - -		if (spec.a > 0.0) -		{ -			//vec3 ref = dot(pos+lv, norm); -			vec3 h = normalize(lv+npos); -			float nh = dot(n, h); -			float nv = dot(n, npos); -			float vh = dot(npos, h); -			float sa = nh; -			float fres = pow(1 - dot(h, npos), 5)*0.4+0.5; - -			float gtdenom = 2 * nh; -			float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh)); -								 -			if (nh > 0.0) -			{ -				float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da); -				vec3 speccol = lit*scol*light_col.rgb*spec.rgb; -				col += speccol; - -				float cur_glare = max(speccol.r, speccol.g); -				cur_glare = max(cur_glare, speccol.b); -				glare = max(glare, speccol.r); -				glare += max(cur_glare, 0.0); -				//col += spec.rgb; -			} -		} -	} - -	return max(col, vec3(0.0,0.0,0.0));	 +    //get light vector +    vec3 lv = lp.xyz-v; +     +    //get distance +    float d = length(lv); +     +    float da = 1.0; + +    vec3 col = vec3(0,0,0); + +    if (d > 0.0 && la > 0.0 && fa > 0.0) +    { +        //normalize light vector +        lv = normalize(lv); +     +        //distance attenuation +        float dist = d/la; +        float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0); +        dist_atten *= dist_atten; +        dist_atten *= 2.0; + +        // spotlight coefficient. +        float spot = max(dot(-ln, lv), is_pointlight); +        da *= spot*spot; // GL_SPOT_EXPONENT=2 + +        //angular attenuation +        da *= max(dot(n, lv), 0.0);      +         +        float lit = max(da * dist_atten, 0.0); + +        col = light_col*lit*diffuse; + +        if (spec.a > 0.0) +        { +            //vec3 ref = dot(pos+lv, norm); +            vec3 h = normalize(lv+npos); +            float nh = dot(n, h); +            float nv = dot(n, npos); +            float vh = dot(npos, h); +            float sa = nh; +            float fres = pow(1 - dot(h, npos), 5)*0.4+0.5; + +            float gtdenom = 2 * nh; +            float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh)); +                                 +            if (nh > 0.0) +            { +                float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da); +                vec3 speccol = lit*scol*light_col.rgb*spec.rgb; +                col += speccol; + +                float cur_glare = max(speccol.r, speccol.g); +                cur_glare = max(cur_glare, speccol.b); +                glare = max(glare, speccol.r); +                glare += max(cur_glare, 0.0); +                //col += spec.rgb; +            } +        } +    } + +    return max(col, vec3(0.0,0.0,0.0));   }  vec4 getPosition_d(vec2 pos_screen, float depth)  { -	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; +    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;  } @@ -234,262 +231,255 @@ vec3 decode_normal (vec2 enc);  void main()   { -	vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy); -	diffcol.rgb *= vertex_color.rgb; +    vec2 pos_screen = vary_texcoord0.xy; + +    vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy); +    diffcol.rgb *= vertex_color.rgb;  #if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK) -	if (diffcol.a < minimum_alpha) -	{ -		discard; -	} +    if (diffcol.a < minimum_alpha) +    { +        discard; +    }  #endif  #if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) -	vec3 gamma_diff = diffcol.rgb; -	diffcol.rgb = srgb_to_linear(diffcol.rgb); +    vec3 gamma_diff = diffcol.rgb;  #endif  #if HAS_SPECULAR_MAP -	vec4 spec = texture2D(specularMap, vary_texcoord2.xy); -	spec.rgb *= specular_color.rgb; +    vec4 spec = texture2D(specularMap, vary_texcoord2.xy); +    spec.rgb *= specular_color.rgb;  #else -	vec4 spec = vec4(specular_color.rgb, 1.0); +    vec4 spec = vec4(specular_color.rgb, 1.0);  #endif  #if HAS_NORMAL_MAP -	vec4 norm = texture2D(bumpMap, vary_texcoord1.xy); +    vec4 norm = texture2D(bumpMap, vary_texcoord1.xy); -	norm.xyz = norm.xyz * 2 - 1; +    norm.xyz = norm.xyz * 2 - 1; -	vec3 tnorm = vec3(dot(norm.xyz,vary_mat0), -			  dot(norm.xyz,vary_mat1), -			  dot(norm.xyz,vary_mat2)); +    vec3 tnorm = vec3(dot(norm.xyz,vary_mat0), +              dot(norm.xyz,vary_mat1), +              dot(norm.xyz,vary_mat2));  #else -	vec4 norm = vec4(0,0,0,1.0); -	vec3 tnorm = vary_normal; +    vec4 norm = vec4(0,0,0,1.0); +    vec3 tnorm = vary_normal;  #endif      norm.xyz = tnorm;      norm.xyz = normalize(norm.xyz); -	vec2 abnormal	= encode_normal(norm.xyz); -		 norm.xyz   = decode_normal(abnormal.xy); +    vec2 abnormal   = encode_normal(norm.xyz); +         norm.xyz   = decode_normal(abnormal.xy); -	vec4 final_color = diffcol; -	 +    vec4 final_color = diffcol; +      #if (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE) -	final_color.a = emissive_brightness; +    final_color.a = emissive_brightness;  #else -	final_color.a = max(final_color.a, emissive_brightness); +    final_color.a = max(final_color.a, emissive_brightness);  #endif -	vec4 final_specular = spec; +    vec4 final_specular = spec;  #if HAS_SPECULAR_MAP -	vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity * spec.a, 0.0); -	final_specular.a = specular_color.a * norm.a; +    vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity * spec.a, 0.0); +    final_specular.a = specular_color.a * norm.a;  #else -	vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity, 0.0); -	final_specular.a = specular_color.a; +    vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity, 0.0); +    final_specular.a = specular_color.a;  #endif -	 +      #if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) -		//forward rendering, output just lit RGBA -	vec3 pos = vary_position; +        //forward rendering, output just lit RGBA +    vec3 pos = vary_position;  #if HAS_SUN_SHADOW -	float shadow = 0.0; -	 -	vec4 spos = vec4(pos,1.0); -		 -	if (spos.z > -shadow_clip.w) -	{	 -		vec4 lpos; -		 -		vec4 near_split = shadow_clip*-0.75; -		vec4 far_split = shadow_clip*-1.25; -		vec4 transition_domain = near_split-far_split; -		float weight = 0.0; - -		if (spos.z < near_split.z) -		{ -			lpos = shadow_matrix[3]*spos; -			 -			float w = 1.0; -			w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; -			shadow += pcfShadow(shadowMap3, lpos)*w; -			weight += w; -			shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); -		} - -		if (spos.z < near_split.y && spos.z > far_split.z) -		{ -			lpos = shadow_matrix[2]*spos; -			 -			float w = 1.0; -			w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; -			w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; -			shadow += pcfShadow(shadowMap2, lpos)*w; -			weight += w; -		} - -		if (spos.z < near_split.x && spos.z > far_split.y) -		{ -			lpos = shadow_matrix[1]*spos; -			 -			float w = 1.0; -			w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; -			w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; -			shadow += pcfShadow(shadowMap1, lpos)*w; -			weight += w; -		} - -		if (spos.z > far_split.x) -		{ -			lpos = shadow_matrix[0]*spos; -							 -			float w = 1.0; -			w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; -				 -			shadow += pcfShadow(shadowMap0, lpos)*w; -			weight += w; -		} -		 - -		shadow /= weight; -	} -	else -	{ -		shadow = 1.0; -	} +    float shadow = 0.0; +     +    vec4 spos = vec4(pos,1.0); +         +    if (spos.z > -shadow_clip.w) +    {    +        vec4 lpos; +         +        vec4 near_split = shadow_clip*-0.75; +        vec4 far_split = shadow_clip*-1.25; +        vec4 transition_domain = near_split-far_split; +        float weight = 0.0; + +        if (spos.z < near_split.z) +        { +            lpos = shadow_matrix[3]*spos; +             +            float w = 1.0; +            w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; +            shadow += pcfShadowLegacy(shadowMap3, lpos)*w; +            weight += w; +            shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); +        } + +        if (spos.z < near_split.y && spos.z > far_split.z) +        { +            lpos = shadow_matrix[2]*spos; +             +            float w = 1.0; +            w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; +            w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; +            shadow += pcfShadowLegacy(shadowMap2, lpos)*w; +            weight += w; +        } + +        if (spos.z < near_split.x && spos.z > far_split.y) +        { +            lpos = shadow_matrix[1]*spos; +             +            float w = 1.0; +            w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; +            w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; +            shadow += pcfShadowLegacy(shadowMap1, lpos)*w; +            weight += w; +        } + +        if (spos.z > far_split.x) +        { +            lpos = shadow_matrix[0]*spos; +                             +            float w = 1.0; +            w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; +                 +            shadow += pcfShadowLegacy(shadowMap0, lpos)*w; +            weight += w; +        } +         + +        shadow /= weight; +    } +    else +    { +        shadow = 1.0; +    }  #else -	float shadow = 1.0; +    float shadow = 1.0;  #endif -	spec = final_specular; -	vec4 diffuse = final_color; -	float envIntensity = final_normal.z; +    spec = final_specular; +    vec4 diffuse = final_color; +    float envIntensity = final_normal.z;      vec3 col = vec3(0.0f,0.0f,0.0f); -	float bloom = 0.0; +    float bloom = 0.0;          vec3 sunlit;          vec3 amblit;          vec3 additive;          vec3 atten; -	calcFragAtmospherics(pos.xyz, 1.0, sunlit, amblit, additive, atten); -	 -	vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); +    calcFragAtmospherics(pos.xyz, 1.0, sunlit, amblit, additive, atten); +     +    vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); -	float sun_da  = dot(norm.xyz, sun_dir.xyz); -	float moon_da = dot(norm.xyz, moon_dir.xyz); +    float sun_da  = dot(norm.xyz, sun_dir.xyz); +    float moon_da = dot(norm.xyz, moon_dir.xyz);      float final_da = max(sun_da,moon_da);            final_da = min(final_da, shadow);            //final_da = max(final_da, diffuse.a);            final_da = max(final_da, 0.0f); -		  final_da = min(final_da, 1.0f); -		  final_da = pow(final_da, 1.0/1.3); +          final_da = min(final_da, 1.0f); +          final_da = pow(final_da, display_gamma); -	col.rgb = atmosFragAmbient(col, amblit); -	 -	float ambient = min(abs(final_da), 1.0); -	ambient *= 0.5; -	ambient *= ambient; -	ambient = (1.0-ambient); +    col.rgb = (col * 0.5) + amblit; +     +    float ambient = min(abs(final_da), 1.0); +    ambient *= 0.5; +    ambient *= ambient; +    ambient = (1.0-ambient); -	col.rgb *= ambient; +    col.rgb *= ambient; -	col.rgb = col.rgb + (final_da * sunlit); +    col.rgb = col.rgb + (final_da * sunlit); -	col.rgb *= gamma_diff.rgb; -	 +    col.rgb *= gamma_diff.rgb; +     -	float glare = 0.0; +    float glare = 0.0; -	if (spec.a > 0.0) // specular reflection -	{ -		// the old infinite-sky shiny reflection -		// -				 +    if (spec.a > 0.0) // specular reflection +    { +        // the old infinite-sky shiny reflection +        // +                          float sa = dot(refnormpersp, sun_dir.xyz); -		vec3 dumbshiny = sunlit*shadow*(texture2D(lightFunc, vec2(sa, spec.a)).r); -							 -		// add the two types of shiny together -		vec3 spec_contrib = dumbshiny * spec.rgb; -		bloom = dot(spec_contrib, spec_contrib) / 6; - -		glare = max(spec_contrib.r, spec_contrib.g); -		glare = max(glare, spec_contrib.b); +        vec3 dumbshiny = sunlit*shadow*(texture2D(lightFunc, vec2(sa, spec.a)).r); +                             +        // add the two types of shiny together +        vec3 spec_contrib = dumbshiny * spec.rgb; +        bloom = dot(spec_contrib, spec_contrib) / 6; -		col += spec_contrib; -	} +        glare = max(spec_contrib.r, spec_contrib.g); +        glare = max(glare, spec_contrib.b); +        col += spec_contrib; +    } -	col = mix(col.rgb, diffcol.rgb, diffuse.a); - -	if (envIntensity > 0.0) -	{ -		//add environmentmap -		vec3 env_vec = env_mat * refnormpersp; -		 -		vec3 refcol = textureCube(environmentMap, env_vec).rgb; -		col = mix(col.rgb, refcol,  -			envIntensity);   +    col = mix(col.rgb, diffcol.rgb, diffuse.a); -		float cur_glare = max(refcol.r, refcol.g); -		cur_glare = max(cur_glare, refcol.b); -		cur_glare *= envIntensity*4.0; -		glare += cur_glare; -	} +    if (envIntensity > 0.0) +    { +        //add environmentmap +        vec3 env_vec = env_mat * refnormpersp; +         +        vec3 refcol = textureCube(environmentMap, env_vec).rgb; -	//col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a); -	//col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col),  diffuse.a); +        col = mix(col.rgb, refcol,  +            envIntensity);   -	col = atmosFragLighting(col, additive, atten); -	col = scaleSoftClipFrag(col); +        float cur_glare = max(refcol.r, refcol.g); +        cur_glare = max(cur_glare, refcol.b); +        cur_glare *= envIntensity*4.0; +        glare += cur_glare; +    } -	//convert to linear space before adding local lights -	col = srgb_to_linear(col); +    col = atmosFragLighting(col, additive, atten); -	vec3 npos = normalize(-pos.xyz); -			 -	vec3 light = vec3(0,0,0); +    vec3 npos = normalize(-pos.xyz); +             +    vec3 light = vec3(0,0,0);   #define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, npos, diffuse.rgb, final_specular, pos.xyz, norm.xyz, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, glare); -		LIGHT_LOOP(1) -		LIGHT_LOOP(2) -		LIGHT_LOOP(3) -		LIGHT_LOOP(4) -		LIGHT_LOOP(5) -		LIGHT_LOOP(6) -		LIGHT_LOOP(7) +        LIGHT_LOOP(1) +        LIGHT_LOOP(2) +        LIGHT_LOOP(3) +        LIGHT_LOOP(4) +        LIGHT_LOOP(5) +        LIGHT_LOOP(6) +        LIGHT_LOOP(7) -	col.rgb += light.rgb; +    col.rgb += light.rgb; -	glare = min(glare, 1.0); -	float al = max(diffcol.a,glare)*vertex_color.a; +    glare = min(glare, 1.0); +    float al = max(diffcol.a,glare)*vertex_color.a; -	//convert to gamma space for display on screen -	col.rgb = linear_to_srgb(col.rgb); +    col = scaleSoftClipFrag(col);  #ifdef WATER_FOG -	vec4 temp = applyWaterFogView(pos, vec4(col.rgb, al)); -	col.rgb = temp.rgb; -	al = temp.a; +    vec4 temp = applyWaterFogView(pos, vec4(col.rgb, al)); +    col.rgb = temp.rgb; +    al = temp.a;  #endif -	frag_color.rgb = col.rgb; -	frag_color.a   = al; +    frag_color.rgb = col.rgb; +    frag_color.a   = al;  #else -	frag_data[0] = final_color; -	frag_data[1] = final_specular; // XYZ = Specular color. W = Specular exponent. -	frag_data[2] = final_normal; // XY = Normal.  Z = Env. intensity. +    frag_data[0] = final_color; +    frag_data[1] = final_specular; // XYZ = Specular color. W = Specular exponent. +    frag_data[2] = final_normal; // XY = Normal.  Z = Env. intensity.  #endif  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl index d1ac19270d..e8eef9b94b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl @@ -59,18 +59,7 @@ uniform mat4 inv_proj;  vec3 decode_normal (vec2 enc); -vec4 getPosition(vec2 pos_screen) -{ -	float depth = texture2DRect(depthMap, pos_screen.xy).r; -	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; -} +vec4 getPosition(vec2 pos_screen);  void main()   { diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl index 1d75322b4c..7438fac8fc 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl @@ -73,13 +73,10 @@ uniform vec2 screen_res;  uniform mat4 inv_proj;  vec3 decode_normal (vec2 enc); -vec3 srgb_to_linear(vec3 cs); -vec3 linear_to_srgb(vec3 cl);  vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); -	ret.rgb = srgb_to_linear(ret.rgb);  	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); @@ -99,7 +96,6 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)  vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); -	ret.rgb = srgb_to_linear(ret.rgb);  	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); @@ -117,7 +113,6 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)  vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); -	ret.rgb = srgb_to_linear(ret.rgb);  	vec2 dist = tc-vec2(0.5); @@ -128,19 +123,7 @@ vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)  	return ret;  } - -vec4 getPosition(vec2 pos_screen) -{ -	float depth = texture2DRect(depthMap, pos_screen.xy).r; -	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; -} +vec4 getPosition(vec2 pos_screen);  void main()   { diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl index 13b803e03e..8e756c37bf 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl @@ -58,18 +58,7 @@ uniform vec4 viewport;  vec3 decode_normal (vec2 enc); -vec4 getPosition(vec2 pos_screen) -{ -	float depth = texture2DRect(depthMap, pos_screen.xy).r; -	vec2 sc = (pos_screen.xy-viewport.xy)*2.0; -	sc /= viewport.zw; -	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; -} +vec4 getPosition(vec2 pos_screen);  void main()   { diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl index 8791469675..0b943d2527 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl @@ -40,12 +40,10 @@ VARYING vec2 vary_fragcoord;  uniform float display_gamma; -vec3 linear_to_srgb(vec3 cl); -  void main()   { -	vec4 diff = texture2DRect(diffuseRect, vary_fragcoord); +    vec4 diff = texture2DRect(diffuseRect, vary_fragcoord);      diff.rgb = pow(diff.rgb, vec3(display_gamma)); -	frag_color = diff; +    frag_color = diff;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowUtil.glsl new file mode 100644 index 0000000000..ae5cb7cbc1 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowUtil.glsl @@ -0,0 +1,191 @@ +/**  + * @file class1/deferred/shadowUtil.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +uniform sampler2DRect   normalMap; +uniform sampler2DRect   depthMap; +uniform sampler2D       noiseMap; +uniform sampler2DShadow shadowMap0; +uniform sampler2DShadow shadowMap1; +uniform sampler2DShadow shadowMap2; +uniform sampler2DShadow shadowMap3; +uniform sampler2DShadow shadowMap4; +uniform sampler2DShadow shadowMap5; + +uniform float ssao_radius; +uniform float ssao_max_radius; +uniform float ssao_factor; +uniform float ssao_factor_inv; + +uniform vec3 sun_dir; +uniform vec3 moon_dir; +uniform vec2 shadow_res; +uniform vec2 proj_shadow_res; +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; +uniform float shadow_bias; + +uniform float spot_shadow_bias; +uniform float spot_shadow_offset; + +uniform mat4 inv_proj; +uniform vec2 screen_res; + +vec3 decode_normal(vec2 enc); + +float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float bias_scale, vec2 pos_screen) +{ +    stc.xyz /= stc.w; +    stc.z += shadow_bias; +         +    stc.x = floor(stc.x*pos_screen.x + fract(stc.y*shadow_res.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here +     +    float cs = shadow2D(shadowMap, stc.xyz).x; +    float shadow = cs; +    shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; +    shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; +    shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; +    shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; +    return shadow*0.2; +} + +float pcfSpotShadow(sampler2DShadow shadowMap, vec4 stc, float bias_scale, vec2 pos_screen) +{ +    stc.xyz /= stc.w; +    stc.z += spot_shadow_bias * bias_scale; +    stc.x = floor(proj_shadow_res.x * stc.x + fract(pos_screen.y*0.666666666)) / proj_shadow_res.x; // snap + +    float cs = shadow2D(shadowMap, stc.xyz).x; +    float shadow = cs; + +    vec2 off = 1.0/proj_shadow_res; +    off.y *= 1.5; +     +    shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x*2.0, off.y, 0.0)).x; +    shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x; +    shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x; +    shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x*2.0, -off.y, 0.0)).x; +    return shadow*0.2; +} + +float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen) +{ +    float dp_sun = max(0.0, dot(sun_dir.xyz, norm)); +    float dp_moon = max(0.0, dot(moon_dir.xyz, norm)); +    float dp_directional_light = max(dp_sun,dp_moon); +          dp_directional_light = clamp(dp_directional_light, 0.0, 1.0); + +        vec3 light_dir = (dp_moon > dp_sun) ? moon_dir : sun_dir; +    vec3 offset = light_dir * (1.0-dp_directional_light); +    vec3 shadow_pos = pos.xyz + (offset * shadow_bias); + +    float shadow = 0.0f; +    vec4 spos = vec4(shadow_pos,1.0); +    if (spos.z > -shadow_clip.w) +    {    +        vec4 lpos; +        vec4 near_split = shadow_clip*-0.75; +        vec4 far_split = shadow_clip*-1.25; +        vec4 transition_domain = near_split-far_split; +        float weight = 0.0; + +        if (spos.z < near_split.z) +        { +            lpos = shadow_matrix[3]*spos; +             +            float w = 1.0; +            w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; +            shadow += pcfShadow(shadowMap3, lpos, 0.5, pos_screen)*w; +            weight += w; +            shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); +        } + +        if (spos.z < near_split.y && spos.z > far_split.z) +        { +            lpos = shadow_matrix[2]*spos; +             +            float w = 1.0; +            w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; +            w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; +            shadow += pcfShadow(shadowMap2, lpos, 0.75, pos_screen)*w; +            weight += w; +        } + +        if (spos.z < near_split.x && spos.z > far_split.y) +        { +            lpos = shadow_matrix[1]*spos; +             +            float w = 1.0; +            w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; +            w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; +            shadow += pcfShadow(shadowMap1, lpos, 0.88, pos_screen)*w; +            weight += w; +        } + +        if (spos.z > far_split.x) +        { +            lpos = shadow_matrix[0]*spos; +                             +            float w = 1.0; +            w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; +                 +            shadow += pcfShadow(shadowMap0, lpos, 1.0, pos_screen)*w; +            weight += w; +        } + +        shadow /= weight; +    } +    return shadow; +} + +float sampleSpotShadow(vec3 pos, vec3 norm, int index, vec2 pos_screen) +{ +    float shadow = 0.0f; +    pos += norm * spot_shadow_offset; + +    vec4 spos = vec4(pos,1.0); +    if (spos.z > -shadow_clip.w) +    {    +        vec4 lpos; +         +        vec4 near_split = shadow_clip*-0.75; +        vec4 far_split = shadow_clip*-1.25; +        vec4 transition_domain = near_split-far_split; +        float weight = 0.0; + +        { +            lpos = shadow_matrix[4 + index]*spos; +            float w = 1.0; +            w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; +         +            shadow += pcfSpotShadow((index == 0) ? shadowMap4 : shadowMap5, lpos, 0.8, spos.xy)*w; +            weight += w; +            shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); +        } + +        shadow /= weight; +    } +    return shadow; +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl index 41eb06126b..0de38a3d62 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl @@ -66,10 +66,7 @@ uniform vec2 screen_res;  vec4 applyWaterFogView(vec3 pos, vec4 color);  #endif -vec3 srgb_to_linear(vec3 cs); -vec3 linear_to_srgb(vec3 cl);  vec3 decode_normal (vec2 enc); -  vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten);  vec3 fullbrightAtmosTransportFrag(vec3 l, vec3 additive, vec3 atten);  void calcFragAtmospherics(vec3 inPositionEye, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten); @@ -89,18 +86,14 @@ vec4 getPosition_d(vec2 pos_screen, float depth)      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); -} - +vec4 getPositionWithDepth(vec2 pos_screen, float depth); +vec4 getPosition(vec2 pos_screen);  void main()   {      vec2 tc = vary_fragcoord.xy;      float depth = texture2DRect(depthMap, tc.xy).r; -    vec3 pos = getPosition_d(tc, depth).xyz; +    vec3 pos = getPositionWithDepth(tc, depth).xyz;      vec4 norm = texture2DRect(normalMap, tc);      float envIntensity = norm.z;      norm.xyz = decode_normal(norm.xy); // unpack norm @@ -110,13 +103,10 @@ void main()      float da = max(da_sun, da_moon);      float final_da = clamp(da, 0.0, 1.0); -          final_da = pow(final_da, global_gamma); +          final_da = pow(final_da, global_gamma + 0.3);      vec4 diffuse = texture2DRect(diffuseRect, tc); -    //convert to gamma space -    //diffuse.rgb = linear_to_srgb(diffuse.rgb); -      vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);      vec3 col;      float bloom = 0.0; @@ -173,10 +163,6 @@ void main()              col = fogged.rgb;              bloom = fogged.a;          #endif - -        //col = srgb_to_linear(col); -        //col = vec3(1,0,1); -        //col.g = envIntensity;      }      frag_color.rgb = col.rgb; diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl index 2b6428963d..22488944cd 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl @@ -71,18 +71,10 @@ uniform vec2 screen_res;  uniform mat4 inv_proj;  vec3 decode_normal (vec2 enc); -vec3 srgb_to_linear(vec3 cs); -vec3 linear_to_srgb(vec3 cl); - -vec4 correctWithGamma(vec4 col) -{ -	return vec4(srgb_to_linear(col.rgb), col.a); -}  vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); -	ret.rgb = srgb_to_linear(ret.rgb);  	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); @@ -102,7 +94,6 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)  vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); -	ret = correctWithGamma(ret);  	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); @@ -120,7 +111,6 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)  vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); -	ret = correctWithGamma(ret);  	vec2 dist = tc-vec2(0.5); @@ -131,19 +121,7 @@ vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)  	return ret;  } - -vec4 getPosition(vec2 pos_screen) -{ -	float depth = texture2DRect(depthMap, pos_screen.xy).r; -	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; -} +vec4 getPosition(vec2 pos_screen);  void main()   { diff --git a/indra/newview/app_settings/shaders/class1/deferred/srgb.glsl b/indra/newview/app_settings/shaders/class1/deferred/srgb.glsl deleted file mode 100644 index bc3324f543..0000000000 --- a/indra/newview/app_settings/shaders/class1/deferred/srgb.glsl +++ /dev/null @@ -1,61 +0,0 @@ -/**  - * @file srgb.glsl - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2007, Linden Research, Inc. - *  - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - */ - -vec3 rgb2hsv(vec3 c) -{ -    vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); -    vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); -    vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); - -    float d = q.x - min(q.w, q.y); -    float e = 1.0e-10; -    return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); -} - -vec3 hsv2rgb(vec3 c) -{ -    vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); -    vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); -    return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); -} - -vec3 srgb_to_linear(vec3 cs) -{ -	vec3 low_range = cs / vec3(12.92); -	vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); - -	bvec3 lte = lessThanEqual(cs,vec3(0.04045)); -	return mix(high_range, low_range, lte); -} - -vec3 linear_to_srgb(vec3 cl) -{ -	cl = clamp(cl, vec3(0), vec3(1)); -	vec3 low_range  = cl * 12.92; -	vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055; - -	bvec3 lt = lessThan(cl,vec3(0.0031308)); -	return mix(high_range, low_range, lt); -} diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl index 403df87853..6d65ee2add 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl @@ -41,82 +41,15 @@ uniform sampler2D noiseMap;  // Inputs -uniform float ssao_radius; -uniform float ssao_max_radius; -uniform float ssao_factor; -uniform float ssao_factor_inv; -  VARYING vec2 vary_fragcoord;  uniform mat4 inv_proj;  uniform vec2 screen_res;  vec3 decode_normal (vec2 enc); - -vec4 getPosition(vec2 pos_screen) -{ -	float depth = texture2DRect(depthMap, pos_screen.xy).r; -	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; -	 -	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) -			 -		angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv); -			 -		// 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion"  -		points = points + int(diff.z > -1.0); -	} -		 -	angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0); -		 -	ret = (1.0 - (float(points != 0) * angle_hidden)); -	 -	return min(ret, 1.0); -} +vec4 getPosition(vec2 pos_screen); +vec3 getNorm(vec2 pos_screen); +float calcAmbientOcclusion(vec4 pos, vec3 norm, vec2 pos_screen);  void main()   { @@ -124,13 +57,11 @@ void main()  	//try doing an unproject here -	vec4 pos = getPosition(pos_screen); -	 -	vec3 norm = texture2DRect(normalMap, pos_screen).xyz; -	norm = decode_normal(norm.xy); +	vec4 pos = getPosition(pos_screen);	 +	vec3 norm = getNorm(pos_screen); -	frag_color[0] = 1.0; -	frag_color[1] = calcAmbientOcclusion(pos, norm); -	frag_color[2] = 1.0;  -	frag_color[3] = 1.0; +	frag_color.r = 1.0; +	frag_color.g = calcAmbientOcclusion(pos, norm, pos_screen); +	frag_color.b = 1.0;  +	frag_color.a = 1.0;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl index db1eab23fb..e95a688e1f 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl @@ -58,9 +58,6 @@ VARYING vec4 refCoord;  VARYING vec4 littleWave;  VARYING vec4 view; -vec3 srgb_to_linear(vec3 cs); -vec3 linear_to_srgb(vec3 cl); -  vec2 encode_normal(vec3 n);  vec4 applyWaterFog(vec4 color, vec3 viewVec) diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl index 69543b93ea..9da2548586 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl @@ -62,7 +62,6 @@ VARYING vec4 littleWave;  VARYING vec4 view;  VARYING vec4 vary_position; -vec3 srgb_to_linear(vec3 cs);  vec2 encode_normal(vec3 n);  vec3 scaleSoftClipFrag(vec3 l); diff --git a/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl b/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl index f98b3a5edf..4a8b892c3a 100644 --- a/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl @@ -64,3 +64,21 @@ vec3 ColorFromRadiance(vec3 radiance)  {      return vec3(1.0) - exp(-radiance * 0.0001);  } + +vec3 rgb2hsv(vec3 c) +{ +    vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); +    vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); +    vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + +    float d = q.x - min(q.w, q.y); +    float e = 1.0e-10; +    return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +vec3 hsv2rgb(vec3 c) +{ +    vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); +    vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); +    return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl index 8b7c4f2ecf..4f0e2a6cb6 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl @@ -1,5 +1,5 @@  /**  - * @file atmosphericsF.glsl + * @file class1\windlight\atmosphericsF.glsl   *   * $LicenseInfo:firstyear=2005&license=viewerlgpl$   * Second Life Viewer Source Code diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl index 864ba4859d..1c5d3901f5 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl @@ -71,19 +71,11 @@ uniform vec2 screen_res;  uniform mat4 inv_proj; -vec3 srgb_to_linear(vec3 cs); -vec3 linear_to_srgb(vec3 cl);  vec3 decode_normal (vec2 enc); -vec4 correctWithGamma(vec4 col) -{ -	return vec4(srgb_to_linear(col.rgb), col.a); -} -  vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); -	ret.rgb = srgb_to_linear(ret.rgb);  	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); @@ -103,7 +95,6 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)  vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); -	ret = correctWithGamma(ret);  	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); @@ -121,7 +112,6 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)  vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); -	ret = correctWithGamma(ret);  	vec2 dist = tc-vec2(0.5); @@ -132,19 +122,7 @@ vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)  	return ret;  } - -vec4 getPosition(vec2 pos_screen) -{ -	float depth = texture2DRect(depthMap, pos_screen.xy).r; -	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; -} +vec4 getPosition(vec2 pos_screen);  void main()   { diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl index 184ac13b27..1b0a1b5d84 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -74,8 +74,6 @@ VARYING vec2 vary_fragcoord;  uniform mat4 inv_proj;  uniform vec2 screen_res; -vec3 srgb_to_linear(vec3 cs); -vec3 linear_to_srgb(vec3 cl);  vec3 decode_normal (vec2 enc);  void calcFragAtmospherics(vec3 inPositionEye, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten); @@ -87,24 +85,8 @@ vec3 atmosTransportFrag(vec3 light, vec3 additive, vec3 atten);  vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten);  vec3 fullbrightShinyAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten); -vec4 getPosition_d(vec2 pos_screen, float depth) -{ -    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; -} - -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).r; -    return getPosition_d(pos_screen, depth); -} - +vec4 getPositionWithDepth(vec2 pos_screen, float depth); +vec4 getPosition(vec2 pos_screen);  #ifdef WATER_FOG  vec4 applyWaterFogView(vec3 pos, vec4 color); @@ -112,32 +94,29 @@ vec4 applyWaterFogView(vec3 pos, vec4 color);  void main()   { -    vec2 tc = vary_fragcoord.xy; -    float depth = texture2DRect(depthMap, tc.xy).r; -    vec3 pos = getPosition_d(tc, depth).xyz; -    vec4 norm = texture2DRect(normalMap, tc); -    float envIntensity = norm.z; -    norm.xyz = decode_normal(norm.xy); // unpack norm -         -    float da_sun  = dot(norm.xyz, normalize(sun_dir.xyz)); +	vec2 tc = vary_fragcoord.xy; +	float depth = texture2DRect(depthMap, tc.xy).r; +	vec4 pos = getPositionWithDepth(tc, depth); +	vec4 norm = texture2DRect(normalMap, tc); +	float envIntensity = norm.z; +	norm.xyz = decode_normal(norm.xy); // unpack norm +		 +	float da_sun  = dot(norm.xyz, normalize(sun_dir.xyz));      float da_moon = dot(norm.xyz, normalize(moon_dir.xyz));      float da = max(da_sun, da_moon);            da = clamp(da, 0.0, 1.0); -    da = pow(da, global_gamma); - -    vec4 diffuse = texture2DRect(diffuseRect, tc); - -    //convert to gamma space -	//diffuse.rgb = linear_to_srgb(diffuse.rgb); +	da = pow(da, global_gamma + 0.3); +	vec4 diffuse = texture2DRect(diffuseRect, tc); +	      vec3 col;      float bloom = 0.0;      {          vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);          vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg; -        scol_ambocc = pow(scol_ambocc, vec2(global_gamma)); +        scol_ambocc = pow(scol_ambocc, vec2(global_gamma + 0.3));          float scol = max(scol_ambocc.r, diffuse.a);           float ambocc = scol_ambocc.g; @@ -195,9 +174,6 @@ void main()              col = fogged.rgb;              bloom = fogged.a;          #endif - -        //col = srgb_to_linear(col); -      }      frag_color.rgb = col;      frag_color.a = bloom; diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl index c840d72784..8b8b338f68 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl @@ -36,7 +36,5 @@ void main()  	//transform vertex  	vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);  	gl_Position = pos;  -	 -	  	vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;  } diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl index a7da140b31..36854b0e66 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl @@ -72,18 +72,10 @@ uniform vec2 screen_res;  uniform mat4 inv_proj;  vec3 decode_normal (vec2 enc); -vec3 srgb_to_linear(vec3 cs); -vec3 linear_to_srgb(vec3 cl); - -vec4 correctWithGamma(vec4 col) -{ -	return vec4(srgb_to_linear(col.rgb), col.a); -}  vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); -	ret.rgb = srgb_to_linear(ret.rgb);  	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); @@ -103,7 +95,6 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)  vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); -	ret = correctWithGamma(ret);  	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); @@ -121,7 +112,6 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)  vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); -	ret = correctWithGamma(ret);  	vec2 dist = tc-vec2(0.5); @@ -132,19 +122,7 @@ vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)  	return ret;  } - -vec4 getPosition(vec2 pos_screen) -{ -	float depth = texture2DRect(depthMap, pos_screen.xy).r; -	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; -} +vec4 getPosition(vec2 pos_screen);  void main()   { diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl index f2d04c95fe..5f8f3114a1 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl @@ -68,22 +68,13 @@ uniform float shadow_offset;  uniform float spot_shadow_bias;  uniform float spot_shadow_offset; -vec3 decode_normal (vec2 enc); +vec3 getNorm(vec2 pos_screen); +vec4 getPosition(vec2 pos_screen); -vec4 getPosition(vec2 pos_screen) -{ -	float depth = texture2DRect(depthMap, pos_screen.xy).r; -	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; -} +float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen); +float pcfSpotShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen); -float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen) +float pcfShadowLegacy(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)  {  	stc.xyz /= stc.w;  	stc.z += shadow_bias; @@ -102,7 +93,7 @@ float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)      return shadow*0.2;  } -float pcfSpotShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen) +float pcfSpotShadowLegacy(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)  {  	stc.xyz /= stc.w;  	stc.z += spot_shadow_bias*scl; @@ -128,10 +119,8 @@ void main()  	//try doing an unproject here -	vec4 pos = getPosition(pos_screen); -	 -	vec3 norm = texture2DRect(normalMap, pos_screen).xyz; -	norm = decode_normal(norm.xy); // unpack norm +	vec4 pos  = getPosition(pos_screen);	 +	vec3 norm = getNorm(pos_screen);  	/*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL  	{ @@ -174,7 +163,7 @@ void main()  				float w = 1.0;  				w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; -				shadow += pcfShadow(shadowMap3, lpos, 0.25, pos_screen)*w; +				shadow += pcfShadowLegacy(shadowMap3, lpos, 0.25, pos_screen)*w;  				weight += w;  				shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);  			} @@ -186,7 +175,7 @@ void main()  				float w = 1.0;  				w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;  				w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; -				shadow += pcfShadow(shadowMap2, lpos, 0.5, pos_screen)*w; +				shadow += pcfShadowLegacy(shadowMap2, lpos, 0.5, pos_screen)*w;  				weight += w;  			} @@ -197,7 +186,7 @@ void main()  				float w = 1.0;  				w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;  				w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; -				shadow += pcfShadow(shadowMap1, lpos, 0.75, pos_screen)*w; +				shadow += pcfShadowLegacy(shadowMap1, lpos, 0.75, pos_screen)*w;  				weight += w;  			} @@ -208,7 +197,7 @@ void main()  				float w = 1.0;  				w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; -				shadow += pcfShadow(shadowMap0, lpos, 1.0, pos_screen)*w; +				shadow += pcfShadowLegacy(shadowMap0, lpos, 1.0, pos_screen)*w;  				weight += w;  			} @@ -242,11 +231,11 @@ void main()  	//spotlight shadow 1  	vec4 lpos = shadow_matrix[4]*spos; -	frag_color[2] = pcfSpotShadow(shadowMap4, lpos, 0.8, pos_screen);  +	frag_color[2] = pcfSpotShadowLegacy(shadowMap4, lpos, 0.8, pos_screen);   	//spotlight shadow 2  	lpos = shadow_matrix[5]*spos; -	frag_color[3] = pcfSpotShadow(shadowMap5, lpos, 0.8, pos_screen);  +	frag_color[3] = pcfSpotShadowLegacy(shadowMap5, lpos, 0.8, pos_screen);   	//frag_color.rgb = pos.xyz;  	//frag_color.b = shadow; diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl index fd3256e9c8..10ef1785da 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl @@ -1,5 +1,5 @@  /**  - * @file sunLightSSAOF.glsl + * @file class2/deferred/sunLightSSAOF.glsl   * $LicenseInfo:firstyear=2007&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2007, Linden Research, Inc. @@ -42,110 +42,33 @@ uniform sampler2DShadow shadowMap2;  uniform sampler2DShadow shadowMap3;  uniform sampler2DShadow shadowMap4;  uniform sampler2DShadow shadowMap5; -uniform sampler2D noiseMap; - - -// Inputs -uniform mat4 shadow_matrix[6]; -uniform vec4 shadow_clip; -uniform float ssao_radius; -uniform float ssao_max_radius; -uniform float ssao_factor; -uniform float ssao_factor_inv;  VARYING vec2 vary_fragcoord;  uniform mat4 inv_proj;  uniform vec2 screen_res;  uniform vec2 proj_shadow_res; -uniform vec3 sun_dir; -uniform vec3 moon_dir; +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip;  uniform vec2 shadow_res; -  uniform float shadow_bias;  uniform float shadow_offset; -  uniform float spot_shadow_bias;  uniform float spot_shadow_offset; -vec3 decode_normal (vec2 enc); - -vec4 getPosition(vec2 pos_screen) -{ -	float depth = texture2DRect(depthMap, pos_screen.xy).r; -	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; -} - -vec2 getKern(int i) -{ -	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; -        -	return kern[i]; -} +uniform vec3 sun_dir; +uniform vec3 moon_dir; -//calculate decreases in ambient lighting when crowded out (SSAO) -float calcAmbientOcclusion(vec4 pos, vec3 norm) -{ -	float ret = 1.0; +vec4 getPosition(vec2 pos_screen); +vec3 getNorm(vec2 pos_screen); -	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; -	float 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(getKern(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) -		 -		float funky_val = (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) ? 1.0 : 0.0; -		angle_hidden = angle_hidden + funky_val * min(1.0/dist2, ssao_factor_inv); -			 -		// 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion"  -		float diffz_val = (diff.z > -1.0) ? 1.0 : 0.0; -		points = points + diffz_val; -	} -		 -	angle_hidden = min(ssao_factor*angle_hidden/points, 1.0); -	 -	float points_val = (points > 0.0) ? 1.0 : 0.0; -	ret = (1.0 - (points_val * angle_hidden)); +float calcAmbientOcclusion(vec4 pos, vec3 norm, vec2 pos_screen); +float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen); +float pcfSpotShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen); -	ret = max(ret, 0.0); -	return min(ret, 1.0); -} -float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen) +float pcfShadowLegacy(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)  {  	stc.xyz /= stc.w;  	stc.z += shadow_bias; @@ -163,7 +86,7 @@ float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)          return shadow*0.2;  } -float pcfSpotShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen) +float pcfSpotShadowLegacy(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)  {  	stc.xyz /= stc.w;  	stc.z += spot_shadow_bias*scl; @@ -189,10 +112,8 @@ void main()  	//try doing an unproject here -	vec4 pos = getPosition(pos_screen); -	 -	vec3 norm = texture2DRect(normalMap, pos_screen).xyz; -	norm = decode_normal(norm.xy); // unpack norm +	vec4 pos  = getPosition(pos_screen); +	vec3 norm = getNorm(pos_screen);  	/*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL  	{ @@ -235,7 +156,7 @@ void main()  				float w = 1.0;  				w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; -				shadow += pcfShadow(shadowMap3, lpos, 0.25, pos_screen)*w; +				shadow += pcfShadowLegacy(shadowMap3, lpos, 0.25, pos_screen)*w;  				weight += w;  				shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);  			} @@ -247,7 +168,7 @@ void main()  				float w = 1.0;  				w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;  				w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; -				shadow += pcfShadow(shadowMap2, lpos, 0.5, pos_screen)*w; +				shadow += pcfShadowLegacy(shadowMap2, lpos, 0.5, pos_screen)*w;  				weight += w;  			} @@ -258,7 +179,7 @@ void main()  				float w = 1.0;  				w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;  				w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; -				shadow += pcfShadow(shadowMap1, lpos, 0.75, pos_screen)*w; +				shadow += pcfShadowLegacy(shadowMap1, lpos, 0.75, pos_screen)*w;  				weight += w;  			} @@ -269,7 +190,7 @@ void main()  				float w = 1.0;  				w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; -				shadow += pcfShadow(shadowMap0, lpos, 1.0, pos_screen)*w; +				shadow += pcfShadowLegacy(shadowMap0, lpos, 1.0, pos_screen)*w;  				weight += w;  			} @@ -297,7 +218,7 @@ void main()  	}  	frag_color[0] = shadow; -	frag_color[1] = calcAmbientOcclusion(pos, norm); +	frag_color[1] = calcAmbientOcclusion(pos, norm, pos_screen);  	spos = vec4(shadow_pos+norm*spot_shadow_offset, 1.0); diff --git a/indra/newview/app_settings/shaders/class3/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class3/deferred/deferredUtil.glsl new file mode 100644 index 0000000000..cccd01e0d7 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/deferredUtil.glsl @@ -0,0 +1,75 @@ +/**  + * @file class3/deferred/deferredUtil.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +uniform sampler2DRect   normalMap; +uniform sampler2DRect   depthMap; + +uniform mat4 inv_proj; +uniform vec2 screen_res; + +vec3 decode_normal(vec2 enc); + +vec2 getScreenCoordinate(vec2 screenpos) +{ +    vec2 sc = screenpos.xy * 2.0; +    if (screen_res.x > 0 && screen_res.y > 0) +    { +       sc /= screen_res; +    } +    return sc - vec2(1.0, 1.0); +} + +vec3 getNorm(vec2 screenpos) +{ +   vec2 enc_norm = texture2DRect(normalMap, screenpos.xy).xy; +   return decode_normal(enc_norm); +} + +float getDepth(vec2 pos_screen) +{ +    float depth = texture2DRect(depthMap, pos_screen).r; +    return depth; +} + +vec4 getPosition(vec2 pos_screen) +{ +    float depth = getDepth(pos_screen); +    vec2 sc = getScreenCoordinate(pos_screen); +    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; +} + +vec4 getPositionWithDepth(vec2 pos_screen, float depth) +{ +    vec2 sc = getScreenCoordinate(pos_screen); +    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; +} diff --git a/indra/newview/app_settings/shaders/class3/deferred/depthToShadowVolumeG.glsl b/indra/newview/app_settings/shaders/class3/deferred/depthToShadowVolumeG.glsl new file mode 100644 index 0000000000..5734e2abb2 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/depthToShadowVolumeG.glsl @@ -0,0 +1,202 @@ +/** 
 + * @file depthToShadowVolumeG.glsl
 + *
 + * $LicenseInfo:firstyear=2011&license=viewerlgpl$
 + * Second Life Viewer Source Code
 + * Copyright (C) 2011, Linden Research, Inc.
 + * 
 + * This library is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU Lesser General Public
 + * License as published by the Free Software Foundation;
 + * version 2.1 of the License only.
 + * 
 + * This library is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 + * Lesser General Public License for more details.
 + * 
 + * You should have received a copy of the GNU Lesser General Public
 + * License along with this library; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 + * 
 + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 + * $/LicenseInfo$
 + */
 +#extension GL_ARB_geometry_shader4  : enable
 +#extension GL_ARB_texture_rectangle : enable
 +
 +/*[EXTRA_CODE_HERE]*/
 +
 +layout (triangles) in;
 +layout (triangle_strip, max_vertices = 128) out;
 +
 +uniform sampler2DRect depthMap;
 +uniform mat4 shadowMatrix[6]; 
 +uniform vec4 lightpos;
 +
 +VARYING vec2 vary_texcoord0;
 +
 +out vec3 to_vec;
 +
 +void cross_products(out vec4 ns[3], int a, int b, int c)
 +{
 +   ns[0] = cross(gl_PositionIn[b].xyz - gl_PositionIn[a].xyz, gl_PositionIn[c].xyz - gl_PositionIn[a].xyz);
 +   ns[1] = cross(gl_PositionIn[c].xyz - gl_PositionIn[b].xyz, gl_PositionIn[a].xyz - gl_PositionIn[b].xyz);
 +   ns[2] = cross(gl_PositionIn[a].xyz - gl_PositionIn[c].xyz, gl_PositionIn[b].xyz - gl_PositionIn[c].xyz);
 +}
 +
 +vec3 getLightDirection(vec4 lightpos, vec3 pos)
 +{
 +
 +    vec3 lightdir = lightpos.xyz - lightpos.w * pos;
 +    return lightdir;
 +}
 +
 +void emitTri(vec4 v[3])
 +{
 +    gl_Position = proj_matrix * v[0];
 +    EmitVertex();
 +
 +    gl_Position = proj_matrix * v[1];
 +    EmitVertex();
 +
 +    gl_Position = proj_matrix * v[2];
 +    EmitVertex();
 +
 +    EndPrimitive();
 +}
 +
 +void emitQuad(vec4 v[4]
 +{
 +    // Emit a quad as a triangle strip.
 +    gl_Position = proj_matrix*v[0];
 +    EmitVertex();
 +
 +    gl_Position = proj_matrix*v[1];
 +    EmitVertex();
 +
 +    gl_Position = proj_matrix*v[2];
 +    EmitVertex();
 +
 +    gl_Position = proj_matrix*v[3];
 +    EmitVertex(); 
 +
 +    EndPrimitive();
 +}
 +
 +void emitPrimitives(int layer)
 +{
 +    int i = layer;
 +    gl_Layer = i;
 +
 +    vec4 depth1 = vec4(texture2DRect(depthMap, tc0).rg, texture2DRect(depthMap, tc1).rg));
 +    vec3 depth2 = vec4(texture2DRect(depthMap, tc2).rg, texture2DRect(depthMap, tc3).rg));
 +    vec3 depth3 = vec4(texture2DRect(depthMap, tc4).rg, texture2DRect(depthMap, tc5).rg));
 +    vec3 depth4 = vec4(texture2DRect(depthMap, tc6).rg, texture2DRect(depthMap, tc7).rg));
 +
 +    depth1 = min(depth1, depth2);
 +    depth1 = min(depth1, depth3);
 +    depth1 = min(depth1, depth4);
 +
 +    vec2 depth = min(depth1.xy, depth1.zw);
 +
 +    int side = sqrt(gl_VerticesIn);
 +
 +    for (int j = 0; j < side; j++)
 +    {
 +        for (int k = 0; k < side; ++k)
 +        {
 +            vec3 pos = gl_PositionIn[(j * side) + k].xyz;
 +            vec4 v = shadowMatrix[i] * vec4(pos, 1.0);
 +            gl_Position = v;
 +            to_vec = pos - light_position.xyz * depth;
 +            EmitVertex();
 +        }
 +
 +        EndPrimitive();
 +    }
 +
 +    vec3 norms[3]; // Normals
 +    vec3 lightdir3]; // Directions toward light
 +
 +    vec4 v[4]; // Temporary vertices
 +
 +    vec4 or_pos[3] =
 +    {  // Triangle oriented toward light source
 +        gl_PositionIn[0],
 +        gl_PositionIn[2],
 +        gl_PositionIn[4]
 +    };
 +
 +    // Compute normal at each vertex.
 +    cross_products(n, 0, 2, 4);
 +
 +    // Compute direction from vertices to light.
 +    lightdir[0] = getLightDirection(lightpos, gl_PositionIn[0].xyz);
 +    lightdir[1] = getLightDirection(lightpos, gl_PositionIn[2].xyz);
 +    lightdir[2] = getLightDirection(lightpos, gl_PositionIn[4].xyz);
 +
 +    // Check if the main triangle faces the light.
 +    bool faces_light = true;
 +    if (!(dot(ns[0],d[0]) > 0
 +         |dot(ns[1],d[1]) > 0
 +         |dot(ns[2],d[2]) > 0))
 +    {
 +        // Flip vertex winding order in or_pos.
 +        or_pos[1] = gl_PositionIn[4];
 +        or_pos[2] = gl_PositionIn[2];
 +        faces_light = false;
 +    }
 +
 +    // Near cap: simply render triangle.
 +    emitTri(or_pos);
 +
 +    // Far cap: extrude positions to infinity.
 +    v[0] =vec4(lightpos.w * or_pos[0].xyz - lightpos.xyz,0);
 +    v[1] =vec4(lightpos.w * or_pos[2].xyz - lightpos.xyz,0);
 +    v[2] =vec4(lightpos.w * or_pos[1].xyz - lightpos.xyz,0);
 +
 +    emitTri(v);
 +
 +    // Loop over all edges and extrude if needed.
 +    for ( int i=0; i<3; i++ ) 
 +    {
 +       // Compute indices of neighbor triangle.
 +       int v0 = i*2;
 +       int nb = (i*2+1);
 +       int v1 = (i*2+2) % 6;
 +       cross_products(n, v0, nb, v1);
 +
 +       // Compute direction to light, again as above.
 +       d[0] =lightpos.xyz-lightpos.w*gl_PositionIn[v0].xyz;
 +       d[1] =lightpos.xyz-lightpos.w*gl_PositionIn[nb].xyz;
 +       d[2] =lightpos.xyz-lightpos.w*gl_PositionIn[v1].xyz;
 +
 +       bool is_parallel = gl_PositionIn[nb].w < 1e-5;
 +
 +       // Extrude the edge if it does not have a
 +       // neighbor, or if it's a possible silhouette.
 +       if (is_parallel ||
 +          ( faces_light != (dot(ns[0],d[0])>0 ||
 +                            dot(ns[1],d[1])>0 ||
 +                            dot(ns[2],d[2])>0) ))
 +       {
 +           // Make sure sides are oriented correctly.
 +           int i0 = faces_light ? v0 : v1;
 +           int i1 = faces_light ? v1 : v0;
 +
 +           v[0] = gl_PositionIn[i0];
 +           v[1] = vec4(lightpos.w*gl_PositionIn[i0].xyz - lightpos.xyz, 0);
 +           v[2] = gl_PositionIn[i1];
 +           v[3] = vec4(lightpos.w*gl_PositionIn[i1].xyz - lightpos.xyz, 0);
 +
 +           emitQuad(v);
 +       }
 +    }
 +}
 +
 +void main()
 +{
 +    // Output
 +    emitPrimitives(0);
 +}
 diff --git a/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShF.glsl b/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShF.glsl new file mode 100644 index 0000000000..34d26cddea --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShF.glsl @@ -0,0 +1,70 @@ +/**  + * @file class3/deferred/gatherSkyShF.glsl + * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2005, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ +  +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_data[3]; +#else +#define frag_data gl_FragData +#endif + +VARYING vec2 vary_frag; + +uniform vec2 screen_res; +uniform sampler2D sh_input_r; +uniform sampler2D sh_input_g; +uniform sampler2D sh_input_b; + +void main() +{ +    vec2 offset	  = vec2(2.0) / screen_res; + +    vec4 r = vec4(0); +    vec4 g = vec4(0); +    vec4 b = vec4(0); + +    vec2 tc = vary_frag * 2.0; + +	r += texture2D(sh_input_r, tc + vec2(0,        0)); +	r += texture2D(sh_input_r, tc + vec2(offset.x, 0)); +	r += texture2D(sh_input_r, tc + vec2(0,        offset.y)); +	r += texture2D(sh_input_r, tc + vec2(offset.x, offset.y)); +    r /= 4.0f; + +	g += texture2D(sh_input_g, tc + vec2(0,        0)); +	g += texture2D(sh_input_g, tc + vec2(offset.x, 0)); +	g += texture2D(sh_input_g, tc + vec2(0,        offset.y)); +	g += texture2D(sh_input_g, tc + vec2(offset.x, offset.y)); +    g /= 4.0f; + +	b += texture2D(sh_input_b, tc + vec2(0,        0)); +	b += texture2D(sh_input_b, tc + vec2(offset.x, 0)); +	b += texture2D(sh_input_b, tc + vec2(0,        offset.y)); +	b += texture2D(sh_input_b, tc + vec2(offset.x, offset.y)); +    b /= 4.0f; + +    frag_data[0] = r; +    frag_data[1] = g; +    frag_data[2] = b; +} diff --git a/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShV.glsl b/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShV.glsl new file mode 100644 index 0000000000..337c8a50fe --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShV.glsl @@ -0,0 +1,40 @@ +/**  + * @file gatherSkyShV.glsl + * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2005, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ +  +ATTRIBUTE vec3 position; +ATTRIBUTE vec2 texcoord0; + +VARYING vec2 vary_frag; +uniform vec2 screen_res; + +void main() +{ +    // pass through untransformed fullscreen pos +    float oo_divisor = screen_res.x / 64.0; +    vec3 pos = (position.xyz * oo_divisor) + vec3(oo_divisor - 1, oo_divisor - 1, 0); +	gl_Position = vec4(pos.xyz, 1.0); +    vary_frag = texcoord0 * oo_divisor; +} + diff --git a/indra/newview/app_settings/shaders/class3/deferred/genSkyShF.glsl b/indra/newview/app_settings/shaders/class3/deferred/genSkyShF.glsl new file mode 100644 index 0000000000..c02e6d1e57 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/genSkyShF.glsl @@ -0,0 +1,112 @@ +/**  + * @file class3/deferred/genSkyShF.glsl + * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2005, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ +  +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_data[3]; +#else +#define frag_data gl_FragData +#endif + +VARYING vec2 vary_frag; + +uniform vec3 sun_dir; + +uniform sampler2D transmittance_texture; +uniform sampler3D scattering_texture; +uniform sampler3D single_mie_scattering_texture; +uniform sampler2D irradiance_texture; +uniform vec4 gamma; + +vec3 GetSkyLuminance(vec3 camPos, vec3 view_dir, float shadow_length, vec3 dir, out vec3 transmittance); + +vec3 calcDirection(vec2 tc) +{ +     float phi = tc.y * 2.0 * 3.14159265; +     float cosTheta = sqrt(1.0 - tc.x); +     float sinTheta = sqrt(1.0 - cosTheta * cosTheta); +     return vec3(cos(phi) * sinTheta, sin(phi) * sinTheta, cosTheta); +} + +// reverse mapping above to convert a hemisphere direction into phi/theta values +void getPhiAndThetaFromDirection(vec3 dir, out float phi, out float theta) +{ +     float sin_theta; +     float cos_theta; +     cos_theta = dir.z; +     theta     = acos(cos_theta); +     sin_theta = sin(theta); +     phi       = abs(sin_theta) > 0.0001 ? acos(dir.x / sin_theta) : 1.0; +} + +// reverse mapping above to convert a hemisphere direction into an SH texture sample pos +vec2 calcShUvFromDirection(vec3 dir) +{ +    vec2 uv; +    float phi; +    float theta; +    getPhiAndThetaFromDirection(dir, phi, theta); +    uv.y = phi   / 2.0 * 3.14159265; +    uv.x = theta / 2.0 * 3.14159265; +    return uv; +} + +void projectToL1(vec3 n, vec3 c, vec4 basis, out vec4 coeffs[3]) +{ +    coeffs[0] = vec4(basis.x, n * basis.yzw * c.r); +    coeffs[1] = vec4(basis.x, n * basis.yzw * c.g); +    coeffs[2] = vec4(basis.x, n * basis.yzw * c.b); +} + +void main() +{ +    float Y00 = sqrt(1.0 / 3.14159265) * 0.5; +    float Y1x = sqrt(3.0 / 3.14159265) * 0.5; +    float Y1y = Y1x; +    float Y1z = Y1x; + +    vec4 L1 = vec4(Y00, Y1x, Y1y, Y1z); + +    vec3 view_direction = calcDirection(vary_frag); +    vec3 sun_direction  = normalize(sun_dir); +    vec3 cam_pos        = vec3(0, 0, 6360); + +    vec3 transmittance; +    vec3 radiance = GetSkyLuminance(cam_pos, view_direction, 0.0f, sun_direction, transmittance); + +    vec3 color = vec3(1.0) - exp(-radiance * 0.0001); + +    color = pow(color, vec3(1.0/2.2)); + +    vec4 coeffs[3]; +    coeffs[0] = vec4(0); +    coeffs[1] = vec4(0); +    coeffs[2] = vec4(0); + +    projectToL1(view_direction, color.rgb, L1, coeffs); + +    frag_data[0] = coeffs[0]; +    frag_data[1] = coeffs[1]; +    frag_data[2] = coeffs[2]; +} diff --git a/indra/newview/app_settings/shaders/class3/deferred/genSkyShV.glsl b/indra/newview/app_settings/shaders/class3/deferred/genSkyShV.glsl new file mode 100644 index 0000000000..b466883dc7 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/genSkyShV.glsl @@ -0,0 +1,37 @@ +/**  + * @file genSkyShV.glsl + * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2005, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ +  +ATTRIBUTE vec3 position; +ATTRIBUTE vec2 texcoord0; + +VARYING vec2 vary_frag; + +void main() +{ +    // pass through untransformed fullscreen pos +	gl_Position = vec4(position.xyz, 1.0); +    vary_frag = texcoord0; +} + diff --git a/indra/newview/app_settings/shaders/class3/deferred/indirect.glsl b/indra/newview/app_settings/shaders/class3/deferred/indirect.glsl new file mode 100644 index 0000000000..33c5667cae --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/indirect.glsl @@ -0,0 +1,44 @@ +/**  + * @file class3/deferred/indirect.glsl + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +/*[EXTRA_CODE_HERE]*/ + +uniform sampler2D sh_input_r; +uniform sampler2D sh_input_g; +uniform sampler2D sh_input_b; + +vec3 GetIndirect(vec3 norm) +{ +    vec4 l1tap = vec4(1.0/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265)); +    vec4 l1r = texture2D(sh_input_r, vec2(0,0)); +    vec4 l1g = texture2D(sh_input_g, vec2(0,0)); +    vec4 l1b = texture2D(sh_input_b, vec2(0,0)); +    vec3 indirect = vec3(dot(l1r, l1tap * vec4(1, norm.xyz)), +                         dot(l1g, l1tap * vec4(1, norm.xyz)), +                         dot(l1b, l1tap * vec4(1, norm.xyz))); +    indirect = clamp(indirect, vec3(0), vec3(1.0)); +    return indirect; +} + diff --git a/indra/newview/app_settings/shaders/class3/deferred/lightUtil.glsl b/indra/newview/app_settings/shaders/class3/deferred/lightUtil.glsl new file mode 100644 index 0000000000..8bb3f07fc6 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/lightUtil.glsl @@ -0,0 +1,117 @@ +/**  + * @file lightInfo.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +struct DirectionalLightInfo +{ +    vec4 pos; +    float depth; +    vec4 normal; +    vec3 normalizedLightDirection; +    vec3 normalizedToLight; +    float lightIntensity; +    vec3 lightDiffuseColor; +    float specExponent; +    float shadow; +}; + +struct SpotLightInfo +{ +    vec4 pos; +    float depth; +    vec4 normal; +    vec3 normalizedLightDirection; +    vec3 normalizedToLight; +    float lightIntensity; +    float attenuation; +    float distanceToLight; +    vec3 lightDiffuseColor; +    float innerHalfAngleCos; +    float outerHalfAngleCos; +    float spotExponent; +    float specExponent; +    float shadow; +}; + +struct PointLightInfo +{ +    vec4 pos; +    float depth; +    vec4 normal; +    vec3 normalizedToLight; +    float lightIntensity; +    float attenuation; +    float distanceToLight; +    vec3 lightDiffuseColor; +    float lightRadius; +    float specExponent; +    vec3 worldspaceLightDirection; +    float shadow; +}; + +float attenuate(float attenuationSelection, float distanceToLight) +{ +// LLRENDER_REVIEW +// sh/could eventually consume attenuation func defined in texture +    return (attenuationSelection == 0.0f) ? 1.0f : // none +           (attenuationSelection <  1.0f) ? (1.0f / distanceToLight) : // linear atten  +           (attenuationSelection <  2.0f) ? (1.0f / (distanceToLight*distanceToLight)) // quadratic atten +										  : (1.0f / (distanceToLight*distanceToLight*distanceToLight));	// cubic atten     +} + + +vec3 lightDirectional(struct DirectionalLightInfo dli) +{ +    float lightIntensity = dli.lightIntensity; +	lightIntensity *= dot(dli.normal.xyz, dli.normalizedLightDirection); +    //lightIntensity *= directionalShadowSample(vec4(dli.pos.xyz, 1.0f), dli.depth, dli.directionalShadowMap, dli.directionalShadowMatrix); +	return lightIntensity * dli.lightDiffuseColor; +} + + +vec3 lightSpot(struct SpotLightInfo sli)     +{ +	float penumbraRange = (sli.outerHalfAngleCos - sli.innerHalfAngleCos); +    float coneAngleCos = max(dot(sli.normalizedLightDirection, sli.normalizedToLight), 0.0); +	float coneAttenFactor = (coneAngleCos <= sli.outerHalfAngleCos) ? 1.0f : pow(smoothstep(1,0, sli.outerHalfAngleCos / penumbraRange), sli.spotExponent); +    float distanceAttenuation = attenuate(sli.attenuation, sli.distanceToLight); +    float lightIntensity = sli.lightIntensity; +    lightIntensity *= distanceAttenuation; +	lightIntensity *= max(dot(sli.normal.xyz, sli.normalizedLightDirection), 0.0); +	lightIntensity *= coneAttenFactor; +    lightIntensity *= sli.shadow; +	return lightIntensity * sli.lightDiffuseColor; +} + +vec3 lightPoint(struct PointLightInfo pli) +{ +    float padRadius = pli.lightRadius * 0.1; // distance for which to perform smoothed dropoff past light radius +	float distanceAttenuation =	attenuate(pli.attenuation, pli.distanceToLight); +    float lightIntensity = pli.lightIntensity; +    lightIntensity*= distanceAttenuation;     +	lightIntensity *= clamp((padRadius - pli.distanceToLight + pli.lightRadius) / padRadius, 0.0, 1.0); +    lightIntensity *= pli.shadow; +    lightIntensity *= max(dot(pli.normal.xyz, pli.normalizedToLight), 0.0); +	return lightIntensity * pli.lightDiffuseColor; +} diff --git a/indra/newview/app_settings/shaders/class3/deferred/pointShadowBlurF.glsl b/indra/newview/app_settings/shaders/class3/deferred/pointShadowBlurF.glsl new file mode 100644 index 0000000000..ca9ce3a2e1 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/pointShadowBlurF.glsl @@ -0,0 +1,37 @@ +/**  + * @file pointShadowBlur.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +uniform samplerCube cube_map;  + +in vec3 to_vec; + +out vec4 fragColor; + +void main()  +{ +	vec4 vcol = texture(cube_map, to_vec); +	fragColor = vec4(vcol.rgb, 1.0); +} + diff --git a/indra/newview/app_settings/shaders/class3/deferred/shVisF.glsl b/indra/newview/app_settings/shaders/class3/deferred/shVisF.glsl new file mode 100644 index 0000000000..c8991f7a18 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/shVisF.glsl @@ -0,0 +1,73 @@ +/**  + * @file class3/deferred/shVisF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifdef DEFINE_GL_FRAGCOLOR +    out vec4 frag_color; +#else +    #define frag_color gl_FragColor +#endif + +///////////////////////////////////////////////////////////////////////// +// Fragment shader for L1 SH debug rendering +///////////////////////////////////////////////////////////////////////// + +uniform sampler2D sh_input_r; +uniform sampler2D sh_input_g; +uniform sampler2D sh_input_b; + +uniform mat3 inv_modelviewprojection; + +VARYING vec4 vary_pos; + +void main(void)  +{ +    vec2 coord = vary_pos.xy + vec2(0.5,0.5); + +    coord.x *= (1.6/0.9); + +    if (dot(coord, coord) > 0.25) +    { +        discard; +    } + +    vec4 n = vec4(coord*2.0, 0.0, 1); +    //n.y = -n.y; +    n.z = sqrt(max(1.0-n.x*n.x-n.y*n.y, 0.0)); +    //n.xyz = inv_modelviewprojection * n.xyz; + +    vec4 l1tap = vec4(1.0/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265)); +    vec4 l1r = texture2D(sh_input_r, vec2(0,0)); +    vec4 l1g = texture2D(sh_input_g, vec2(0,0)); +    vec4 l1b = texture2D(sh_input_b, vec2(0,0)); +    vec3 indirect = vec3( +                      dot(l1r, l1tap * n), +                      dot(l1g, l1tap * n), +                      dot(l1b, l1tap * n)); + +    //indirect = pow(indirect, vec3(0.45)); +    indirect *= 3.0; + +	frag_color = vec4(indirect, 1.0); +} diff --git a/indra/newview/app_settings/shaders/class3/deferred/shVisV.glsl b/indra/newview/app_settings/shaders/class3/deferred/shVisV.glsl new file mode 100644 index 0000000000..8f32dfde79 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/shVisV.glsl @@ -0,0 +1,33 @@ +/**  + * @file class3/deferred/shVisV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ +ATTRIBUTE vec3 position; +VARYING vec4 vary_pos; + +void main() +{ +    // Output +    vary_pos = vec4(position, 1); +    gl_Position = vary_pos; +} diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendF.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendF.glsl new file mode 100644 index 0000000000..01599d81c4 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendF.glsl @@ -0,0 +1,58 @@ +/**  + * @file shadowAlphaMaskF.glsl + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +/*[EXTRA_CODE_HERE]*/ + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif + +uniform sampler2D diffuseMap; + +#if !DEPTH_CLAMP +VARYING float pos_zd2; +#endif + +VARYING float pos_w; + +VARYING float target_pos_x; +VARYING vec4 vertex_color; +VARYING vec2 vary_texcoord0; +VARYING vec3 pos; + +vec4 computeMoments(float depth, float a); + +void main()  +{ +	float alpha = diffuseLookup(vary_texcoord0.xy).a * vertex_color.a; + +    frag_color = computeMoments(length(pos), float a); + +#if !DEPTH_CLAMP +	gl_FragDepth = max(pos_zd2/pos_w+0.5, 0.0); +#endif +} diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendV.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendV.glsl new file mode 100644 index 0000000000..3fb2bafca4 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendV.glsl @@ -0,0 +1,66 @@ +/**  + * @file shadowAlphaMaskV.glsl + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +uniform mat4 texture_matrix0; +uniform mat4 modelview_projection_matrix; +uniform float shadow_target_width; + +ATTRIBUTE vec3 position; +ATTRIBUTE vec4 diffuse_color; +ATTRIBUTE vec2 texcoord0; + +#if !DEPTH_CLAMP +VARYING float pos_zd2; +#endif + +VARYING float target_pos_x; +VARYING vec4 pos; +VARYING vec4 vertex_color; +VARYING vec2 vary_texcoord0; + +void passTextureIndex(); + +void main() +{ +	//transform vertex +	vec4 pre_pos = vec4(position.xyz, 1.0); +	vec4 pos = modelview_projection_matrix * pre_pos; +	target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x; + +	pos_w = pos.w; + +#if !DEPTH_CLAMP +	pos_zd2 = pos.z * 0.5; +	 +	gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); +#else +	gl_Position = pos; +#endif +	 +	passTextureIndex(); + +	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; +	vertex_color = diffuse_color; +} diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskF.glsl new file mode 100644 index 0000000000..d6ed5b6bb0 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskF.glsl @@ -0,0 +1,74 @@ +/**  + * @file class3/deferred/shadowAlphaMaskF.glsl + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +/*[EXTRA_CODE_HERE]*/ + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif + +uniform sampler2D diffuseMap; + +#if !DEPTH_CLAMP +VARYING float pos_zd2; +#endif + +VARYING float pos_w; + +VARYING float target_pos_x; +VARYING vec4 vertex_color; +VARYING vec2 vary_texcoord0; + +vec4 getPosition(vec2 screen_coord); +vec4 computeMoments(float depth, float a); + +void main()  +{ +    vec4 pos = getPosition(vary_texcoord0.xy); + +    float alpha = diffuseLookup(vary_texcoord0.xy).a * vertex_color.a; + +    if (alpha < 0.05) // treat as totally transparent +    { +        discard; +    } + +    if (alpha < 0.88) // treat as semi-transparent +    { +        if (fract(0.5*floor(target_pos_x / pos_w )) < 0.25) +        { +            discard; +        } +    } + +    frag_color = computeMoments(length(pos.xyz), alpha); +     +#if !DEPTH_CLAMP +    gl_FragDepth = max(pos_zd2/pos_w+0.5, 0.0); +#endif + +} diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskV.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskV.glsl new file mode 100644 index 0000000000..bc7fe003f2 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskV.glsl @@ -0,0 +1,67 @@ +/**  + * @file class3/deferred/shadowAlphaMaskV.glsl + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +uniform mat4 texture_matrix0; +uniform mat4 modelview_projection_matrix; +uniform float shadow_target_width; + +ATTRIBUTE vec3 position; +ATTRIBUTE vec4 diffuse_color; +ATTRIBUTE vec2 texcoord0; + +#if !DEPTH_CLAMP +VARYING float pos_zd2; +#endif + +VARYING vec4 pos; +VARYING float target_pos_x; +VARYING vec4 vertex_color; +VARYING vec2 vary_texcoord0; + +void passTextureIndex(); + +void main() +{ +	//transform vertex +	vec4 pre_pos = vec4(position.xyz, 1.0); + +	pos = modelview_projection_matrix * pre_pos; + +	target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x; + +#if !DEPTH_CLAMP +	pos_zd2 = pos.z * 0.5; +	 +	gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); +#else +	gl_Position = pos; +#endif +	 +	passTextureIndex(); + +	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; + +	vertex_color = diffuse_color; +} diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowCubeV.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowCubeV.glsl new file mode 100644 index 0000000000..923de09ada --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/shadowCubeV.glsl @@ -0,0 +1,50 @@ +/**  + * @file class3/deferred/shadowCubeV.glsl + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +uniform mat4 modelview_projection_matrix; + +ATTRIBUTE vec3 position; + +#if !DEPTH_CLAMP +VARYING vec4 post_pos; +#endif + +uniform vec3 box_center; +uniform vec3 box_size; + +void main() +{ +	//transform vertex +	vec3 p = position*box_size+box_center; +	vec4 pos = modelview_projection_matrix*vec4(p.xyz, 1.0); + +#if !DEPTH_CLAMP +	post_pos = pos; + +	gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); +#else +	gl_Position = pos; +#endif +} diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowF.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowF.glsl new file mode 100644 index 0000000000..5a6c8728c0 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/shadowF.glsl @@ -0,0 +1,49 @@ +/**  + * @file class3/deferred/shadowF.glsl + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +/*[EXTRA_CODE_HERE]*/ + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif + +uniform sampler2D diffuseMap; + +#if !DEPTH_CLAMP +VARYING float pos_zd2; +#endif + +VARYING vec4 pos; +VARYING float target_pos_x; + +vec4 computeMoments(float depth, float a); + +void main()  +{ +    frag_color = computeMoments(length(pos), 1.0); +} + diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowUtil.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowUtil.glsl new file mode 100644 index 0000000000..2f69a353e8 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/shadowUtil.glsl @@ -0,0 +1,157 @@ +/**  + * @file class3/deferred/shadowUtil.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +uniform sampler2D       shadowMap0; +uniform sampler2D       shadowMap1; +uniform sampler2D       shadowMap2; +uniform sampler2D       shadowMap3; +uniform sampler2D       shadowMap4; +uniform sampler2D       shadowMap5; + +uniform vec3 sun_dir; +uniform vec3 moon_dir; +uniform vec2 shadow_res; +uniform vec2 proj_shadow_res; +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; +uniform float shadow_bias; + +uniform float spot_shadow_bias; +uniform float spot_shadow_offset; + +float getDepth(vec2 screenpos); +vec3 getNorm(vec2 screenpos); +vec4 getPosition(vec2 pos_screen); + +float ReduceLightBleeding(float p_max, float Amount) +{ +    return smoothstep(Amount, 1, p_max); +} + +float ChebyshevUpperBound(vec2 m, float t, float min_v, float Amount) +{ +    float p = (t <= m.x) ? 1.0 : 0.0; + +    float v = m.y - (m.x*m.x); +    v = max(v, min_v); + +    float d = t - m.x; + +    float p_max = v / (v + d*d); + +    p_max = ReduceLightBleeding(p_max, Amount); + +    return max(p, p_max); +} + +vec4 computeMoments(float depth, float a) +{ +    float m1 = depth; +    float dx = dFdx(depth); +    float dy = dFdy(depth); +    float m2 = m1*m1 + 0.25 * a * (dx*dx + dy*dy); +    return vec4(m1, m2, a, max(dx, dy)); +} + +float vsmDirectionalSample(vec4 stc, float depth, sampler2D shadowMap, mat4 shadowMatrix) +{ +    vec4 lpos = shadowMatrix * stc; +    vec4 moments = texture2D(shadowMap, lpos.xy); +    return ChebyshevUpperBound(moments.rg, depth - shadow_bias * 256.0f, 0.125, 0.9); +} + +float vsmSpotSample(vec4 stc, float depth, sampler2D shadowMap, mat4 shadowMatrix) +{ +    vec4 lpos = shadowMatrix * stc; +    vec4 moments = texture2D(shadowMap, lpos.xy); +    lpos.xyz /= lpos.w; +    lpos.xy *= 0.5; +    lpos.xy += 0.5; +    return ChebyshevUpperBound(moments.rg, depth - spot_shadow_bias * 16.0f, 0.125, 0.9); +} + +#if VSM_POINT_SHADOWS +float vsmPointSample(float lightDistance, vec3 lightDirection, samplerCube shadow_cube_map) +{ +    vec4 moments = textureCube(shadow_cube_map, light_direction); +    return ChebyshevUpperBound(moments.rg, light_distance, 0.01, 0.25); +} +#endif + +float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen) +{ +	if (pos.z < -shadow_clip.w) +    { +        discard; +    } + +    float depth = getDepth(pos_screen); + +    vec4 spos       = vec4(pos,1.0); +    vec4 near_split = shadow_clip*-0.75; +    vec4 far_split  = shadow_clip*-1.25; + +    float shadow = 0.0f; +    float weight = 1.0; + +    if (spos.z < near_split.z) +    { +        shadow += vsmDirectionalSample(spos, depth, shadowMap3, shadow_matrix[3]); +        weight += 1.0f; +    } +    if (spos.z < near_split.y) +    { +        shadow += vsmDirectionalSample(spos, depth, shadowMap2, shadow_matrix[2]); +        weight += 1.0f; +    } +    if (spos.z < near_split.x) +    { +        shadow += vsmDirectionalSample(spos, depth, shadowMap1, shadow_matrix[1]); +        weight += 1.0f; +    } +    if (spos.z > far_split.x) +    { +        shadow += vsmDirectionalSample(spos, depth, shadowMap0, shadow_matrix[0]); +        weight += 1.0f; +    } + +    shadow /= weight; + +    return shadow; +} + +float sampleSpotShadow(vec3 pos, vec3 norm, int index, vec2 pos_screen) +{ +	if (pos.z < -shadow_clip.w) +    { +        discard; +    } + +    float depth = getDepth(pos_screen); + +    pos += norm * spot_shadow_offset; +    return vsmSpotSample(vec4(pos, 1.0), depth, (index == 0) ? shadowMap4 : shadowMap5, shadow_matrix[4 + index]); +} + diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowV.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowV.glsl new file mode 100644 index 0000000000..9a5edaf091 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/shadowV.glsl @@ -0,0 +1,62 @@ +/**  + * @file class3/deferred/shadowV.glsl + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +uniform mat4 modelview_projection_matrix; +uniform float shadow_target_width; +uniform mat4 texture_matrix0; + +ATTRIBUTE vec3 position; +ATTRIBUTE vec2 texcoord0; + +#if !DEPTH_CLAMP +VARYING float pos_zd2; +#endif + +VARYING vec4 pos; +VARYING float target_pos_x; +VARYING vec4 vertex_color; +VARYING vec2 vary_texcoord0; + +void passTextureIndex(); + +void main() +{ +	//transform vertex +	vec4 pre_pos = vec4(position.xyz, 1.0); + +	pos = modelview_projection_matrix * pre_pos; + +	target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x; + +#if !DEPTH_CLAMP +	pos_zd2 = pos.z * 0.5; +	 +	gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); +#else +	gl_Position = pos; +#endif +	 +	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; +} diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index ecf6858136..b84d3efbaa 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -40,15 +40,13 @@ uniform sampler2DRect lightMap;  uniform sampler2DRect depthMap;  uniform sampler2D     lightFunc; -uniform float blur_size;  uniform samplerCube environmentMap; - +uniform float blur_size;  uniform float blur_fidelity;  // Inputs  uniform vec4 morphFactor;  uniform vec3 camPosLocal; -uniform vec4 gamma;  uniform float cloud_shadow;  uniform float max_y;  uniform vec4 glow; diff --git a/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl index 9c050256dc..90ab5d2793 100644 --- a/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl +++ b/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl @@ -61,14 +61,17 @@ vec3 fullbrightShinyAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten)  	return mix(atmosTransportFrag(light.rgb, additive, atten), (light.rgb + additive.rgb) * (2.0 - brightness), brightness * brightness);  } -vec3 atmosTransport(vec3 light) { -     return (no_atmo == 1) ? light : atmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation()); +vec3 atmosTransport(vec3 light) +{ +     return atmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation());  } -vec3 fullbrightAtmosTransport(vec3 light) { -     return (no_atmo == 1) ? light : fullbrightAtmosTransportFrag(light, GetAdditiveColor(), getAtmosAttenuation()); +vec3 fullbrightAtmosTransport(vec3 light) +{ +     return fullbrightAtmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation());  } -vec3 fullbrightShinyAtmosTransport(vec3 light) { -    return (no_atmo == 1) ? light : fullbrightShinyAtmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation()); +vec3 fullbrightShinyAtmosTransport(vec3 light) +{ +    return fullbrightShinyAtmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation());  } diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 82888b2df6..00493c83df 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -127,7 +127,7 @@ LLDrawPool::LLDrawPool(const U32 type)  	mType = type;  	sNumDrawPools++;  	mId = sNumDrawPools; -	mVertexShaderLevel = 0; +	mShaderLevel = 0;  	mSkipRender = false;  } @@ -141,7 +141,7 @@ LLViewerTexture *LLDrawPool::getDebugTexture()  	return NULL;  } -//virtuals +//virtual  void LLDrawPool::beginRenderPass( S32 pass )  {  } diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index bc299cc89f..df86d78a89 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -107,7 +107,7 @@ public:  	virtual void prerender() = 0;  	virtual U32 getVertexDataMask() = 0;  	virtual BOOL verify() const { return TRUE; }		// Verify that all data in the draw pool is correct! -	virtual S32 getVertexShaderLevel() const { return mVertexShaderLevel; } +	virtual S32 getShaderLevel() const { return mShaderLevel; }  	static LLDrawPool* createPool(const U32 type, LLViewerTexture *tex0 = NULL);  	virtual LLDrawPool *instancePool() = 0;	// Create an empty new instance of the pool. @@ -116,7 +116,7 @@ public:  	virtual void resetDrawOrders() = 0;  protected: -	S32 mVertexShaderLevel; +	S32 mShaderLevel;  	S32	mId;  	U32 mType;				// Type of draw pool  	BOOL mSkipRender; diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 7679d44826..73582e2345 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -69,7 +69,7 @@ LLDrawPoolAlpha::~LLDrawPoolAlpha()  void LLDrawPoolAlpha::prerender()  { -	mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); +	mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);  }  S32 LLDrawPoolAlpha::getNumPostDeferredPasses()  @@ -160,7 +160,7 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)      }  	deferred_render = TRUE; -	if (mVertexShaderLevel > 0) +	if (mShaderLevel > 0)  	{  		// Start out with no shaders.  		current_shader = target_shader = NULL; @@ -209,7 +209,7 @@ void LLDrawPoolAlpha::beginRenderPass(S32 pass)  		emissive_shader = &gObjectEmissiveProgram;  	} -	if (mVertexShaderLevel > 0) +	if (mShaderLevel > 0)  	{  		// Start out with no shaders.  		current_shader = target_shader = NULL; @@ -264,7 +264,7 @@ void LLDrawPoolAlpha::render(S32 pass)  		mAlphaDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA;       // }  		gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); -		if (mVertexShaderLevel > 0) +		if (mShaderLevel > 0)  		{  			if (LLPipeline::sImpostorRender)  			{ @@ -326,7 +326,7 @@ void LLDrawPoolAlpha::render(S32 pass)  		}  	} -	if (mVertexShaderLevel > 0) +	if (mShaderLevel > 0)  	{  		renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, pass);  	} @@ -432,7 +432,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)  			bool is_particle_or_hud_particle = group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_PARTICLE  													  || group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE; -			bool draw_glow_for_this_partition = mVertexShaderLevel > 0; // no shaders = no glow. +			bool draw_glow_for_this_partition = mShaderLevel > 0; // no shaders = no glow.  			LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_GROUP_LOOP); diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index d4dc6f3558..996c7eed4b 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -144,16 +144,16 @@ LLDrawPool *LLDrawPoolAvatar::instancePool()  } -S32 LLDrawPoolAvatar::getVertexShaderLevel() const +S32 LLDrawPoolAvatar::getShaderLevel() const  { -	return (S32) LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR); +	return (S32) LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR);  }  void LLDrawPoolAvatar::prerender()  { -	mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR); +	mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR); -	sShaderLevel = mVertexShaderLevel; +	sShaderLevel = mShaderLevel;  	if (sShaderLevel > 0)  	{ @@ -304,7 +304,7 @@ void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass)  void LLDrawPoolAvatar::beginPostDeferredAlpha()  {  	sSkipOpaque = TRUE; -	sShaderLevel = mVertexShaderLevel; +	sShaderLevel = mShaderLevel;  	sVertexProgram = &gDeferredAvatarAlphaProgram;  	sRenderingSkinned = TRUE; @@ -395,7 +395,7 @@ void LLDrawPoolAvatar::endPostDeferredAlpha()  	gPipeline.unbindDeferredShader(*sVertexProgram);  	sDiffuseChannel = 0; -	sShaderLevel = mVertexShaderLevel; +	sShaderLevel = mShaderLevel;  }  void LLDrawPoolAvatar::renderPostDeferred(S32 pass) @@ -493,7 +493,7 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)  	}  	LLVOAvatar *avatarp = (LLVOAvatar *)facep->getDrawable()->getVObj().get(); -	if (avatarp->isDead() || avatarp->isUIAvatar() || avatarp->mDrawable.isNull()) +	if (avatarp->isDead() || avatarp->mIsDummy || avatarp->mDrawable.isNull())  	{  		return;  	} @@ -714,7 +714,7 @@ void LLDrawPoolAvatar::beginRigid()  void LLDrawPoolAvatar::endRigid()  { -	sShaderLevel = mVertexShaderLevel; +	sShaderLevel = mShaderLevel;  	if (sVertexProgram != NULL)  	{  		sVertexProgram->unbind(); @@ -739,7 +739,7 @@ void LLDrawPoolAvatar::beginDeferredImpostor()  void LLDrawPoolAvatar::endDeferredImpostor()  { -	sShaderLevel = mVertexShaderLevel; +	sShaderLevel = mShaderLevel;  	sVertexProgram->disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL);  	sVertexProgram->disableTexture(LLViewerShaderMgr::SPECULAR_MAP);  	sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); @@ -766,7 +766,7 @@ void LLDrawPoolAvatar::beginDeferredRigid()  void LLDrawPoolAvatar::endDeferredRigid()  { -	sShaderLevel = mVertexShaderLevel; +	sShaderLevel = mShaderLevel;  	sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);  	sVertexProgram->unbind();  	gGL.getTexUnit(0)->activate(); @@ -848,7 +848,7 @@ void LLDrawPoolAvatar::endSkinned()  		sVertexProgram->disableTexture(LLViewerShaderMgr::BUMP_MAP);  		gGL.getTexUnit(0)->activate();  		sVertexProgram->unbind(); -		sShaderLevel = mVertexShaderLevel; +		sShaderLevel = mShaderLevel;  	}  	else  	{ @@ -1281,7 +1281,7 @@ void LLDrawPoolAvatar::endDeferredRiggedMaterial(S32 pass)  void LLDrawPoolAvatar::beginDeferredSkinned()  { -	sShaderLevel = mVertexShaderLevel; +	sShaderLevel = mShaderLevel;  	sVertexProgram = &gDeferredAvatarProgram;  	sRenderingSkinned = TRUE; @@ -1308,7 +1308,7 @@ void LLDrawPoolAvatar::endDeferredSkinned()  	sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); -	sShaderLevel = mVertexShaderLevel; +	sShaderLevel = mShaderLevel;  	gGL.getTexUnit(0)->activate();  } @@ -1820,7 +1820,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(  void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)  { -	if (!avatar->shouldRenderRigged()) +	if (avatar->isSelf() && !gAgent.needsRenderAvatar())  	{  		return;  	} @@ -2196,6 +2196,7 @@ void LLDrawPoolAvatar::addRiggedFace(LLFace* facep, U32 type)  	{  		LL_ERRS() << "Invalid rigged face type." << LL_ENDL;  	} +  	if (facep->getRiggedIndex(type) != -1)  	{  		LL_ERRS() << "Tried to add a rigged face that's referenced elsewhere." << LL_ENDL; diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index 45b6d71110..8292279042 100644 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -57,7 +57,7 @@ public:  	virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; } -	virtual S32 getVertexShaderLevel() const; +	virtual S32 getShaderLevel() const;  	LLDrawPoolAvatar();      ~LLDrawPoolAvatar(); diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index e27b6867b9..14069fa6c2 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -193,7 +193,7 @@ LLDrawPoolBump::LLDrawPoolBump()  void LLDrawPoolBump::prerender()  { -	mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); +	mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);  }  // static @@ -201,7 +201,7 @@ S32 LLDrawPoolBump::numBumpPasses()  {  	if (gSavedSettings.getBOOL("RenderObjectBump"))  	{ -		if (mVertexShaderLevel > 1) +		if (mShaderLevel > 1)  		{  			if (LLPipeline::sImpostorRender)  			{ @@ -241,7 +241,7 @@ void LLDrawPoolBump::beginRenderPass(S32 pass)  			beginShiny();  			break;  		case 1: -			if (mVertexShaderLevel > 1) +			if (mShaderLevel > 1)  			{  				beginFullbrightShiny();  			} @@ -274,7 +274,7 @@ void LLDrawPoolBump::render(S32 pass)  			renderShiny();  			break;  		case 1: -			if (mVertexShaderLevel > 1) +			if (mShaderLevel > 1)  			{  				renderFullbrightShiny();  			} @@ -301,7 +301,7 @@ void LLDrawPoolBump::endRenderPass(S32 pass)  			endShiny();  			break;  		case 1: -			if (mVertexShaderLevel > 1) +			if (mShaderLevel > 1)  			{  				endFullbrightShiny();  			} @@ -335,12 +335,12 @@ void LLDrawPoolBump::beginShiny(bool invisible)  	mShiny = TRUE;  	sVertexMask = VERTEX_MASK_SHINY;  	// Second pass: environment map -	if (!invisible && mVertexShaderLevel > 1) +	if (!invisible && mShaderLevel > 1)  	{  		sVertexMask = VERTEX_MASK_SHINY | LLVertexBuffer::MAP_TEXCOORD0;  	} -	if (getVertexShaderLevel() > 0) +	if (getShaderLevel() > 0)  	{  		if (LLPipeline::sUnderWaterRender)  		{ @@ -365,9 +365,9 @@ void LLDrawPoolBump::beginShiny(bool invisible)  		shader = NULL;  	} -	bindCubeMap(shader, mVertexShaderLevel, diffuse_channel, cube_channel, invisible); +	bindCubeMap(shader, mShaderLevel, diffuse_channel, cube_channel, invisible); -	if (mVertexShaderLevel > 1) +	if (mShaderLevel > 1)  	{ //indexed texture rendering, channel 0 is always diffuse  		diffuse_channel = 0;  	} @@ -436,7 +436,7 @@ void LLDrawPoolBump::renderShiny(bool invisible)  	if( gSky.mVOSkyp->getCubeMap() )  	{  		LLGLEnable blend_enable(GL_BLEND); -		if (!invisible && mVertexShaderLevel > 1) +		if (!invisible && mShaderLevel > 1)  		{  			LLRenderPass::pushBatches(LLRenderPass::PASS_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);  		} @@ -461,7 +461,7 @@ void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32&  		{  			shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); -			if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0) +			if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0)  			{  				if (diffuse_channel != 0)  				{ @@ -494,7 +494,7 @@ void LLDrawPoolBump::endShiny(bool invisible)  		return;  	} -	unbindCubeMap(shader, mVertexShaderLevel, diffuse_channel, cube_channel, invisible); +	unbindCubeMap(shader, mShaderLevel, diffuse_channel, cube_channel, invisible);  	if (shader)  	{  		shader->unbind(); @@ -568,7 +568,7 @@ void LLDrawPoolBump::beginFullbrightShiny()  		gGL.getTexUnit(0)->activate();  	} -	if (mVertexShaderLevel > 1) +	if (mShaderLevel > 1)  	{ //indexed texture rendering, channel 0 is always diffuse  		diffuse_channel = 0;  	} @@ -588,7 +588,7 @@ void LLDrawPoolBump::renderFullbrightShiny()  	{  		LLGLEnable blend_enable(GL_BLEND); -		if (mVertexShaderLevel > 1) +		if (mShaderLevel > 1)  		{  			LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);  		} @@ -1541,7 +1541,7 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL  			tex_setup = true;  		} -		if (mShiny && mVertexShaderLevel > 1 && texture) +		if (mShiny && mShaderLevel > 1 && texture)  		{  			if (params.mTexture.notNull())  			{ diff --git a/indra/newview/lldrawpoolground.cpp b/indra/newview/lldrawpoolground.cpp index bae07a171b..6bd2631d3b 100644 --- a/indra/newview/lldrawpoolground.cpp +++ b/indra/newview/lldrawpoolground.cpp @@ -53,7 +53,7 @@ LLDrawPool *LLDrawPoolGround::instancePool()  void LLDrawPoolGround::prerender()  { -	mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT); +	mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT);  }  void LLDrawPoolGround::render(S32 pass) diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp index 113c198a9a..05b0c1f1a9 100644 --- a/indra/newview/lldrawpoolmaterials.cpp +++ b/indra/newview/lldrawpoolmaterials.cpp @@ -42,7 +42,7 @@ LLDrawPoolMaterials::LLDrawPoolMaterials()  void LLDrawPoolMaterials::prerender()  { -	mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);  +	mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);   }  S32 LLDrawPoolMaterials::getNumDeferredPasses() @@ -203,7 +203,7 @@ void LLDrawPoolMaterials::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture,  			tex_setup = true;  		} -		if (mVertexShaderLevel > 1 && texture) +		if (mShaderLevel > 1 && texture)  		{  			if (params.mTexture.notNull())  			{ diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp index bb50ad8e3e..f653920662 100644 --- a/indra/newview/lldrawpoolsimple.cpp +++ b/indra/newview/lldrawpoolsimple.cpp @@ -90,7 +90,7 @@ void LLDrawPoolGlow::endPostDeferredPass(S32 pass)  S32 LLDrawPoolGlow::getNumPasses()  { -	if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0) +	if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0)  	{  		return 1;  	} @@ -111,7 +111,7 @@ void LLDrawPoolGlow::render(S32 pass)  	glPolygonOffset(-1.0f, -1.0f);  	gGL.setSceneBlendType(LLRender::BT_ADD); -	U32 shader_level = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); +	U32 shader_level = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);  	//should never get here without basic shaders enabled  	llassert(shader_level > 0); @@ -164,7 +164,7 @@ LLDrawPoolSimple::LLDrawPoolSimple() :  void LLDrawPoolSimple::prerender()  { -	mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); +	mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);  }  void LLDrawPoolSimple::beginRenderPass(S32 pass) @@ -184,7 +184,7 @@ void LLDrawPoolSimple::beginRenderPass(S32 pass)  		simple_shader = &gObjectSimpleProgram;  	} -	if (mVertexShaderLevel > 0) +	if (mShaderLevel > 0)  	{  		simple_shader->bind(); @@ -213,7 +213,7 @@ void LLDrawPoolSimple::endRenderPass(S32 pass)  	stop_glerror();  	LLRenderPass::endRenderPass(pass);  	stop_glerror(); -	if (mVertexShaderLevel > 0) +	if (mShaderLevel > 0)  	{  		simple_shader->unbind();  	} @@ -227,7 +227,7 @@ void LLDrawPoolSimple::render(S32 pass)  		LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE);  		gPipeline.enableLightsDynamic(); -		if (mVertexShaderLevel > 0) +		if (mShaderLevel > 0)  		{  			U32 mask = getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX; @@ -270,7 +270,7 @@ LLDrawPoolAlphaMask::LLDrawPoolAlphaMask() :  void LLDrawPoolAlphaMask::prerender()  { -	mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); +	mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);  }  void LLDrawPoolAlphaMask::beginRenderPass(S32 pass) @@ -286,7 +286,7 @@ void LLDrawPoolAlphaMask::beginRenderPass(S32 pass)  		simple_shader = &gObjectSimpleAlphaMaskProgram;  	} -	if (mVertexShaderLevel > 0) +	if (mShaderLevel > 0)  	{  		simple_shader->bind(); @@ -315,7 +315,7 @@ void LLDrawPoolAlphaMask::endRenderPass(S32 pass)  	stop_glerror();  	LLRenderPass::endRenderPass(pass);  	stop_glerror(); -	if (mVertexShaderLevel > 0) +	if (mShaderLevel > 0)  	{  		simple_shader->unbind();  	} @@ -326,7 +326,7 @@ void LLDrawPoolAlphaMask::render(S32 pass)  	LLGLDisable blend(GL_BLEND);  	LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK); -	if (mVertexShaderLevel > 0) +	if (mShaderLevel > 0)  	{  		simple_shader->bind();  		simple_shader->setMinimumAlpha(0.33f); @@ -361,7 +361,7 @@ LLDrawPoolFullbrightAlphaMask::LLDrawPoolFullbrightAlphaMask() :  void LLDrawPoolFullbrightAlphaMask::prerender()  { -	mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); +	mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);  }  void LLDrawPoolFullbrightAlphaMask::beginRenderPass(S32 pass) @@ -377,7 +377,7 @@ void LLDrawPoolFullbrightAlphaMask::beginRenderPass(S32 pass)  		simple_shader = &gObjectFullbrightAlphaMaskProgram;  	} -	if (mVertexShaderLevel > 0) +	if (mShaderLevel > 0)  	{  		simple_shader->bind(); @@ -406,7 +406,7 @@ void LLDrawPoolFullbrightAlphaMask::endRenderPass(S32 pass)  	stop_glerror();  	LLRenderPass::endRenderPass(pass);  	stop_glerror(); -	if (mVertexShaderLevel > 0) +	if (mShaderLevel > 0)  	{  		simple_shader->unbind();  	} @@ -416,7 +416,7 @@ void LLDrawPoolFullbrightAlphaMask::render(S32 pass)  {  	LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK); -	if (mVertexShaderLevel > 0) +	if (mShaderLevel > 0)  	{  		if (simple_shader)  		{ @@ -533,7 +533,7 @@ LLDrawPoolGrass::LLDrawPoolGrass() :  void LLDrawPoolGrass::prerender()  { -	mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); +	mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);  } @@ -551,7 +551,7 @@ void LLDrawPoolGrass::beginRenderPass(S32 pass)  		simple_shader = &gObjectAlphaMaskNonIndexedProgram;  	} -	if (mVertexShaderLevel > 0) +	if (mShaderLevel > 0)  	{  		simple_shader->bind();  		simple_shader->setMinimumAlpha(0.5f); @@ -580,7 +580,7 @@ void LLDrawPoolGrass::endRenderPass(S32 pass)  	LL_RECORD_BLOCK_TIME(FTM_RENDER_GRASS);  	LLRenderPass::endRenderPass(pass); -	if (mVertexShaderLevel > 0) +	if (mShaderLevel > 0)  	{  		simple_shader->unbind();  	} @@ -643,7 +643,7 @@ LLDrawPoolFullbright::LLDrawPoolFullbright() :  void LLDrawPoolFullbright::prerender()  { -	mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); +	mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);  }  void LLDrawPoolFullbright::beginPostDeferredPass(S32 pass) @@ -711,7 +711,7 @@ void LLDrawPoolFullbright::endRenderPass(S32 pass)  	stop_glerror(); -	if (mVertexShaderLevel > 0) +	if (mShaderLevel > 0)  	{  		fullbright_shader->unbind();  	} @@ -726,7 +726,7 @@ void LLDrawPoolFullbright::render(S32 pass)  	stop_glerror(); -	if (mVertexShaderLevel > 0) +	if (mShaderLevel > 0)  	{  		fullbright_shader->bind();  		fullbright_shader->uniform1f(LLViewerShaderMgr::FULLBRIGHT, 1.f); diff --git a/indra/newview/lldrawpoolsky.cpp b/indra/newview/lldrawpoolsky.cpp index 4d4711d7c9..516302676d 100644 --- a/indra/newview/lldrawpoolsky.cpp +++ b/indra/newview/lldrawpoolsky.cpp @@ -55,7 +55,7 @@ LLDrawPool *LLDrawPoolSky::instancePool()  void LLDrawPoolSky::prerender()  { -	mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT);  +	mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT);   	gSky.mVOSkyp->updateGeometry(gSky.mVOSkyp->mDrawable);  } @@ -75,7 +75,7 @@ void LLDrawPoolSky::render(S32 pass)  	}  	// don't render sky under water (background just gets cleared to fog color) -	if(mVertexShaderLevel > 0 && LLPipeline::sUnderWaterRender) +	if(mShaderLevel > 0 && LLPipeline::sUnderWaterRender)  	{  		return;  	} @@ -100,8 +100,8 @@ void LLDrawPoolSky::render(S32 pass)  	LLGLSPipelineDepthTestSkyBox gls_skybox(true, false); -	LLGLEnable fog_enable( (mVertexShaderLevel < 1 && LLViewerCamera::getInstance()->cameraUnderWater()) ? GL_FOG : 0); - +	LLGLEnable fog_enable( (mShaderLevel < 1 && LLViewerCamera::getInstance()->cameraUnderWater()) ? GL_FOG : 0); +	  	gGL.pushMatrix();  	LLVector3 origin = LLViewerCamera::getInstance()->getOrigin();  	gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]); diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index b716a76543..593636b14a 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -110,7 +110,7 @@ U32 LLDrawPoolTerrain::getVertexDataMask()  void LLDrawPoolTerrain::prerender()  { -	mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT); +	mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT);  	sDetailMode = gSavedSettings.getS32("RenderTerrainDetail");  } @@ -123,7 +123,7 @@ void LLDrawPoolTerrain::beginRenderPass( S32 pass )  					&gTerrainWaterProgram :  					&gTerrainProgram;	 -	if (mVertexShaderLevel > 1 && sShader->mShaderLevel > 0) +	if (mShaderLevel > 1 && sShader->mShaderLevel > 0)  	{  		sShader->bind();  	} @@ -134,7 +134,7 @@ void LLDrawPoolTerrain::endRenderPass( S32 pass )  	LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN);  	//LLFacePool::endRenderPass(pass); -	if (mVertexShaderLevel > 1 && sShader->mShaderLevel > 0) { +	if (mShaderLevel > 1 && sShader->mShaderLevel > 0) {  		sShader->unbind();  	}  } @@ -180,7 +180,7 @@ void LLDrawPoolTerrain::render(S32 pass)  	LLGLSPipeline gls; -	if (mVertexShaderLevel > 1 && sShader->mShaderLevel > 0) +	if (mShaderLevel > 1 && sShader->mShaderLevel > 0)  	{  		gPipeline.enableLightsDynamic(); @@ -434,7 +434,7 @@ void LLDrawPoolTerrain::renderFullShader()  void LLDrawPoolTerrain::hilightParcelOwners()  { -	if (mVertexShaderLevel > 1) +	if (mShaderLevel > 1)  	{ //use fullbright shader for highlighting  		LLGLSLShader* old_shader = sShader;  		sShader->unbind(); diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index b1f40781f7..81b0c8b1bb 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -57,7 +57,7 @@ LLDrawPool *LLDrawPoolTree::instancePool()  void LLDrawPoolTree::prerender()  { -	mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); +	mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);  }  void LLDrawPoolTree::beginRenderPass(S32 pass) @@ -138,7 +138,7 @@ void LLDrawPoolTree::endRenderPass(S32 pass)  		shader->unbind();  	} -	if (mVertexShaderLevel <= 0) +	if (mShaderLevel <= 0)  	{  		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);  	} diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index d217f95cf3..9316890156 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -46,9 +46,14 @@  #include "llworld.h"  #include "pipeline.h"  #include "llviewershadermgr.h" -#include "llenvironment.h" -#include "llsettingssky.h" -#include "llsettingswater.h" +#include "llwaterparammanager.h" + +#if LL_WINDOWS +#pragma optimize("", off) +#endif + +const LLUUID TRANSPARENT_WATER_TEXTURE("2bfd3884-7e27-69b9-ba3a-3e673f680004"); +const LLUUID OPAQUE_WATER_TEXTURE("43c32285-d658-1793-c123-bf86315de055");  static float sTime; @@ -57,51 +62,42 @@ BOOL deferred_render = FALSE;  BOOL LLDrawPoolWater::sSkipScreenCopy = FALSE;  BOOL LLDrawPoolWater::sNeedsReflectionUpdate = TRUE;  BOOL LLDrawPoolWater::sNeedsDistortionUpdate = TRUE; +LLColor4 LLDrawPoolWater::sWaterFogColor = LLColor4(0.2f, 0.5f, 0.5f, 0.f);  F32 LLDrawPoolWater::sWaterFogEnd = 0.f; -LLDrawPoolWater::LLDrawPoolWater() : LLFacePool(POOL_WATER) -{ -} +LLVector3 LLDrawPoolWater::sLightDir; -LLDrawPoolWater::~LLDrawPoolWater() +LLDrawPoolWater::LLDrawPoolWater() : +	LLFacePool(POOL_WATER)  { -} +	mHBTex[0] = LLViewerTextureManager::getFetchedTexture(gSunTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); +	gGL.getTexUnit(0)->bind(mHBTex[0]) ; +	mHBTex[0]->setAddressMode(LLTexUnit::TAM_CLAMP); -void LLDrawPoolWater::setTransparentTextures(const LLUUID& transparentTextureId, const LLUUID& nextTransparentTextureId) -{ -    LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater(); -    mWaterImagep[0] = LLViewerTextureManager::getFetchedTexture(!transparentTextureId.isNull() ? transparentTextureId : pwater->GetDefaultTransparentTextureAssetId()); -    mWaterImagep[1] = LLViewerTextureManager::getFetchedTexture(!nextTransparentTextureId.isNull() ? nextTransparentTextureId : (!transparentTextureId.isNull() ? transparentTextureId : pwater->GetDefaultTransparentTextureAssetId())); -    mWaterImagep[0]->addTextureStats(1024.f*1024.f); -    mWaterImagep[1]->addTextureStats(1024.f*1024.f); -} +	mHBTex[1] = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); +	gGL.getTexUnit(0)->bind(mHBTex[1]); +	mHBTex[1]->setAddressMode(LLTexUnit::TAM_CLAMP); -void LLDrawPoolWater::setOpaqueTexture(const LLUUID& opaqueTextureId) -{ -    LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater(); -    mOpaqueWaterImagep = LLViewerTextureManager::getFetchedTexture(opaqueTextureId); -    mOpaqueWaterImagep->addTextureStats(1024.f*1024.f); + +	mWaterImagep = LLViewerTextureManager::getFetchedTexture(TRANSPARENT_WATER_TEXTURE); +	llassert(mWaterImagep); +	mWaterImagep->setNoDelete(); +	mOpaqueWaterImagep = LLViewerTextureManager::getFetchedTexture(OPAQUE_WATER_TEXTURE); +	llassert(mOpaqueWaterImagep); +	mWaterNormp = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL); +	mWaterNormp->setNoDelete(); + +	restoreGL();  } -void LLDrawPoolWater::setNormalMaps(const LLUUID& normalMapId, const LLUUID& nextNormalMapId) +LLDrawPoolWater::~LLDrawPoolWater()  { -    LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater(); -    mWaterNormp[0] = LLViewerTextureManager::getFetchedTexture(!normalMapId.isNull() ? normalMapId : pwater->GetDefaultWaterNormalAssetId()); -    mWaterNormp[1] = LLViewerTextureManager::getFetchedTexture(!nextNormalMapId.isNull() ? nextNormalMapId : (!normalMapId.isNull() ? normalMapId : pwater->GetDefaultWaterNormalAssetId())); -    mWaterNormp[0]->addTextureStats(1024.f*1024.f); -    mWaterNormp[1]->addTextureStats(1024.f*1024.f);  }  //static  void LLDrawPoolWater::restoreGL()  { -	/*LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater(); -    if (pwater) -    { -        setTransparentTextures(pwater->getTransparentTextureID(), pwater->getNextTransparentTextureID()); -        setOpaqueTexture(pwater->GetDefaultOpaqueTextureAssetId()); -        setNormalMaps(pwater->getNormalMapID(), pwater->getNextNormalMapID()); -    }*/ +	  }  LLDrawPool *LLDrawPoolWater::instancePool() @@ -113,7 +109,14 @@ LLDrawPool *LLDrawPoolWater::instancePool()  void LLDrawPoolWater::prerender()  { -	mVertexShaderLevel = (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) ? LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0; +	mVertexShaderLevel = (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) ? +		LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0; + +	// got rid of modulation by light color since it got a little too +	// green at sunset and sl-57047 (underwater turns black at 8:00) +	sWaterFogColor = LLWaterParamManager::instance().getFogColor(); +	sWaterFogColor.mV[3] = 0; +  }  S32 LLDrawPoolWater::getNumPasses() @@ -204,13 +207,10 @@ void LLDrawPoolWater::render(S32 pass)  	LLGLDisable cullFace(GL_CULL_FACE);  	// Set up second pass first +	mWaterImagep->addTextureStats(1024.f*1024.f);  	gGL.getTexUnit(1)->activate();  	gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); -	gGL.getTexUnit(1)->bind(mWaterImagep[0]) ; - -    gGL.getTexUnit(2)->activate(); -	gGL.getTexUnit(2)->enable(LLTexUnit::TT_TEXTURE); -	gGL.getTexUnit(2)->bind(mWaterImagep[1]) ; +	gGL.getTexUnit(1)->bind(mWaterImagep) ;  	LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis();  	F32 up_dot = camera_up * LLVector3::z_axis; @@ -267,14 +267,6 @@ void LLDrawPoolWater::render(S32 pass)  	gGL.getTexUnit(1)->activate();  	gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);  	gGL.getTexUnit(1)->disable(); - -    glDisable(GL_TEXTURE_GEN_S); //texture unit 1 -	glDisable(GL_TEXTURE_GEN_T); //texture unit 1 - -    gGL.getTexUnit(1)->activate(); -	gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE); -	gGL.getTexUnit(1)->disable(); -  	glDisable(GL_TEXTURE_GEN_S); //texture unit 1  	glDisable(GL_TEXTURE_GEN_T); //texture unit 1 @@ -374,6 +366,8 @@ void LLDrawPoolWater::renderOpaqueLegacyWater()  	gPipeline.disableLights(); +	mOpaqueWaterImagep->addTextureStats(1024.f*1024.f); +  	// Activate the texture binding and bind one  	// texture since all images will have the same texture  	gGL.getTexUnit(0)->activate(); @@ -471,7 +465,7 @@ void LLDrawPoolWater::renderReflection(LLFace* face)  	LLGLSNoFog noFog; -	gGL.getTexUnit(0)->bind((dr == 0) ? voskyp->getSunTex() : voskyp->getMoonTex()); +	gGL.getTexUnit(0)->bind(mHBTex[dr]);  	LLOverrideFaceColor override(this, LLColor4(face->getFaceColor().mV));  	face->renderIndexed(); @@ -496,33 +490,31 @@ void LLDrawPoolWater::shade()  	LLColor3 light_diffuse(0,0,0);  	F32 light_exp = 0.0f;  	LLVector3 light_dir; - -    LLEnvironment& environment = LLEnvironment::instance(); -    LLSettingsWater::ptr_t pwater = environment.getCurrentWater(); -    LLSettingsSky::ptr_t   psky   = environment.getCurrentSky(); - -    light_dir = environment.getLightDirection(); -    light_dir.normalize(); - -    bool sun_up  = environment.getIsSunUp(); -    bool moon_up = environment.getIsMoonUp(); - -    if (sun_up) -    { -        light_diffuse += voskyp->getSun().getColorCached(); -    } -    // moonlight is several orders of magnitude less bright than sunlight, -    // so only use this color when the moon alone is showing -    else if (moon_up) -    {         -        light_diffuse += psky->getMoonDiffuse();  +	LLColor3 light_color; + +	if (gSky.getSunDirection().mV[2] > LLSky::NIGHTTIME_ELEVATION_COS) 	  +    { 	  +        light_dir  = gSky.getSunDirection(); 	  +        light_dir.normVec(); 	 +		light_color = gSky.getSunDiffuseColor(); +		if(gSky.mVOSkyp) { +	        light_diffuse = gSky.mVOSkyp->getSun().getColorCached(); 	  +			light_diffuse.normVec(); 	  +		} +        light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0); 	  +        light_diffuse *= light_exp + 0.25f; 	  +    } 	  +    else  	  +    { 	  +        light_dir       = gSky.getMoonDirection(); 	  +        light_dir.normVec(); 	  +		light_color = gSky.getMoonDiffuseColor(); +        light_diffuse   = gSky.mVOSkyp->getMoon().getColorCached(); 	  +        light_diffuse.normVec(); 	  +        light_diffuse *= 0.5f; 	  +        light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0); 	       } -    light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0.f); - -    light_diffuse.normalize(); -    light_diffuse *= (light_exp + 0.25f); -  	light_exp *= light_exp;  	light_exp *= light_exp;  	light_exp *= light_exp; @@ -530,22 +522,20 @@ void LLDrawPoolWater::shade()  	light_exp *= 256.f;  	light_exp = light_exp > 32.f ? light_exp : 32.f; -    light_diffuse *= 6.f; -  	LLGLSLShader* shader; -	F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - LLEnvironment::instance().getWaterHeight(); +	F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - gAgent.getRegion()->getWaterHeight();  	if (eyedepth < 0.f && LLPipeline::sWaterReflections)  	{ -	    if (deferred_render) -	    { -            shader = &gDeferredUnderWaterProgram; -	    } +	if (deferred_render) +	{ +			shader = &gDeferredUnderWaterProgram; +	}  		else -        { -	        shader = &gUnderWaterProgram; -        } +	{ +		shader = &gUnderWaterProgram; +	}  	}  	else if (deferred_render)  	{ @@ -556,18 +546,16 @@ void LLDrawPoolWater::shade()  		shader = &gWaterProgram;  	} -    shader->bind(); -  	if (deferred_render)  	{ -        if (shader->getUniformLocation(LLShaderMgr::DEFERRED_NORM_MATRIX) >= 0) -	    { -		    glh::matrix4f norm_mat = get_current_modelview().inverse().transpose(); -		    shader->uniformMatrix4fv(LLShaderMgr::DEFERRED_NORM_MATRIX, 1, FALSE, norm_mat.m); -	    } +		gPipeline.bindDeferredShader(*shader); +	} +	else +	{ +		shader->bind();  	} -	sTime = (F32)LLFrameTimer::getElapsedSeconds() * 0.5f; +	sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f;  	S32 reftex = shader->enableTexture(LLShaderMgr::WATER_REFTEX); @@ -581,48 +569,43 @@ void LLDrawPoolWater::shade()  	//bind normal map  	S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP); -    if (mWaterNormp[0]) -    { -	    gGL.getTexUnit(bumpTex)->bind(mWaterNormp[0]) ; +	LLWaterParamManager * param_mgr = &LLWaterParamManager::instance(); -	    if (gSavedSettings.getBOOL("RenderWaterMipNormal")) -	    { -		    mWaterNormp[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC); -	    } -	    else  -	    { -		    mWaterNormp[0]->setFilteringOption(LLTexUnit::TFO_POINT); -	    } +	// change mWaterNormp if needed +	if (mWaterNormp->getID() != param_mgr->getNormalMapID()) +	{ +		mWaterNormp = LLViewerTextureManager::getFetchedTexture(param_mgr->getNormalMapID());  	} -    if (mWaterNormp[1]) -    { -        bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP2); - -        gGL.getTexUnit(bumpTex)->bind(mWaterNormp[1]) ; - -	    if (gSavedSettings.getBOOL("RenderWaterMipNormal")) -	    { -            mWaterNormp[1]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC); -	    } -	    else  -	    { -            mWaterNormp[1]->setFilteringOption(LLTexUnit::TFO_POINT); -	    } +	mWaterNormp->addTextureStats(1024.f*1024.f); +	gGL.getTexUnit(bumpTex)->bind(mWaterNormp) ; +	if (gSavedSettings.getBOOL("RenderWaterMipNormal")) +	{ +		mWaterNormp->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);  	} - -    shader->uniform3fv(LLShaderMgr::WATER_FOGCOLOR, 1, pwater->getWaterFogColor().mV); -    shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, pwater->getWaterFogDensity()); +	else  +	{ +		mWaterNormp->setFilteringOption(LLTexUnit::TFO_POINT); +	} +	 +	S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);	 +		 +	if (screentex > -1) +	{ +		shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV); +		shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY,  +			param_mgr->getFogDensity()); +		gPipeline.mWaterDis.bindTexture(0, screentex); +	} +	 +	stop_glerror(); -    // bind reflection texture from RenderTarget -	S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);  	gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);	  	if (mVertexShaderLevel == 1)  	{ -        LLColor4 fog_color(pwater->getWaterFogColor(), 0.f); -        fog_color[3] = pwater->getWaterFogDensity(); -        shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, fog_color.mV); +		sWaterFogColor.mV[3] = param_mgr->mDensitySliderValue; +		shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV);  	}  	F32 screenRes[] =  @@ -636,30 +619,25 @@ void LLDrawPoolWater::shade()  	S32 diffTex = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP);  	stop_glerror(); +	light_dir.normVec(); +	sLightDir = light_dir; +	 +	light_diffuse *= 6.f; +  	//shader->uniformMatrix4fv("inverse_ref", 1, GL_FALSE, (GLfloat*) gGLObliqueProjectionInverse.mMatrix);  	shader->uniform1f(LLShaderMgr::WATER_WATERHEIGHT, eyedepth);  	shader->uniform1f(LLShaderMgr::WATER_TIME, sTime);  	shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV);  	shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV);  	shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp); -    if (LLEnvironment::instance().isCloudScrollPaused()) -    { -        static const std::array<F32, 2> zerowave{ {0.0f, 0.0f} }; -         -        shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, zerowave.data()); -        shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, zerowave.data()); -    } -    else -    { -        shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV); -        shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV); -    } +	shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, param_mgr->getWave1Dir().mV); +	shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, param_mgr->getWave2Dir().mV);  	shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV); -	shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, pwater->getNormalScale().mV); -	shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, pwater->getFresnelScale()); -	shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, pwater->getFresnelOffset()); -    shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, pwater->getBlurMultiplier()); +	shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, param_mgr->getNormalScale().mV); +	shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, param_mgr->getFresnelScale()); +	shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, param_mgr->getFresnelOffset()); +	shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, param_mgr->getBlurMultiplier());  	F32 sunAngle = llmax(0.f, light_dir.mV[2]);  	F32 scaledAngle = 1.f - sunAngle; @@ -674,12 +652,12 @@ void LLDrawPoolWater::shade()  	if (LLViewerCamera::getInstance()->cameraUnderWater())  	{  		water_color.setVec(1.f, 1.f, 1.f, 0.4f); -		shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleBelow()); +		shader->uniform1f(LLShaderMgr::WATER_REFSCALE, param_mgr->getScaleBelow());  	}  	else  	{  		water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot)); -		shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleAbove()); +		shader->uniform1f(LLShaderMgr::WATER_REFSCALE, param_mgr->getScaleAbove());  	}  	if (water_color.mV[3] > 0.9f) @@ -687,19 +665,40 @@ void LLDrawPoolWater::shade()  		water_color.mV[3] = 0.9f;  	} -	{		 +	{ +		LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0);  		LLGLDisable cullface(GL_CULL_FACE); - -        sNeedsReflectionUpdate = TRUE;			 -        sNeedsDistortionUpdate = TRUE; - -        for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++) +		for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); +			iter != mDrawFace.end(); iter++)  		{  			LLFace *face = *iter; + +			if (voskyp->isReflFace(face)) +			{ +				continue; +			} + +			LLVOWater* water = (LLVOWater*) face->getViewerObject();  			gGL.getTexUnit(diffTex)->bind(face->getTexture()); -            face->renderIndexed(); + +			sNeedsReflectionUpdate = TRUE; +			 +			if (water->getUseTexture() || !water->getIsEdgePatch()) +			{ +				sNeedsDistortionUpdate = TRUE; +				face->renderIndexed(); +			} +			else if (gGLManager.mHasDepthClamp || deferred_render) +			{ +				face->renderIndexed(); +			} +			else +			{ +				LLGLSquashToFarClip far_clip(glh_get_current_projection()); +				face->renderIndexed(); +			}  		} -    } +	}  	shader->disableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);  	shader->disableTexture(LLShaderMgr::WATER_SCREENTEX);	 @@ -708,7 +707,14 @@ void LLDrawPoolWater::shade()  	shader->disableTexture(LLShaderMgr::WATER_REFTEX);  	shader->disableTexture(LLShaderMgr::WATER_SCREENDEPTH); -	shader->unbind(); +	if (deferred_render) +	{ +		gPipeline.unbindDeferredShader(*shader); +	} +	else +	{ +		shader->unbind(); +	}  	gGL.getTexUnit(0)->activate();  	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index 8904020ab9..025a4c86e5 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -375,7 +375,7 @@ void LLDrawPoolWLSky::renderStarsDeferred(void) const      gDeferredStarProgram.uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor); -    if (LLPipeline::sRenderingWaterReflection) +    if (LLPipeline::sReflectionRender)      {          star_alpha = 1.0f;      } diff --git a/indra/newview/lldrawpoolwlsky.h b/indra/newview/lldrawpoolwlsky.h index e7b4726321..1980ba6878 100644 --- a/indra/newview/lldrawpoolwlsky.h +++ b/indra/newview/lldrawpoolwlsky.h @@ -66,7 +66,7 @@ public:  	/*virtual*/ void prerender();  	/*virtual*/ U32 getVertexDataMask() { return SKY_VERTEX_DATA_MASK; }  	/*virtual*/ BOOL verify() const { return TRUE; }		// Verify that all data in the draw pool is correct! -	/*virtual*/ S32 getVertexShaderLevel() const { return mVertexShaderLevel; } +	/*virtual*/ S32 getShaderLevel() const { return mShaderLevel; }  	//static LLDrawPool* createPool(const U32 type, LLViewerTexture *tex0 = NULL); diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index 96dd309fa4..4993441508 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -560,7 +560,7 @@ void LLPanelVolume::refresh()  		mRootObject = NULL;  	} -	BOOL visible = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 0 ? TRUE : FALSE; +	BOOL visible = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 0 ? TRUE : FALSE;  	getChildView("Light FOV")->setVisible( visible);  	getChildView("Light Focus")->setVisible( visible); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 82120db53e..2d4478bfdb 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -653,7 +653,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  		stop_glerror();  		S32 water_clip = 0; -		if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT) > 1) && +		if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT) > 1) &&  			 (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER) ||   			  gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_VOIDWATER)))  		{ @@ -1021,9 +1021,14 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  			}  		} +        if (LLPipeline::sRenderDeferred && gAtmosphere && gSavedSettings.getBOOL("RenderUseAdvancedAtmospherics")) +        { +            gPipeline.generateSkyIndirect(); +        } +  		if (LLPipeline::sRenderDeferred)  		{ -			gPipeline.renderDeferredLighting(); +			gPipeline.renderDeferredLighting(&gPipeline.mScreen);  		}  		LLPipeline::sUnderWaterRender = FALSE; diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index 43a81ada49..6990f56a08 100644 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -112,7 +112,7 @@ void LLViewerJointMesh::uploadJointMatrices()  	S32 joint_num;  	LLPolyMesh *reference_mesh = mMesh->getReferenceMesh();  	LLDrawPool *poolp = mFace ? mFace->getPool() : NULL; -	BOOL hardware_skinning = (poolp && poolp->getVertexShaderLevel() > 0) ? TRUE : FALSE; +	BOOL hardware_skinning = (poolp && poolp->getShaderLevel() > 0) ? TRUE : FALSE;  	//calculate joint matrices  	for (joint_num = 0; joint_num < reference_mesh->mJointRenderData.size(); joint_num++) @@ -246,7 +246,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)  	stop_glerror(); -	LLGLSSpecular specular(LLColor4(1.f,1.f,1.f,1.f), (mFace->getPool()->getVertexShaderLevel() > 0 || LLGLSLShader::sNoFixedFunction) ? 0.f : mShiny); +	LLGLSSpecular specular(LLColor4(1.f,1.f,1.f,1.f), (mFace->getPool()->getShaderLevel() > 0 || LLGLSLShader::sNoFixedFunction) ? 0.f : mShiny);  	//----------------------------------------------------------------  	// setup current texture @@ -307,14 +307,14 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)  	if (mMesh->hasWeights())  	{ -		if ((mFace->getPool()->getVertexShaderLevel() > 0)) +		if ((mFace->getPool()->getShaderLevel() > 0))  		{  			if (first_pass)  			{  				uploadJointMatrices();  			}  			mask = mask | LLVertexBuffer::MAP_WEIGHT; -			if (mFace->getPool()->getVertexShaderLevel() > 1) +			if (mFace->getPool()->getShaderLevel() > 1)  			{  				mask = mask | LLVertexBuffer::MAP_CLOTHWEIGHT;  			} @@ -390,7 +390,7 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w  	}  	LLDrawPool *poolp = mFace->getPool(); -	BOOL hardware_skinning = (poolp && poolp->getVertexShaderLevel() > 0) ? TRUE : FALSE; +	BOOL hardware_skinning = (poolp && poolp->getShaderLevel() > 0) ? TRUE : FALSE;  	if (!hardware_skinning && terse_update)  	{ //no need to do terse updates if we're doing software vertex skinning @@ -538,7 +538,7 @@ void LLViewerJointMesh::updateJointGeometry()  		  && mFace  		  && mMesh->hasWeights()  		  && mFace->getVertexBuffer() -		  && LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) == 0)) +		  && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) == 0))  	{  		return;  	} diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 6e500f7962..1bbda04ae6 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -1211,6 +1211,20 @@ class LLAdvancedSelectedTextureInfo : public view_listener_t  	}  }; +//////////////////////////// +// TOGGLE SH LIGHTING VIS // +//////////////////////////// + +class LLAdvancedToggleDebugSH : public view_listener_t +{ +	bool handleEvent(const LLSD& userdata) +	{ +        gPipeline.toggleRenderDebug(LLPipeline::RENDER_DEBUG_SH); +        gSavedSettings.setBOOL("RenderDebugSH", gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SH)); +		return true; +	} +}; +  //////////////////////  // TOGGLE WIREFRAME //  ////////////////////// @@ -2274,8 +2288,8 @@ class LLAdvancedEnableRenderDeferred: public view_listener_t  {  	bool handleEvent(const LLSD& userdata)  	{ -		bool new_value = gGLManager.mHasFramebufferObject && LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 && -			LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) > 0; +		bool new_value = gGLManager.mHasFramebufferObject && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 && +			LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) > 0;  		return new_value;  	}  }; @@ -2287,8 +2301,8 @@ class LLAdvancedEnableRenderDeferredOptions: public view_listener_t  {  	bool handleEvent(const LLSD& userdata)  	{ -		bool new_value = gGLManager.mHasFramebufferObject && LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 && -			LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) > 0 && gSavedSettings.getBOOL("RenderDeferred"); +		bool new_value = gGLManager.mHasFramebufferObject && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 && +			LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) > 0 && gSavedSettings.getBOOL("RenderDeferred");  		return new_value;  	}  }; @@ -6101,12 +6115,7 @@ class LLAvatarResetSkeleton: public view_listener_t  {      bool handleEvent(const LLSD& userdata)      { -		LLVOAvatar* avatar = NULL; -        LLViewerObject *obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); -        if (obj) -        { -            avatar = obj->getAvatar(); -        } +		LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );  		if(avatar)          {              avatar->resetSkeleton(false); @@ -8650,7 +8659,6 @@ class LLWorldEnableEnvPreset : public view_listener_t  	}  }; -  /// Post-Process callbacks  class LLWorldPostProcess : public view_listener_t  { @@ -8991,6 +8999,7 @@ void initialize_menus()  	commit.add("Advanced.SelectedMaterialInfo", boost::bind(&handle_selected_material_info));  	view_listener_t::addMenu(new LLAdvancedToggleWireframe(), "Advanced.ToggleWireframe");  	view_listener_t::addMenu(new LLAdvancedCheckWireframe(), "Advanced.CheckWireframe"); +    view_listener_t::addMenu(new LLAdvancedToggleDebugSH(), "Advanced.ToggleDebugSH");  	// Develop > Render  	view_listener_t::addMenu(new LLAdvancedEnableObjectObjectOcclusion(), "Advanced.EnableObjectObjectOcclusion");  	view_listener_t::addMenu(new LLAdvancedEnableRenderFBO(), "Advanced.EnableRenderFBO"); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index f4f9a3a0c2..9a62ab232d 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -242,12 +242,16 @@ LLGLSLShader			gDeferredSkinnedFullbrightShinyProgram;  LLGLSLShader			gDeferredSkinnedFullbrightProgram;  LLGLSLShader			gNormalMapGenProgram; +LLGLSLShader			gDeferredGenSkyShProgram; +LLGLSLShader			gDeferredGatherSkyShProgram; +LLGLSLShader			gDeferredShVisProgram; +  // Deferred materials shaders  LLGLSLShader			gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];  LLGLSLShader			gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2];  LLViewerShaderMgr::LLViewerShaderMgr() : -	mVertexShaderLevel(SHADER_COUNT, 0), +	mShaderLevel(SHADER_COUNT, 0),  	mMaxAvatarShaderLevel(0)  {	  	/// Make sure WL Sky is the first program @@ -350,11 +354,14 @@ LLViewerShaderMgr::LLViewerShaderMgr() :  	mShaderList.push_back(&gDeferredWLCloudProgram);      mShaderList.push_back(&gDeferredWLMoonProgram);      mShaderList.push_back(&gDeferredWLSunProgram); +    mShaderList.push_back(&gDeferredGenSkyShProgram); +    mShaderList.push_back(&gDeferredGatherSkyShProgram); +    mShaderList.push_back(&gDeferredShVisProgram);  }  LLViewerShaderMgr::~LLViewerShaderMgr()  { -	mVertexShaderLevel.clear(); +	mShaderLevel.clear();  	mShaderList.clear();  } @@ -391,9 +398,9 @@ void LLViewerShaderMgr::initAttribsAndUniforms(void)  //============================================================================  // Set Levels -S32 LLViewerShaderMgr::getVertexShaderLevel(S32 type) +S32 LLViewerShaderMgr::getShaderLevel(S32 type)  { -	return LLPipeline::sDisableShaders ? 0 : mVertexShaderLevel[type]; +	return LLPipeline::sDisableShaders ? 0 : mShaderLevel[type];  }  //============================================================================ @@ -468,7 +475,7 @@ void LLViewerShaderMgr::setShaders()  	for (S32 i = 0; i < SHADER_COUNT; i++)  	{ -		mVertexShaderLevel[i] = 0; +		mShaderLevel[i] = 0;  	}  	mMaxAvatarShaderLevel = 0; @@ -526,22 +533,22 @@ void LLViewerShaderMgr::setShaders()  		}  		// Trigger a full rebuild of the fallback skybox / cubemap if we've toggled windlight shaders -		if (mVertexShaderLevel[SHADER_WINDLIGHT] != wl_class && gSky.mVOSkyp.notNull()) +		if (mShaderLevel[SHADER_WINDLIGHT] != wl_class && gSky.mVOSkyp.notNull())  		{  			gSky.mVOSkyp->forceSkyUpdate();  		}  		// Load lighting shaders -		mVertexShaderLevel[SHADER_LIGHTING] = light_class; -		mVertexShaderLevel[SHADER_INTERFACE] = light_class; -		mVertexShaderLevel[SHADER_ENVIRONMENT] = env_class; -		mVertexShaderLevel[SHADER_WATER] = water_class; -		mVertexShaderLevel[SHADER_OBJECT] = obj_class; -		mVertexShaderLevel[SHADER_EFFECT] = effect_class; -		mVertexShaderLevel[SHADER_WINDLIGHT] = wl_class; -		mVertexShaderLevel[SHADER_DEFERRED] = deferred_class; -		mVertexShaderLevel[SHADER_TRANSFORM] = transform_class; +		mShaderLevel[SHADER_LIGHTING] = light_class; +		mShaderLevel[SHADER_INTERFACE] = light_class; +		mShaderLevel[SHADER_ENVIRONMENT] = env_class; +		mShaderLevel[SHADER_WATER] = water_class; +		mShaderLevel[SHADER_OBJECT] = obj_class; +		mShaderLevel[SHADER_EFFECT] = effect_class; +		mShaderLevel[SHADER_WINDLIGHT] = wl_class; +		mShaderLevel[SHADER_DEFERRED] = deferred_class; +		mShaderLevel[SHADER_TRANSFORM] = transform_class;  		BOOL loaded = loadBasicShaders();          if (loaded) @@ -646,7 +653,7 @@ void LLViewerShaderMgr::setShaders()  			if (loaded)  			{  				// Load max avatar shaders to set the max level -				mVertexShaderLevel[SHADER_AVATAR] = 3; +				mShaderLevel[SHADER_AVATAR] = 3;  				mMaxAvatarShaderLevel = 3;  				if (gSavedSettings.getBOOL("RenderAvatarVP") && loadShadersObject()) @@ -657,17 +664,18 @@ void LLViewerShaderMgr::setShaders()  					S32 avatar_class = avatar_cloth ? 3 : 1;  					// Set the actual level -					mVertexShaderLevel[SHADER_AVATAR] = avatar_class; +					mShaderLevel[SHADER_AVATAR] = avatar_class; +  					loaded = loadShadersAvatar();                      llassert(loaded); -					if (mVertexShaderLevel[SHADER_AVATAR] != avatar_class) +					if (mShaderLevel[SHADER_AVATAR] != avatar_class)  					{ -						if (mVertexShaderLevel[SHADER_AVATAR] == 0) +						if (mShaderLevel[SHADER_AVATAR] == 0)  						{  							gSavedSettings.setBOOL("RenderAvatarVP", FALSE);  						} -						if(llmax(mVertexShaderLevel[SHADER_AVATAR]-1,0) >= 3) +						if(llmax(mShaderLevel[SHADER_AVATAR]-1,0) >= 3)  						{  							avatar_cloth = true;  						} @@ -680,8 +688,8 @@ void LLViewerShaderMgr::setShaders()  				}  				else  				{ //hardware skinning not possible, neither is deferred rendering -					mVertexShaderLevel[SHADER_AVATAR] = 0; -					mVertexShaderLevel[SHADER_DEFERRED] = 0; +					mShaderLevel[SHADER_AVATAR] = 0; +					mShaderLevel[SHADER_DEFERRED] = 0;  					if (gSavedSettings.getBOOL("RenderAvatarVP"))  					{ @@ -734,14 +742,14 @@ void LLViewerShaderMgr::setShaders()  			LLGLSLShader::sNoFixedFunction = false;  			gPipeline.mVertexShadersEnabled = FALSE;  			gPipeline.mVertexShadersLoaded = 0; -			mVertexShaderLevel[SHADER_LIGHTING] = 0; -			mVertexShaderLevel[SHADER_INTERFACE] = 0; -			mVertexShaderLevel[SHADER_ENVIRONMENT] = 0; -			mVertexShaderLevel[SHADER_WATER] = 0; -			mVertexShaderLevel[SHADER_OBJECT] = 0; -			mVertexShaderLevel[SHADER_EFFECT] = 0; -			mVertexShaderLevel[SHADER_WINDLIGHT] = 0; -			mVertexShaderLevel[SHADER_AVATAR] = 0; +			mShaderLevel[SHADER_LIGHTING] = 0; +			mShaderLevel[SHADER_INTERFACE] = 0; +			mShaderLevel[SHADER_ENVIRONMENT] = 0; +			mShaderLevel[SHADER_WATER] = 0; +			mShaderLevel[SHADER_OBJECT] = 0; +			mShaderLevel[SHADER_EFFECT] = 0; +			mShaderLevel[SHADER_WINDLIGHT] = 0; +			mShaderLevel[SHADER_AVATAR] = 0;  		}  	}  	else @@ -749,14 +757,14 @@ void LLViewerShaderMgr::setShaders()  		LLGLSLShader::sNoFixedFunction = false;  		gPipeline.mVertexShadersEnabled = FALSE;  		gPipeline.mVertexShadersLoaded = 0; -		mVertexShaderLevel[SHADER_LIGHTING] = 0; -		mVertexShaderLevel[SHADER_INTERFACE] = 0; -		mVertexShaderLevel[SHADER_ENVIRONMENT] = 0; -		mVertexShaderLevel[SHADER_WATER] = 0; -		mVertexShaderLevel[SHADER_OBJECT] = 0; -		mVertexShaderLevel[SHADER_EFFECT] = 0; -		mVertexShaderLevel[SHADER_WINDLIGHT] = 0; -		mVertexShaderLevel[SHADER_AVATAR] = 0; +		mShaderLevel[SHADER_LIGHTING] = 0; +		mShaderLevel[SHADER_INTERFACE] = 0; +		mShaderLevel[SHADER_ENVIRONMENT] = 0; +		mShaderLevel[SHADER_WATER] = 0; +		mShaderLevel[SHADER_OBJECT] = 0; +		mShaderLevel[SHADER_EFFECT] = 0; +		mShaderLevel[SHADER_WINDLIGHT] = 0; +		mShaderLevel[SHADER_AVATAR] = 0;  	}  	if (gViewerWindow) @@ -885,15 +893,15 @@ void LLViewerShaderMgr::unloadShaders()  	gTransformColorProgram.unload();  	gTransformTangentProgram.unload(); -	mVertexShaderLevel[SHADER_LIGHTING] = 0; -	mVertexShaderLevel[SHADER_OBJECT] = 0; -	mVertexShaderLevel[SHADER_AVATAR] = 0; -	mVertexShaderLevel[SHADER_ENVIRONMENT] = 0; -	mVertexShaderLevel[SHADER_WATER] = 0; -	mVertexShaderLevel[SHADER_INTERFACE] = 0; -	mVertexShaderLevel[SHADER_EFFECT] = 0; -	mVertexShaderLevel[SHADER_WINDLIGHT] = 0; -	mVertexShaderLevel[SHADER_TRANSFORM] = 0; +	mShaderLevel[SHADER_LIGHTING] = 0; +	mShaderLevel[SHADER_OBJECT] = 0; +	mShaderLevel[SHADER_AVATAR] = 0; +	mShaderLevel[SHADER_ENVIRONMENT] = 0; +	mShaderLevel[SHADER_WATER] = 0; +	mShaderLevel[SHADER_INTERFACE] = 0; +	mShaderLevel[SHADER_EFFECT] = 0; +	mShaderLevel[SHADER_WINDLIGHT] = 0; +	mShaderLevel[SHADER_TRANSFORM] = 0;  	gPipeline.mVertexShadersLoaded = 0;  } @@ -936,16 +944,16 @@ BOOL LLViewerShaderMgr::loadBasicShaders()  	// (in order of shader function call depth for reference purposes, deepest level first)  	vector< pair<string, S32> > shaders; -	shaders.push_back( make_pair( "windlight/atmosphericsVarsV.glsl",		mVertexShaderLevel[SHADER_WINDLIGHT] ) ); -	shaders.push_back( make_pair( "windlight/atmosphericsVarsWaterV.glsl",	mVertexShaderLevel[SHADER_WINDLIGHT] ) ); -	shaders.push_back( make_pair( "windlight/atmosphericsHelpersV.glsl",	mVertexShaderLevel[SHADER_WINDLIGHT] ) ); -	shaders.push_back( make_pair( "lighting/lightFuncV.glsl",				mVertexShaderLevel[SHADER_LIGHTING] ) ); +	shaders.push_back( make_pair( "windlight/atmosphericsVarsV.glsl",		mShaderLevel[SHADER_WINDLIGHT] ) ); +	shaders.push_back( make_pair( "windlight/atmosphericsVarsWaterV.glsl",	mShaderLevel[SHADER_WINDLIGHT] ) ); +	shaders.push_back( make_pair( "windlight/atmosphericsHelpersV.glsl",	mShaderLevel[SHADER_WINDLIGHT] ) ); +	shaders.push_back( make_pair( "lighting/lightFuncV.glsl",				mShaderLevel[SHADER_LIGHTING] ) );  	shaders.push_back( make_pair( "lighting/sumLightsV.glsl",				sum_lights_class ) ); -	shaders.push_back( make_pair( "lighting/lightV.glsl",					mVertexShaderLevel[SHADER_LIGHTING] ) ); -	shaders.push_back( make_pair( "lighting/lightFuncSpecularV.glsl",		mVertexShaderLevel[SHADER_LIGHTING] ) ); +	shaders.push_back( make_pair( "lighting/lightV.glsl",					mShaderLevel[SHADER_LIGHTING] ) ); +	shaders.push_back( make_pair( "lighting/lightFuncSpecularV.glsl",		mShaderLevel[SHADER_LIGHTING] ) );  	shaders.push_back( make_pair( "lighting/sumLightsSpecularV.glsl",		sum_lights_class ) ); -	shaders.push_back( make_pair( "lighting/lightSpecularV.glsl",			mVertexShaderLevel[SHADER_LIGHTING] ) ); -	shaders.push_back( make_pair( "windlight/atmosphericsV.glsl",			mVertexShaderLevel[SHADER_WINDLIGHT] ) ); +	shaders.push_back( make_pair( "lighting/lightSpecularV.glsl",			mShaderLevel[SHADER_LIGHTING] ) ); +	shaders.push_back( make_pair( "windlight/atmosphericsV.glsl",			mShaderLevel[SHADER_WINDLIGHT] ) );  	shaders.push_back( make_pair( "avatar/avatarSkinV.glsl",				1 ) );  	shaders.push_back( make_pair( "avatar/objectSkinV.glsl",				1 ) );  	if (gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30) @@ -981,44 +989,44 @@ BOOL LLViewerShaderMgr::loadBasicShaders()  	}  	std::vector<S32> index_channels;     -	index_channels.push_back(-1);	 shaders.push_back( make_pair( "windlight/atmosphericsVarsF.glsl",		mVertexShaderLevel[SHADER_WINDLIGHT] ) ); -	index_channels.push_back(-1);	 shaders.push_back( make_pair( "windlight/atmosphericsVarsWaterF.glsl",		mVertexShaderLevel[SHADER_WINDLIGHT] ) ); -    index_channels.push_back(-1);	 shaders.push_back( make_pair( "windlight/atmosphericsHelpersF.glsl",		mVertexShaderLevel[SHADER_WINDLIGHT] ) );	 -	index_channels.push_back(-1);	 shaders.push_back( make_pair( "windlight/atmosphericsF.glsl",			mVertexShaderLevel[SHADER_WINDLIGHT] ) ); -	index_channels.push_back(-1);	 shaders.push_back( make_pair( "windlight/transportF.glsl",				mVertexShaderLevel[SHADER_WINDLIGHT] ) );	 -    index_channels.push_back(-1);	 shaders.push_back( make_pair( "windlight/gammaF.glsl",					mVertexShaderLevel[SHADER_WINDLIGHT]) ); -	index_channels.push_back(-1);	 shaders.push_back( make_pair( "environment/waterFogF.glsl",				mVertexShaderLevel[SHADER_WATER] ) ); -    index_channels.push_back(-1);	 shaders.push_back( make_pair( "environment/encodeNormF.glsl",				    mVertexShaderLevel[SHADER_ENVIRONMENT] ) ); -    index_channels.push_back(-1);	 shaders.push_back( make_pair( "environment/decodeNormF.glsl",				    mVertexShaderLevel[SHADER_ENVIRONMENT] ) ); -    index_channels.push_back(-1);	 shaders.push_back( make_pair( "environment/srgbF.glsl",				    mVertexShaderLevel[SHADER_ENVIRONMENT] ) ); -#if USE_DEFERRED_SHADER_API -    index_channels.push_back(-1);	 shaders.push_back( make_pair( "deferred/deferredUtil.glsl",				    mVertexShaderLevel[SHADER_DEFERRED] ) ); -    index_channels.push_back(-1);	 shaders.push_back( make_pair( "deferred/indirect.glsl",				    mVertexShaderLevel[SHADER_DEFERRED] ) ); -#endif -	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl",					mVertexShaderLevel[SHADER_LIGHTING] ) ); -	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightAlphaMaskNonIndexedF.glsl",					mVertexShaderLevel[SHADER_LIGHTING] ) ); -	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightFullbrightNonIndexedF.glsl",			mVertexShaderLevel[SHADER_LIGHTING] ) ); -	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightFullbrightNonIndexedAlphaMaskF.glsl",			mVertexShaderLevel[SHADER_LIGHTING] ) ); -	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightWaterNonIndexedF.glsl",				mVertexShaderLevel[SHADER_LIGHTING] ) ); -	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightWaterAlphaMaskNonIndexedF.glsl",				mVertexShaderLevel[SHADER_LIGHTING] ) ); -	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightFullbrightWaterNonIndexedF.glsl",	mVertexShaderLevel[SHADER_LIGHTING] ) ); -	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl",	mVertexShaderLevel[SHADER_LIGHTING] ) ); -	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightShinyNonIndexedF.glsl",				mVertexShaderLevel[SHADER_LIGHTING] ) ); -	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightFullbrightShinyNonIndexedF.glsl",	mVertexShaderLevel[SHADER_LIGHTING] ) ); -	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightShinyWaterNonIndexedF.glsl",			mVertexShaderLevel[SHADER_LIGHTING] ) ); -	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightFullbrightShinyWaterNonIndexedF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); -	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightF.glsl",					mVertexShaderLevel[SHADER_LIGHTING] ) ); -	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightAlphaMaskF.glsl",					mVertexShaderLevel[SHADER_LIGHTING] ) ); -	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightFullbrightF.glsl",			mVertexShaderLevel[SHADER_LIGHTING] ) ); -	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightFullbrightAlphaMaskF.glsl",			mVertexShaderLevel[SHADER_LIGHTING] ) ); -	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightWaterF.glsl",				mVertexShaderLevel[SHADER_LIGHTING] ) ); -	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightWaterAlphaMaskF.glsl",	mVertexShaderLevel[SHADER_LIGHTING] ) ); -	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightFullbrightWaterF.glsl",	mVertexShaderLevel[SHADER_LIGHTING] ) ); -	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightFullbrightWaterAlphaMaskF.glsl",	mVertexShaderLevel[SHADER_LIGHTING] ) ); -	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightShinyF.glsl",				mVertexShaderLevel[SHADER_LIGHTING] ) ); -	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightFullbrightShinyF.glsl",	mVertexShaderLevel[SHADER_LIGHTING] ) ); -	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightShinyWaterF.glsl",			mVertexShaderLevel[SHADER_LIGHTING] ) ); -	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightFullbrightShinyWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(-1);	 shaders.push_back( make_pair( "windlight/atmosphericsVarsF.glsl",		mShaderLevel[SHADER_WINDLIGHT] ) ); +	index_channels.push_back(-1);	 shaders.push_back( make_pair( "windlight/atmosphericsVarsWaterF.glsl",		mShaderLevel[SHADER_WINDLIGHT] ) ); +    index_channels.push_back(-1);	 shaders.push_back( make_pair( "windlight/atmosphericsHelpersF.glsl",		mShaderLevel[SHADER_WINDLIGHT] ) ); +	index_channels.push_back(-1);	 shaders.push_back( make_pair( "windlight/gammaF.glsl",					mShaderLevel[SHADER_WINDLIGHT]) ); +	index_channels.push_back(-1);	 shaders.push_back( make_pair( "windlight/atmosphericsF.glsl",			mShaderLevel[SHADER_WINDLIGHT] ) ); +	index_channels.push_back(-1);	 shaders.push_back( make_pair( "windlight/transportF.glsl",				mShaderLevel[SHADER_WINDLIGHT] ) );	 +	index_channels.push_back(-1);	 shaders.push_back( make_pair( "environment/waterFogF.glsl",				mShaderLevel[SHADER_WATER] ) ); +    index_channels.push_back(-1);	 shaders.push_back( make_pair( "environment/encodeNormF.glsl",				    mShaderLevel[SHADER_ENVIRONMENT] ) ); +    index_channels.push_back(-1);	 shaders.push_back( make_pair( "environment/decodeNormF.glsl",				    mShaderLevel[SHADER_ENVIRONMENT] ) ); +    index_channels.push_back(-1);	 shaders.push_back( make_pair( "environment/srgbF.glsl",				    mShaderLevel[SHADER_ENVIRONMENT] ) ); +    index_channels.push_back(-1);	 shaders.push_back( make_pair( "deferred/deferredUtil.glsl",				    mShaderLevel[SHADER_DEFERRED] ) ); +    index_channels.push_back(-1);	 shaders.push_back( make_pair( "deferred/shadowUtil.glsl",				    mShaderLevel[SHADER_DEFERRED] ) ); +    index_channels.push_back(-1);	 shaders.push_back( make_pair( "deferred/aoUtil.glsl",				    mShaderLevel[SHADER_DEFERRED] ) ); +    index_channels.push_back(-1);	 shaders.push_back( make_pair( "deferred/indirect.glsl",				    mShaderLevel[SHADER_DEFERRED] ) ); +	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl",					mShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightAlphaMaskNonIndexedF.glsl",					mShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightFullbrightNonIndexedF.glsl",			mShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightFullbrightNonIndexedAlphaMaskF.glsl",			mShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightWaterNonIndexedF.glsl",				mShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightWaterAlphaMaskNonIndexedF.glsl",				mShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightFullbrightWaterNonIndexedF.glsl",	mShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl",	mShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightShinyNonIndexedF.glsl",				mShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightFullbrightShinyNonIndexedF.glsl",	mShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightShinyWaterNonIndexedF.glsl",			mShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightFullbrightShinyWaterNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightF.glsl",					mShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightAlphaMaskF.glsl",					mShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightFullbrightF.glsl",			mShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightFullbrightAlphaMaskF.glsl",			mShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightWaterF.glsl",				mShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightWaterAlphaMaskF.glsl",	mShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightFullbrightWaterF.glsl",	mShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightFullbrightWaterAlphaMaskF.glsl",	mShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightShinyF.glsl",				mShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightFullbrightShinyF.glsl",	mShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightShinyWaterF.glsl",			mShaderLevel[SHADER_LIGHTING] ) ); +	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightFullbrightShinyWaterF.glsl", mShaderLevel[SHADER_LIGHTING] ) );  	for (U32 i = 0; i < shaders.size(); i++)  	{ @@ -1037,7 +1045,7 @@ BOOL LLViewerShaderMgr::loadShadersEnvironment()  {  	BOOL success = TRUE; -	if (mVertexShaderLevel[SHADER_ENVIRONMENT] == 0) +	if (mShaderLevel[SHADER_ENVIRONMENT] == 0)  	{  		gTerrainProgram.unload();  		return TRUE; @@ -1048,21 +1056,24 @@ BOOL LLViewerShaderMgr::loadShadersEnvironment()  		gTerrainProgram.mName = "Terrain Shader";  		gTerrainProgram.mFeatures.calculatesLighting = true;  		gTerrainProgram.mFeatures.calculatesAtmospherics = true; -		gTerrainProgram.mFeatures.hasAtmospherics = true; +        gTerrainProgram.mFeatures.hasAtmospherics = true; +        gTerrainProgram.mFeatures.hasTransport = true; +        gTerrainProgram.mFeatures.hasGamma = true; +        gTerrainProgram.mFeatures.hasSrgb = true;  		gTerrainProgram.mFeatures.mIndexedTextureChannels = 0;  		gTerrainProgram.mFeatures.disableTextureIndex = true;  		gTerrainProgram.mFeatures.hasGamma = true;  		gTerrainProgram.mShaderFiles.clear();  		gTerrainProgram.mShaderFiles.push_back(make_pair("environment/terrainV.glsl", GL_VERTEX_SHADER_ARB));  		gTerrainProgram.mShaderFiles.push_back(make_pair("environment/terrainF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gTerrainProgram.mShaderLevel = mVertexShaderLevel[SHADER_ENVIRONMENT]; +		gTerrainProgram.mShaderLevel = mShaderLevel[SHADER_ENVIRONMENT];  		success = gTerrainProgram.createShader(NULL, NULL);          llassert(success);  	}  	if (!success)  	{ -		mVertexShaderLevel[SHADER_ENVIRONMENT] = 0; +		mShaderLevel[SHADER_ENVIRONMENT] = 0;  		return FALSE;  	} @@ -1076,7 +1087,7 @@ BOOL LLViewerShaderMgr::loadShadersWater()  	BOOL success = TRUE;  	BOOL terrainWaterSuccess = TRUE; -	if (mVertexShaderLevel[SHADER_WATER] == 0) +	if (mShaderLevel[SHADER_WATER] == 0)  	{  		gWaterProgram.unload();  		gUnderWaterProgram.unload(); @@ -1095,7 +1106,7 @@ BOOL LLViewerShaderMgr::loadShadersWater()  		gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER_ARB));  		gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER_ARB));          gWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; -		gWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_WATER]; +		gWaterProgram.mShaderLevel = mShaderLevel[SHADER_WATER];  		success = gWaterProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -1109,7 +1120,7 @@ BOOL LLViewerShaderMgr::loadShadersWater()  		gUnderWaterProgram.mShaderFiles.clear();  		gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER_ARB));  		gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/underWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gUnderWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_WATER];         +		gUnderWaterProgram.mShaderLevel = mShaderLevel[SHADER_WATER];          		gUnderWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;		  		success = gUnderWaterProgram.createShader(NULL, NULL);          llassert(success); @@ -1128,30 +1139,30 @@ BOOL LLViewerShaderMgr::loadShadersWater()  		gTerrainWaterProgram.mShaderFiles.clear();  		gTerrainWaterProgram.mShaderFiles.push_back(make_pair("environment/terrainV.glsl", GL_VERTEX_SHADER_ARB));  		gTerrainWaterProgram.mShaderFiles.push_back(make_pair("environment/terrainWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gTerrainWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_ENVIRONMENT]; +		gTerrainWaterProgram.mShaderLevel = mShaderLevel[SHADER_ENVIRONMENT];  		gTerrainWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  		terrainWaterSuccess = gTerrainWaterProgram.createShader(NULL, NULL);          llassert(terrainWaterSuccess);  	}	  	/// Keep track of water shader levels -	if (gWaterProgram.mShaderLevel != mVertexShaderLevel[SHADER_WATER] -		|| gUnderWaterProgram.mShaderLevel != mVertexShaderLevel[SHADER_WATER]) +	if (gWaterProgram.mShaderLevel != mShaderLevel[SHADER_WATER] +		|| gUnderWaterProgram.mShaderLevel != mShaderLevel[SHADER_WATER])  	{ -		mVertexShaderLevel[SHADER_WATER] = llmin(gWaterProgram.mShaderLevel, gUnderWaterProgram.mShaderLevel); +		mShaderLevel[SHADER_WATER] = llmin(gWaterProgram.mShaderLevel, gUnderWaterProgram.mShaderLevel);  	}  	if (!success)  	{ -		mVertexShaderLevel[SHADER_WATER] = 0; +		mShaderLevel[SHADER_WATER] = 0;  		return FALSE;  	}  	// if we failed to load the terrain water shaders and we need them (using class2 water),  	// then drop down to class1 water. -	if (mVertexShaderLevel[SHADER_WATER] > 1 && !terrainWaterSuccess) +	if (mShaderLevel[SHADER_WATER] > 1 && !terrainWaterSuccess)  	{ -		mVertexShaderLevel[SHADER_WATER]--; +		mShaderLevel[SHADER_WATER]--;  		return loadShadersWater();  	} @@ -1164,7 +1175,7 @@ BOOL LLViewerShaderMgr::loadShadersEffects()  {  	BOOL success = TRUE; -	if (mVertexShaderLevel[SHADER_EFFECT] == 0) +	if (mShaderLevel[SHADER_EFFECT] == 0)  	{  		gGlowProgram.unload();  		gGlowExtractProgram.unload(); @@ -1179,7 +1190,7 @@ BOOL LLViewerShaderMgr::loadShadersEffects()  		gGlowProgram.mShaderFiles.clear();  		gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowV.glsl", GL_VERTEX_SHADER_ARB));  		gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gGlowProgram.mShaderLevel = mVertexShaderLevel[SHADER_EFFECT]; +		gGlowProgram.mShaderLevel = mShaderLevel[SHADER_EFFECT];  		success = gGlowProgram.createShader(NULL, NULL);  		if (!success)  		{ @@ -1193,7 +1204,7 @@ BOOL LLViewerShaderMgr::loadShadersEffects()  		gGlowExtractProgram.mShaderFiles.clear();  		gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER_ARB));  		gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gGlowExtractProgram.mShaderLevel = mVertexShaderLevel[SHADER_EFFECT]; +		gGlowExtractProgram.mShaderLevel = mShaderLevel[SHADER_EFFECT];  		success = gGlowExtractProgram.createShader(NULL, NULL);  		if (!success)  		{ @@ -1207,7 +1218,9 @@ BOOL LLViewerShaderMgr::loadShadersEffects()  BOOL LLViewerShaderMgr::loadShadersDeferred()  { -	if (mVertexShaderLevel[SHADER_DEFERRED] == 0) +    bool use_sun_shadow = mShaderLevel[SHADER_DEFERRED] > 1; + +	if (mShaderLevel[SHADER_DEFERRED] == 0)  	{  		gDeferredTreeProgram.unload();  		gDeferredTreeShadowProgram.unload(); @@ -1270,6 +1283,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  			gDeferredMaterialProgram[i].unload();  			gDeferredMaterialWaterProgram[i].unload();  		} + +        gDeferredGenSkyShProgram.unload(); +        gDeferredGatherSkyShProgram.unload(); +        gDeferredShVisProgram.unload();  		return TRUE;  	} @@ -1279,11 +1296,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	{  		gDeferredDiffuseProgram.mName = "Deferred Diffuse Shader";          gDeferredDiffuseProgram.mFeatures.encodesNormal = true; +        gDeferredDiffuseProgram.mFeatures.isDeferred = true;  		gDeferredDiffuseProgram.mShaderFiles.clear();  		gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseIndexedF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredDiffuseProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; -		gDeferredDiffuseProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredDiffuseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredDiffuseProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -1292,11 +1310,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	{  		gDeferredDiffuseAlphaMaskProgram.mName = "Deferred Diffuse Alpha Mask Shader";          gDeferredDiffuseAlphaMaskProgram.mFeatures.encodesNormal = true; +        gDeferredDiffuseAlphaMaskProgram.mFeatures.isDeferred = true;  		gDeferredDiffuseAlphaMaskProgram.mShaderFiles.clear();  		gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskIndexedF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredDiffuseAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; -		gDeferredDiffuseAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredDiffuseAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredDiffuseAlphaMaskProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -1305,10 +1324,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	{  		gDeferredNonIndexedDiffuseAlphaMaskProgram.mName = "Deferred Diffuse Non-Indexed Alpha Mask Shader";          gDeferredNonIndexedDiffuseAlphaMaskProgram.mFeatures.encodesNormal = true; +        gDeferredNonIndexedDiffuseAlphaMaskProgram.mFeatures.isDeferred = true;  		gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.clear();  		gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredNonIndexedDiffuseAlphaMaskProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -1317,10 +1337,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	{  		gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mName = "Deferred Diffuse Non-Indexed Alpha Mask Shader";          gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mFeatures.encodesNormal = true; +        gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mFeatures.isDeferred = true;  		gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.clear();  		gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseNoColorV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskNoColorF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -1329,10 +1350,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	{  		gDeferredNonIndexedDiffuseProgram.mName = "Non Indexed Deferred Diffuse Shader";          gDeferredNonIndexedDiffuseProgram.mFeatures.encodesNormal = true; +        gDeferredNonIndexedDiffuseProgram.mFeatures.isDeferred = true;  		gDeferredNonIndexedDiffuseProgram.mShaderFiles.clear();  		gDeferredNonIndexedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredNonIndexedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredNonIndexedDiffuseProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredNonIndexedDiffuseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredNonIndexedDiffuseProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -1342,10 +1364,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredSkinnedDiffuseProgram.mName = "Deferred Skinned Diffuse Shader";  		gDeferredSkinnedDiffuseProgram.mFeatures.hasObjectSkinning = true;          gDeferredSkinnedDiffuseProgram.mFeatures.encodesNormal = true; +        gDeferredSkinnedDiffuseProgram.mFeatures.isDeferred = true;  		gDeferredSkinnedDiffuseProgram.mShaderFiles.clear();  		gDeferredSkinnedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseSkinnedV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredSkinnedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredSkinnedDiffuseProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredSkinnedDiffuseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredSkinnedDiffuseProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -1355,10 +1378,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredSkinnedBumpProgram.mName = "Deferred Skinned Bump Shader";  		gDeferredSkinnedBumpProgram.mFeatures.hasObjectSkinning = true;          gDeferredSkinnedBumpProgram.mFeatures.encodesNormal = true; +        gDeferredSkinnedBumpProgram.mFeatures.isDeferred = true;  		gDeferredSkinnedBumpProgram.mShaderFiles.clear();  		gDeferredSkinnedBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpSkinnedV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredSkinnedBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredSkinnedBumpProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredSkinnedBumpProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredSkinnedBumpProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -1378,15 +1402,18 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()          gDeferredSkinnedAlphaProgram.mFeatures.hasAtmospherics = true;          gDeferredSkinnedAlphaProgram.mFeatures.hasTransport = true;          gDeferredSkinnedAlphaProgram.mFeatures.hasGamma = true; +        gDeferredSkinnedAlphaProgram.mFeatures.hasShadows = true; +        gDeferredSkinnedAlphaProgram.mFeatures.hasIndirect = true; +        gDeferredSkinnedAlphaProgram.mFeatures.isDeferred = true;  		gDeferredSkinnedAlphaProgram.mShaderFiles.clear();  		gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredSkinnedAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredSkinnedAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		gDeferredSkinnedAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1");  		gDeferredSkinnedAlphaProgram.addPermutation("HAS_SKIN", "1");  		gDeferredSkinnedAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1"); -		gDeferredSkinnedAlphaProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0"); +		gDeferredSkinnedAlphaProgram.addPermutation("HAS_SHADOW", use_sun_shadow ? "1" : "0");  		success = gDeferredSkinnedAlphaProgram.createShader(NULL, NULL);  		llassert(success); @@ -1399,10 +1426,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	{  		gDeferredBumpProgram.mName = "Deferred Bump Shader";          gDeferredBumpProgram.mFeatures.encodesNormal = true; +        gDeferredBumpProgram.mFeatures.isDeferred = true;  		gDeferredBumpProgram.mShaderFiles.clear();  		gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredBumpProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredBumpProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredBumpProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -1436,21 +1464,24 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  			gDeferredMaterialProgram[i].mShaderFiles.clear();  			gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER_ARB));  			gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER_ARB)); -			gDeferredMaterialProgram[i].mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +			gDeferredMaterialProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED];  			gDeferredMaterialProgram[i].addPermutation("HAS_NORMAL_MAP", i & 0x8? "1" : "0");  			gDeferredMaterialProgram[i].addPermutation("HAS_SPECULAR_MAP", i & 0x4 ? "1" : "0");  			gDeferredMaterialProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode)); -			gDeferredMaterialProgram[i].addPermutation("HAS_SUN_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0"); +			gDeferredMaterialProgram[i].addPermutation("HAS_SUN_SHADOW", use_sun_shadow ? "1" : "0");  			bool has_skin = i & 0x10;  			gDeferredMaterialProgram[i].addPermutation("HAS_SKIN",has_skin ? "1" : "0");  			gDeferredMaterialProgram[i].mFeatures.hasSrgb = true; -            gDeferredMaterialProgram[i].mFeatures.hasGamma = true;              gDeferredMaterialProgram[i].mFeatures.hasTransport = true;              gDeferredMaterialProgram[i].mFeatures.decodesNormal = true;              gDeferredMaterialProgram[i].mFeatures.encodesNormal = true;              gDeferredMaterialProgram[i].mFeatures.calculatesAtmospherics = true;              gDeferredMaterialProgram[i].mFeatures.hasAtmospherics = true; +            gDeferredMaterialProgram[i].mFeatures.hasGamma = true; +            gDeferredMaterialProgram[i].mFeatures.hasShadows = true; +            gDeferredMaterialProgram[i].mFeatures.hasIndirect = true; +            gDeferredMaterialProgram[i].mFeatures.isDeferred = true;  			if (has_skin)  			{ @@ -1470,25 +1501,29 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  			gDeferredMaterialWaterProgram[i].mShaderFiles.clear();  			gDeferredMaterialWaterProgram[i].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER_ARB));  			gDeferredMaterialWaterProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER_ARB)); -			gDeferredMaterialWaterProgram[i].mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +			gDeferredMaterialWaterProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED];  			gDeferredMaterialWaterProgram[i].mShaderGroup = LLGLSLShader::SG_WATER;  			gDeferredMaterialWaterProgram[i].addPermutation("HAS_NORMAL_MAP", i & 0x8? "1" : "0");  			gDeferredMaterialWaterProgram[i].addPermutation("HAS_SPECULAR_MAP", i & 0x4 ? "1" : "0");  			gDeferredMaterialWaterProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode)); -			gDeferredMaterialWaterProgram[i].addPermutation("HAS_SUN_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0"); +			gDeferredMaterialWaterProgram[i].addPermutation("HAS_SUN_SHADOW", use_sun_shadow ? "1" : "0");  			bool has_skin = i & 0x10;  			gDeferredMaterialWaterProgram[i].addPermutation("HAS_SKIN",has_skin ? "1" : "0");  			gDeferredMaterialWaterProgram[i].addPermutation("WATER_FOG","1");  			gDeferredMaterialWaterProgram[i].mFeatures.hasWaterFog = true;  			gDeferredMaterialWaterProgram[i].mFeatures.hasSrgb = true; -            gDeferredMaterialWaterProgram[i].mFeatures.hasGamma = true; -            gDeferredMaterialWaterProgram[i].mFeatures.hasTransport = true;              gDeferredMaterialWaterProgram[i].mFeatures.decodesNormal = true;              gDeferredMaterialWaterProgram[i].mFeatures.encodesNormal = true;              gDeferredMaterialWaterProgram[i].mFeatures.calculatesAtmospherics = true;              gDeferredMaterialWaterProgram[i].mFeatures.hasAtmospherics = true; +            gDeferredMaterialWaterProgram[i].mFeatures.hasGamma = true; + +            gDeferredMaterialWaterProgram[i].mFeatures.hasTransport = true; +            gDeferredMaterialWaterProgram[i].mFeatures.hasShadows = true; +            gDeferredMaterialWaterProgram[i].mFeatures.hasIndirect = true; +            gDeferredMaterialWaterProgram[i].mFeatures.isDeferred = true;  			if (has_skin)  			{ @@ -1524,9 +1559,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredTreeProgram.mName = "Deferred Tree Shader";  		gDeferredTreeProgram.mShaderFiles.clear();          gDeferredTreeProgram.mFeatures.encodesNormal = true; +        gDeferredTreeProgram.mFeatures.isDeferred = true;  		gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredTreeProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredTreeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredTreeProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -1535,9 +1571,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	{  		gDeferredTreeShadowProgram.mName = "Deferred Tree Shadow Shader";  		gDeferredTreeShadowProgram.mShaderFiles.clear(); +        gDeferredTreeShadowProgram.mFeatures.isDeferred = true;  		gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredTreeShadowProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredTreeShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredTreeShadowProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -1548,10 +1585,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredImpostorProgram.mFeatures.hasSrgb = true;          gDeferredImpostorProgram.mFeatures.decodesNormal = true;          gDeferredImpostorProgram.mFeatures.encodesNormal = true; +        //gDeferredImpostorProgram.mFeatures.isDeferred = true;  		gDeferredImpostorProgram.mShaderFiles.clear();  		gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredImpostorProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredImpostorProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredImpostorProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -1560,10 +1598,13 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	{		  		gDeferredLightProgram.mName = "Deferred Light Shader";          gDeferredLightProgram.mFeatures.decodesNormal = true; +        gDeferredLightProgram.mFeatures.isDeferred = true; +        gDeferredLightProgram.mFeatures.hasShadows = true; +  		gDeferredLightProgram.mShaderFiles.clear();  		gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredLightProgram.createShader(NULL, NULL);          llassert(success); @@ -1575,10 +1616,13 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	{  			gDeferredMultiLightProgram[i].mName = llformat("Deferred MultiLight Shader %d", i);              gDeferredMultiLightProgram[i].mFeatures.decodesNormal = true; +            gDeferredMultiLightProgram[i].mFeatures.isDeferred = true; +            gDeferredMultiLightProgram[i].mFeatures.hasShadows = true; +  			gDeferredMultiLightProgram[i].mShaderFiles.clear();  			gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB));  			gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER_ARB)); -			gDeferredMultiLightProgram[i].mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +			gDeferredMultiLightProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED];  			gDeferredMultiLightProgram[i].addPermutation("LIGHT_COUNT", llformat("%d", i+1));  			success = gDeferredMultiLightProgram[i].createShader(NULL, NULL);              llassert(success); @@ -1591,9 +1635,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredSpotLightProgram.mShaderFiles.clear();  		gDeferredSpotLightProgram.mFeatures.hasSrgb = true;          gDeferredSpotLightProgram.mFeatures.decodesNormal = true; +        gDeferredSpotLightProgram.mFeatures.isDeferred = true; +        gDeferredSpotLightProgram.mFeatures.hasShadows = true; +  		gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredSpotLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredSpotLightProgram.createShader(NULL, NULL);          llassert(success); @@ -1604,10 +1651,13 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredMultiSpotLightProgram.mName = "Deferred MultiSpotLight Shader";  		gDeferredMultiSpotLightProgram.mFeatures.hasSrgb = true;          gDeferredMultiSpotLightProgram.mFeatures.decodesNormal = true; +        gDeferredMultiSpotLightProgram.mFeatures.isDeferred = true; +        gDeferredMultiSpotLightProgram.mFeatures.hasShadows = true; +  		gDeferredMultiSpotLightProgram.mShaderFiles.clear();  		gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredMultiSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredMultiSpotLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredMultiSpotLightProgram.createShader(NULL, NULL);          llassert(success); @@ -1618,14 +1668,16 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		std::string fragment;  		std::string vertex = "deferred/sunLightV.glsl"; -		if (gSavedSettings.getBOOL("RenderDeferredSSAO")) +        bool use_ao = gSavedSettings.getBOOL("RenderDeferredSSAO"); + +		if (use_ao)  		{  			fragment = "deferred/sunLightSSAOF.glsl";  		}  		else  		{  			fragment = "deferred/sunLightF.glsl"; -			if (mVertexShaderLevel[SHADER_DEFERRED] == 1) +			if (mShaderLevel[SHADER_DEFERRED] == 1)  			{ //no shadows, no SSAO, no frag coord  				vertex = "deferred/sunLightNoFragCoordV.glsl";  			} @@ -1633,10 +1685,15 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredSunProgram.mName = "Deferred Sun Shader";          gDeferredSunProgram.mFeatures.decodesNormal = true; +        gDeferredSunProgram.mFeatures.isDeferred    = true; +        gDeferredSunProgram.mFeatures.hasShadows    = true; +        gDeferredSunProgram.mFeatures.hasIndirect   = true; +        gDeferredSunProgram.mFeatures.hasAmbientOcclusion = use_ao; +  		gDeferredSunProgram.mShaderFiles.clear();  		gDeferredSunProgram.mShaderFiles.push_back(make_pair(vertex, GL_VERTEX_SHADER_ARB));  		gDeferredSunProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB)); -		gDeferredSunProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredSunProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredSunProgram.createShader(NULL, NULL);          llassert(success); @@ -1646,10 +1703,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	{  		gDeferredBlurLightProgram.mName = "Deferred Blur Light Shader";          gDeferredBlurLightProgram.mFeatures.decodesNormal = true; +        gDeferredBlurLightProgram.mFeatures.isDeferred = true; +  		gDeferredBlurLightProgram.mShaderFiles.clear();  		gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredBlurLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredBlurLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredBlurLightProgram.createShader(NULL, NULL);          llassert(success); @@ -1664,13 +1723,17 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredAlphaProgram.mFeatures.isAlphaLighting = true;  		gDeferredAlphaProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels          gDeferredAlphaProgram.mFeatures.hasSrgb = true; -        gDeferredAlphaProgram.mFeatures.hasGamma = true;          gDeferredAlphaProgram.mFeatures.decodesNormal = true;          gDeferredAlphaProgram.mFeatures.encodesNormal = true;          gDeferredAlphaProgram.mFeatures.calculatesAtmospherics = true;          gDeferredAlphaProgram.mFeatures.hasAtmospherics = true; +        gDeferredAlphaProgram.mFeatures.hasGamma = true; +        gDeferredAlphaProgram.mFeatures.hasTransport = true; +        gDeferredAlphaProgram.mFeatures.isDeferred = true; +        gDeferredAlphaProgram.mFeatures.hasShadows = true; +        gDeferredAlphaProgram.mFeatures.hasIndirect = true; -		if (mVertexShaderLevel[SHADER_DEFERRED] < 1) +		if (mShaderLevel[SHADER_DEFERRED] < 1)  		{  			gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;  		} @@ -1683,9 +1746,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredAlphaProgram.addPermutation("USE_INDEXED_TEX", "1"); -		gDeferredAlphaProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0"); +		gDeferredAlphaProgram.addPermutation("HAS_SHADOW", use_sun_shadow ? "1" : "0");  		gDeferredAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1"); -		gDeferredAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredAlphaProgram.createShader(NULL, NULL);          llassert(success); @@ -1705,8 +1768,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredAlphaImpostorProgram.mFeatures.hasSrgb = true;          gDeferredAlphaImpostorProgram.mFeatures.decodesNormal = true;          gDeferredAlphaImpostorProgram.mFeatures.encodesNormal = true; +        gDeferredAlphaImpostorProgram.mFeatures.isDeferred = true; +        gDeferredAlphaImpostorProgram.mFeatures.hasShadows = true; +        gDeferredAlphaImpostorProgram.mFeatures.hasIndirect = true; +  		gDeferredAlphaImpostorProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels -		if (mVertexShaderLevel[SHADER_DEFERRED] < 1) +		if (mShaderLevel[SHADER_DEFERRED] < 1)  		{  			gDeferredAlphaImpostorProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;  		} @@ -1719,11 +1786,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredAlphaImpostorProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredAlphaImpostorProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredAlphaImpostorProgram.addPermutation("USE_INDEXED_TEX", "1"); -		gDeferredAlphaImpostorProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0"); +		gDeferredAlphaImpostorProgram.addPermutation("HAS_SHADOW", use_sun_shadow ? "1" : "0");  		gDeferredAlphaImpostorProgram.addPermutation("USE_VERTEX_COLOR", "1");  		gDeferredAlphaImpostorProgram.addPermutation("FOR_IMPOSTOR", "1"); -		gDeferredAlphaImpostorProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredAlphaImpostorProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredAlphaImpostorProgram.createShader(NULL, NULL);          llassert(success); @@ -1742,13 +1809,17 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredAlphaWaterProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels  		gDeferredAlphaWaterProgram.mFeatures.hasWaterFog = true;  		gDeferredAlphaWaterProgram.mFeatures.hasSrgb = true; -        gDeferredAlphaWaterProgram.mFeatures.hasGamma = true;          gDeferredAlphaWaterProgram.mFeatures.decodesNormal = true;          gDeferredAlphaWaterProgram.mFeatures.encodesNormal = true;          gDeferredAlphaWaterProgram.mFeatures.calculatesAtmospherics = true;          gDeferredAlphaWaterProgram.mFeatures.hasAtmospherics = true; +        gDeferredAlphaWaterProgram.mFeatures.hasGamma = true; +        gDeferredAlphaWaterProgram.mFeatures.hasTransport = true; +        gDeferredAlphaWaterProgram.mFeatures.isDeferred = true; +        gDeferredAlphaWaterProgram.mFeatures.hasShadows = true; +        gDeferredAlphaWaterProgram.mFeatures.hasIndirect = true; -		if (mVertexShaderLevel[SHADER_DEFERRED] < 1) +		if (mShaderLevel[SHADER_DEFERRED] < 1)  		{  			gDeferredAlphaWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;  		} @@ -1763,8 +1834,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredAlphaWaterProgram.addPermutation("USE_INDEXED_TEX", "1");  		gDeferredAlphaWaterProgram.addPermutation("WATER_FOG", "1");  		gDeferredAlphaWaterProgram.addPermutation("USE_VERTEX_COLOR", "1"); -		gDeferredAlphaWaterProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0"); -		gDeferredAlphaWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredAlphaWaterProgram.addPermutation("HAS_SHADOW", use_sun_shadow ? "1" : "0"); +		gDeferredAlphaWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredAlphaWaterProgram.createShader(NULL, NULL);          llassert(success); @@ -1783,11 +1854,13 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredAvatarEyesProgram.mFeatures.disableTextureIndex = true;          gDeferredAvatarEyesProgram.mFeatures.hasSrgb = true;          gDeferredAvatarEyesProgram.mFeatures.encodesNormal = true; -        gDeferredAvatarEyesProgram.mFeatures.hasGamma = true; +        gDeferredAvatarEyesProgram.mFeatures.isDeferred = true; +        gDeferredAvatarEyesProgram.mFeatures.hasShadows = true; +  		gDeferredAvatarEyesProgram.mShaderFiles.clear();  		gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/avatarEyesV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredAvatarEyesProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredAvatarEyesProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredAvatarEyesProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -1799,12 +1872,13 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredFullbrightProgram.mFeatures.hasGamma = true;  		gDeferredFullbrightProgram.mFeatures.hasTransport = true;  		gDeferredFullbrightProgram.mFeatures.hasSrgb = true; -        gDeferredFullbrightProgram.mFeatures.hasGamma = true; +        gDeferredFullbrightProgram.mFeatures.isDeferred = true; +  		gDeferredFullbrightProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;  		gDeferredFullbrightProgram.mShaderFiles.clear();  		gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredFullbrightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredFullbrightProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -1816,13 +1890,14 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredFullbrightAlphaMaskProgram.mFeatures.hasGamma = true;  		gDeferredFullbrightAlphaMaskProgram.mFeatures.hasTransport = true;  		gDeferredFullbrightAlphaMaskProgram.mFeatures.hasSrgb = true; -        gDeferredFullbrightAlphaMaskProgram.mFeatures.hasGamma = true; +        gDeferredFullbrightAlphaMaskProgram.mFeatures.isDeferred = true; +  		gDeferredFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;  		gDeferredFullbrightAlphaMaskProgram.mShaderFiles.clear();  		gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredFullbrightAlphaMaskProgram.addPermutation("HAS_ALPHA_MASK","1"); -		gDeferredFullbrightAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredFullbrightAlphaMaskProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -1835,12 +1910,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredFullbrightWaterProgram.mFeatures.hasTransport = true;  		gDeferredFullbrightWaterProgram.mFeatures.hasWaterFog = true;  		gDeferredFullbrightWaterProgram.mFeatures.hasSrgb = true; -        gDeferredFullbrightWaterProgram.mFeatures.hasGamma = true; +        gDeferredFullbrightWaterProgram.mFeatures.isDeferred = true;  		gDeferredFullbrightWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;  		gDeferredFullbrightWaterProgram.mShaderFiles.clear();  		gDeferredFullbrightWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredFullbrightWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredFullbrightWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredFullbrightWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		gDeferredFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  		gDeferredFullbrightWaterProgram.addPermutation("WATER_FOG","1");  		success = gDeferredFullbrightWaterProgram.createShader(NULL, NULL); @@ -1855,12 +1930,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasTransport = true;  		gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasWaterFog = true;  		gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasSrgb = true; -        gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasGamma = true; +        gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.isDeferred = true;  		gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;  		gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.clear();  		gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredFullbrightAlphaMaskWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredFullbrightAlphaMaskWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		gDeferredFullbrightAlphaMaskWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  		gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("HAS_ALPHA_MASK","1");  		gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("WATER_FOG","1"); @@ -1874,11 +1949,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true;  		gDeferredFullbrightShinyProgram.mFeatures.hasGamma = true;  		gDeferredFullbrightShinyProgram.mFeatures.hasTransport = true; +        gDeferredFullbrightShinyProgram.mFeatures.isDeferred = true;  		gDeferredFullbrightShinyProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels-1;  		gDeferredFullbrightShinyProgram.mShaderFiles.clear();  		gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredFullbrightShinyProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredFullbrightShinyProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -1892,10 +1968,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredSkinnedFullbrightProgram.mFeatures.hasObjectSkinning = true;  		gDeferredSkinnedFullbrightProgram.mFeatures.disableTextureIndex = true;  		gDeferredSkinnedFullbrightProgram.mFeatures.hasSrgb = true; +        gDeferredSkinnedFullbrightProgram.mFeatures.isDeferred = true;  		gDeferredSkinnedFullbrightProgram.mShaderFiles.clear();  		gDeferredSkinnedFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredSkinnedFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredSkinnedFullbrightProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gDeferredSkinnedFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		success = gDeferredSkinnedFullbrightProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -1908,10 +1985,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasTransport = true;  		gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasObjectSkinning = true;  		gDeferredSkinnedFullbrightShinyProgram.mFeatures.disableTextureIndex = true; +        gDeferredSkinnedFullbrightShinyProgram.mFeatures.isDeferred = true;  		gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.clear();  		gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredSkinnedFullbrightShinyProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gDeferredSkinnedFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		success = gDeferredSkinnedFullbrightShinyProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -1922,11 +2000,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredEmissiveProgram.mFeatures.calculatesAtmospherics = true;  		gDeferredEmissiveProgram.mFeatures.hasGamma = true;  		gDeferredEmissiveProgram.mFeatures.hasTransport = true; +        gDeferredEmissiveProgram.mFeatures.isDeferred = true;  		gDeferredEmissiveProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;  		gDeferredEmissiveProgram.mShaderFiles.clear();  		gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredEmissiveProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredEmissiveProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -1939,10 +2018,14 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredWaterProgram.mFeatures.hasGamma = true;  		gDeferredWaterProgram.mFeatures.hasTransport = true;          gDeferredWaterProgram.mFeatures.encodesNormal = true; +        gDeferredWaterProgram.mFeatures.isDeferred = true; +        gDeferredWaterProgram.mFeatures.hasShadows = true; +        gDeferredWaterProgram.mFeatures.hasIndirect = true; +  		gDeferredWaterProgram.mShaderFiles.clear();  		gDeferredWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +        gDeferredWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];          gDeferredWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  		success = gDeferredWaterProgram.createShader(NULL, NULL);          llassert(success); @@ -1958,10 +2041,14 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredUnderWaterProgram.mFeatures.hasTransport = true;  		gDeferredUnderWaterProgram.mFeatures.hasSrgb = true;          gDeferredUnderWaterProgram.mFeatures.encodesNormal = true; +        gDeferredUnderWaterProgram.mFeatures.isDeferred = true; +        gDeferredUnderWaterProgram.mFeatures.hasShadows = true; +        gDeferredUnderWaterProgram.mFeatures.hasIndirect = true; +  		gDeferredUnderWaterProgram.mShaderFiles.clear();  		gDeferredUnderWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredUnderWaterProgram.mShaderFiles.push_back(make_pair("deferred/underWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredUnderWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredUnderWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredUnderWaterProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -1974,18 +2061,29 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()          gDeferredSoftenProgram.mFeatures.decodesNormal = true;          gDeferredSoftenProgram.mFeatures.calculatesAtmospherics = true;          gDeferredSoftenProgram.mFeatures.hasAtmospherics = true; -        gDeferredSoftenProgram.mFeatures.hasGamma = true;          gDeferredSoftenProgram.mFeatures.hasTransport = true; +        gDeferredSoftenProgram.mFeatures.hasGamma = true; +        gDeferredSoftenProgram.mFeatures.isDeferred = true; +        gDeferredSoftenProgram.mFeatures.hasShadows = true; +        gDeferredSoftenProgram.mFeatures.hasIndirect = true;  		gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredSoftenProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +        gDeferredSoftenProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; -		if (gSavedSettings.getBOOL("RenderDeferredSSAO")) +        if (gSavedSettings.getBOOL("RenderDeferredSSAO"))  		{ //if using SSAO, take screen space light map into account as if shadows are enabled  			gDeferredSoftenProgram.mShaderLevel = llmax(gDeferredSoftenProgram.mShaderLevel, 2);  		} + +        // insure we use class3/deferred version of softenLight for advanced atmo.. +        gDeferredSoftenProgram.mShaderLevel = gSavedSettings.getBOOL("RenderUseAdvancedAtmospherics") ? 3 : gDeferredSoftenProgram.mShaderLevel; +         +        if (gAtmosphere && gDeferredSoftenProgram.mShaderLevel > 2) +        { +            gDeferredSoftenProgram.mExtraLinkObject = gAtmosphere->getAtmosphericShaderForLink(); +        }  		success = gDeferredSoftenProgram.createShader(NULL, NULL);          llassert(success); @@ -1998,7 +2096,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredSoftenWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredSoftenWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredSoftenWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +        gDeferredSoftenWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; +          		gDeferredSoftenWaterProgram.addPermutation("WATER_FOG", "1");  		gDeferredSoftenWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  		gDeferredSoftenWaterProgram.mFeatures.hasWaterFog = true; @@ -2006,8 +2105,16 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()          gDeferredSoftenWaterProgram.mFeatures.decodesNormal = true;          gDeferredSoftenWaterProgram.mFeatures.calculatesAtmospherics = true;          gDeferredSoftenWaterProgram.mFeatures.hasAtmospherics = true; -        gDeferredSoftenWaterProgram.mFeatures.hasGamma = true;          gDeferredSoftenWaterProgram.mFeatures.hasTransport = true; +        gDeferredSoftenWaterProgram.mFeatures.hasGamma = true; +        gDeferredSoftenWaterProgram.mFeatures.isDeferred = true; +        gDeferredSoftenWaterProgram.mFeatures.hasShadows = true; +        gDeferredSoftenWaterProgram.mFeatures.hasIndirect = true; + +        if (gAtmosphere && gDeferredSoftenWaterProgram.mShaderLevel > 2) +        { +            gDeferredSoftenWaterProgram.mExtraLinkObject = gAtmosphere->getAtmosphericShaderForLink(); +        }  		if (gSavedSettings.getBOOL("RenderDeferredSSAO"))  		{ //if using SSAO, take screen space light map into account as if shadows are enabled @@ -2021,10 +2128,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{  		gDeferredShadowProgram.mName = "Deferred Shadow Shader"; +        gDeferredShadowProgram.mFeatures.isDeferred = true;  		gDeferredShadowProgram.mShaderFiles.clear();  		gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredShadowProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		gDeferredShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");  		success = gDeferredShadowProgram.createShader(NULL, NULL);          llassert(success); @@ -2033,11 +2141,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{  		gDeferredShadowCubeProgram.mName = "Deferred Shadow Cube Shader"; +        gDeferredShadowCubeProgram.mFeatures.isDeferred = true;  		gDeferredShadowCubeProgram.mShaderFiles.clear();  		gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowCubeV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredShadowCubeProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0"); -		gDeferredShadowCubeProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredShadowCubeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredShadowCubeProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -2046,11 +2155,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	{  		gDeferredShadowAlphaMaskProgram.mName = "Deferred Shadow Alpha Mask Shader";  		gDeferredShadowAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; +        gDeferredShadowAlphaMaskProgram.mFeatures.isDeferred = true;  		gDeferredShadowAlphaMaskProgram.mShaderFiles.clear();  		gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredShadowAlphaMaskProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0"); -		gDeferredShadowAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredShadowAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredShadowAlphaMaskProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -2059,11 +2169,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	{  		gDeferredAvatarShadowProgram.mName = "Deferred Avatar Shadow Shader";  		gDeferredAvatarShadowProgram.mFeatures.hasSkinning = true; +        gDeferredAvatarShadowProgram.mFeatures.isDeferred = true;  		gDeferredAvatarShadowProgram.mShaderFiles.clear();  		gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredAvatarShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0"); -		gDeferredAvatarShadowProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredAvatarShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredAvatarShadowProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -2072,11 +2183,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	{  		gDeferredAttachmentShadowProgram.mName = "Deferred Attachment Shadow Shader";  		gDeferredAttachmentShadowProgram.mFeatures.hasObjectSkinning = true; +        gDeferredAttachmentShadowProgram.mFeatures.isDeferred = true;  		gDeferredAttachmentShadowProgram.mShaderFiles.clear();  		gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredAttachmentShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0"); -		gDeferredAttachmentShadowProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredAttachmentShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredAttachmentShadowProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -2085,10 +2197,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	{  		gTerrainProgram.mName = "Deferred Terrain Shader";          gDeferredTerrainProgram.mFeatures.encodesNormal = true; +        gDeferredTerrainProgram.mFeatures.isDeferred = true;  		gDeferredTerrainProgram.mShaderFiles.clear();  		gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredTerrainProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredTerrainProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredTerrainProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -2098,10 +2211,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredAvatarProgram.mName = "Avatar Shader";  		gDeferredAvatarProgram.mFeatures.hasSkinning = true;          gDeferredAvatarProgram.mFeatures.encodesNormal = true; +        gDeferredAvatarProgram.mFeatures.isDeferred = true;  		gDeferredAvatarProgram.mShaderFiles.clear();  		gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredAvatarProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredAvatarProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredAvatarProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -2121,14 +2235,20 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()          gDeferredAvatarAlphaProgram.mFeatures.hasAtmospherics = true;          gDeferredAvatarAlphaProgram.mFeatures.hasTransport = true;          gDeferredAvatarAlphaProgram.mFeatures.hasGamma = true; +        gDeferredAvatarAlphaProgram.mFeatures.isDeferred = true; +        gDeferredAvatarAlphaProgram.mFeatures.hasShadows = true; +        gDeferredAvatarAlphaProgram.mFeatures.hasIndirect = true;  		gDeferredAvatarAlphaProgram.mShaderFiles.clear();  		gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredAvatarAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1");  		gDeferredAvatarAlphaProgram.addPermutation("IS_AVATAR_SKIN", "1"); -		gDeferredAvatarAlphaProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0"); -		gDeferredAvatarAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +        if (use_sun_shadow) +        { +		    gDeferredAvatarAlphaProgram.addPermutation("HAS_SHADOW", "1"); +        } +		gDeferredAvatarAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredAvatarAlphaProgram.createShader(NULL, NULL);          llassert(success); @@ -2141,10 +2261,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	{  		gDeferredPostGammaCorrectProgram.mName = "Deferred Gamma Correction Post Process";  		gDeferredPostGammaCorrectProgram.mFeatures.hasSrgb = true; +        gDeferredPostGammaCorrectProgram.mFeatures.isDeferred = true;  		gDeferredPostGammaCorrectProgram.mShaderFiles.clear();  		gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredPostGammaCorrectProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredPostGammaCorrectProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredPostGammaCorrectProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -2152,10 +2273,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{  		gFXAAProgram.mName = "FXAA Shader"; +        gFXAAProgram.mFeatures.isDeferred = true;  		gFXAAProgram.mShaderFiles.clear();  		gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER_ARB));  		gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/fxaaF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gFXAAProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gFXAAProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gFXAAProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -2163,10 +2285,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{  		gDeferredPostProgram.mName = "Deferred Post Shader"; +        gFXAAProgram.mFeatures.isDeferred = true;  		gDeferredPostProgram.mShaderFiles.clear();  		gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredPostProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredPostProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredPostProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -2175,9 +2298,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	{  		gDeferredCoFProgram.mName = "Deferred CoF Shader";  		gDeferredCoFProgram.mShaderFiles.clear(); +        gDeferredCoFProgram.mFeatures.isDeferred = true;  		gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/cofF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredCoFProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredCoFProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredCoFProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -2185,10 +2309,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{  		gDeferredDoFCombineProgram.mName = "Deferred DoFCombine Shader"; +        gDeferredDoFCombineProgram.mFeatures.isDeferred = true;  		gDeferredDoFCombineProgram.mShaderFiles.clear();  		gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/dofCombineF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredDoFCombineProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredDoFCombineProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredDoFCombineProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -2196,10 +2321,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{  		gDeferredPostNoDoFProgram.mName = "Deferred Post Shader"; +        gDeferredPostNoDoFProgram.mFeatures.isDeferred = true;  		gDeferredPostNoDoFProgram.mShaderFiles.clear();  		gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoDoFF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredPostNoDoFProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredPostNoDoFProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		success = gDeferredPostNoDoFProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -2212,10 +2338,17 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()          gDeferredWLSkyProgram.mFeatures.calculatesAtmospherics = true;  		gDeferredWLSkyProgram.mFeatures.hasTransport = true;          gDeferredWLSkyProgram.mFeatures.hasGamma = true; +        gDeferredWLSkyProgram.mFeatures.hasSrgb = true; +        gDeferredWLSkyProgram.mFeatures.isDeferred = true; +  		gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyF.glsl", GL_FRAGMENT_SHADER_ARB)); -        gDeferredWLSkyProgram.mShaderLevel = mVertexShaderLevel[SHADER_WINDLIGHT]; +        gDeferredWLSkyProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT];  		gDeferredWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY; +        if (gAtmosphere && gDeferredWLSkyProgram.mShaderLevel > 2) +        { +            gDeferredWLSkyProgram.mExtraLinkObject = gAtmosphere->getAtmosphericShaderForLink(); +        }  		success = gDeferredWLSkyProgram.createShader(NULL, NULL);          llassert(success);  	} @@ -2227,14 +2360,57 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()          gDeferredWLCloudProgram.mFeatures.calculatesAtmospherics = true;  		gDeferredWLCloudProgram.mFeatures.hasTransport = true;          gDeferredWLCloudProgram.mFeatures.hasGamma = true; +        gDeferredWLCloudProgram.mFeatures.hasSrgb = true; +        gDeferredWLCloudProgram.mFeatures.isDeferred = true; +  		gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredWLCloudProgram.mShaderLevel = mVertexShaderLevel[SHADER_WINDLIGHT]; +		gDeferredWLCloudProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT];  		gDeferredWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY; +        if (gAtmosphere && gDeferredWLCloudProgram.mShaderLevel > 2) +        { +            gDeferredWLCloudProgram.mExtraLinkObject = gAtmosphere->getAtmosphericShaderForLink(); +        }  		success = gDeferredWLCloudProgram.createShader(NULL, NULL);          llassert(success);  	} +    if (success && gAtmosphere && (mShaderLevel[SHADER_WINDLIGHT] > 2)) +	{ +		gDeferredGenSkyShProgram.mName = "Deferred Generate Sky Indirect SH Program"; +        gDeferredGenSkyShProgram.mFeatures.decodesNormal = true; + +		gDeferredGenSkyShProgram.mShaderFiles.clear(); +		gDeferredGenSkyShProgram.mShaderFiles.push_back(make_pair("deferred/genSkyShV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredGenSkyShProgram.mShaderFiles.push_back(make_pair("deferred/genSkyShF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredGenSkyShProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT]; +        gDeferredGenSkyShProgram.mExtraLinkObject = gAtmosphere->getAtmosphericShaderForLink(); +		success = gDeferredGenSkyShProgram.createShader(NULL, NULL); +        llassert(success); +	} + +    if (success && gAtmosphere && (mShaderLevel[SHADER_WINDLIGHT] > 2)) +	{ +		gDeferredGatherSkyShProgram.mName = "Deferred Gather Sky Indirect SH Program"; +		gDeferredGatherSkyShProgram.mShaderFiles.clear(); +		gDeferredGatherSkyShProgram.mShaderFiles.push_back(make_pair("deferred/gatherSkyShV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredGatherSkyShProgram.mShaderFiles.push_back(make_pair("deferred/gatherSkyShF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredGatherSkyShProgram.mShaderLevel = 3; +		success = gDeferredGatherSkyShProgram.createShader(NULL, NULL); +        llassert(success); +	} + +    if (success) +	{ +		gDeferredShVisProgram.mName = "Deferred SH Vis Program"; +		gDeferredShVisProgram.mShaderFiles.clear(); +		gDeferredShVisProgram.mShaderFiles.push_back(make_pair("deferred/shVisV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredShVisProgram.mShaderFiles.push_back(make_pair("deferred/shVisF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredShVisProgram.mShaderLevel = 3; +		success = gDeferredShVisProgram.createShader(NULL, NULL); +        llassert(success); +	} +      if (success)  	{  		gDeferredWLSunProgram.mName = "Deferred Windlight Sun Program"; @@ -2244,10 +2420,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredWLSunProgram.mFeatures.hasAtmospherics = true;          gDeferredWLSunProgram.mFeatures.isFullbright = true;  		gDeferredWLSunProgram.mFeatures.disableTextureIndex = true; +        gDeferredWLSunProgram.mFeatures.isDeferred = true;  		gDeferredWLSunProgram.mShaderFiles.clear();  		gDeferredWLSunProgram.mShaderFiles.push_back(make_pair("deferred/sunDiscV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredWLSunProgram.mShaderFiles.push_back(make_pair("deferred/sunDiscF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredWLSunProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredWLSunProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		gDeferredWLSunProgram.mShaderGroup = LLGLSLShader::SG_SKY;  		success = gDeferredWLSunProgram.createShader(NULL, NULL);          llassert(success); @@ -2262,10 +2439,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredWLMoonProgram.mFeatures.hasAtmospherics = true;          gDeferredWLMoonProgram.mFeatures.isFullbright = true;  		gDeferredWLMoonProgram.mFeatures.disableTextureIndex = true; +        gDeferredWLMoonProgram.mFeatures.isDeferred = true; +  		gDeferredWLMoonProgram.mShaderFiles.clear();  		gDeferredWLMoonProgram.mShaderFiles.push_back(make_pair("deferred/moonV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredWLMoonProgram.mShaderFiles.push_back(make_pair("deferred/moonF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredWLMoonProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredWLMoonProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		gDeferredWLMoonProgram.mShaderGroup = LLGLSLShader::SG_SKY;  		success = gDeferredWLMoonProgram.createShader(NULL, NULL);          llassert(success); @@ -2274,10 +2453,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{  		gDeferredStarProgram.mName = "Deferred Star Program"; +        gDeferredStarProgram.mFeatures.isDeferred = true;  		gDeferredStarProgram.mShaderFiles.clear();  		gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredStarProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredStarProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		gDeferredStarProgram.mShaderGroup = LLGLSLShader::SG_SKY;  		success = gDeferredStarProgram.createShader(NULL, NULL);          llassert(success); @@ -2286,10 +2466,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{  		gNormalMapGenProgram.mName = "Normal Map Generation Program"; +        gNormalMapGenProgram.mFeatures.isDeferred = true;  		gNormalMapGenProgram.mShaderFiles.clear();  		gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenV.glsl", GL_VERTEX_SHADER_ARB));  		gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gNormalMapGenProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gNormalMapGenProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		gNormalMapGenProgram.mShaderGroup = LLGLSLShader::SG_SKY;  		success = gNormalMapGenProgram.createShader(NULL, NULL);  	} @@ -2301,7 +2482,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  {  	BOOL success = TRUE; -	if (mVertexShaderLevel[SHADER_OBJECT] == 0) +	if (mShaderLevel[SHADER_OBJECT] == 0)  	{  		gObjectShinyProgram.unload();  		gObjectFullbrightShinyProgram.unload(); @@ -2366,7 +2547,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectSimpleNonIndexedProgram.mShaderFiles.clear();  		gObjectSimpleNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectSimpleNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectSimpleNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectSimpleNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		success = gObjectSimpleNonIndexedProgram.createShader(NULL, NULL);  	} @@ -2382,7 +2563,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectSimpleNonIndexedTexGenProgram.mShaderFiles.clear();  		gObjectSimpleNonIndexedTexGenProgram.mShaderFiles.push_back(make_pair("objects/simpleTexGenV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectSimpleNonIndexedTexGenProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectSimpleNonIndexedTexGenProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectSimpleNonIndexedTexGenProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		success = gObjectSimpleNonIndexedTexGenProgram.createShader(NULL, NULL);  	} @@ -2399,7 +2580,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectSimpleNonIndexedWaterProgram.mShaderFiles.clear();  		gObjectSimpleNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectSimpleNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectSimpleNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectSimpleNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		gObjectSimpleNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  		success = gObjectSimpleNonIndexedWaterProgram.createShader(NULL, NULL);  	} @@ -2416,7 +2597,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectSimpleNonIndexedTexGenWaterProgram.mShaderFiles.clear();  		gObjectSimpleNonIndexedTexGenWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleTexGenV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectSimpleNonIndexedTexGenWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectSimpleNonIndexedTexGenWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectSimpleNonIndexedTexGenWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		gObjectSimpleNonIndexedTexGenWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  		success = gObjectSimpleNonIndexedTexGenWaterProgram.createShader(NULL, NULL);  	} @@ -2434,7 +2615,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectAlphaMaskNonIndexedProgram.mShaderFiles.clear();  		gObjectAlphaMaskNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleNonIndexedV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectAlphaMaskNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectAlphaMaskNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectAlphaMaskNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		success = gObjectAlphaMaskNonIndexedProgram.createShader(NULL, NULL);  	} @@ -2451,7 +2632,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectAlphaMaskNonIndexedWaterProgram.mShaderFiles.clear();  		gObjectAlphaMaskNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleNonIndexedV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectAlphaMaskNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectAlphaMaskNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectAlphaMaskNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		gObjectAlphaMaskNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  		success = gObjectAlphaMaskNonIndexedWaterProgram.createShader(NULL, NULL);  	} @@ -2469,7 +2650,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectAlphaMaskNoColorProgram.mShaderFiles.clear();  		gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleNoColorV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectAlphaMaskNoColorProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectAlphaMaskNoColorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		success = gObjectAlphaMaskNoColorProgram.createShader(NULL, NULL);  	} @@ -2486,7 +2667,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.clear();  		gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleNoColorV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectAlphaMaskNoColorWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectAlphaMaskNoColorWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		gObjectAlphaMaskNoColorWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  		success = gObjectAlphaMaskNoColorWaterProgram.createShader(NULL, NULL);  	} @@ -2504,7 +2685,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gTreeProgram.mShaderFiles.clear();  		gTreeProgram.mShaderFiles.push_back(make_pair("objects/treeV.glsl", GL_VERTEX_SHADER_ARB));  		gTreeProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gTreeProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gTreeProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		success = gTreeProgram.createShader(NULL, NULL);  	} @@ -2521,7 +2702,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gTreeWaterProgram.mShaderFiles.clear();  		gTreeWaterProgram.mShaderFiles.push_back(make_pair("objects/treeV.glsl", GL_VERTEX_SHADER_ARB));  		gTreeWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gTreeWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gTreeWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		gTreeWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  		success = gTreeWaterProgram.createShader(NULL, NULL);  	} @@ -2538,7 +2719,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightNonIndexedProgram.mShaderFiles.clear();  		gObjectFullbrightNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectFullbrightNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectFullbrightNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectFullbrightNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		success = gObjectFullbrightNonIndexedProgram.createShader(NULL, NULL);  	} @@ -2554,7 +2735,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.clear();  		gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectFullbrightNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectFullbrightNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		gObjectFullbrightNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  		success = gObjectFullbrightNonIndexedWaterProgram.createShader(NULL, NULL);  	} @@ -2571,7 +2752,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectEmissiveNonIndexedProgram.mShaderFiles.clear();  		gObjectEmissiveNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectEmissiveNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectEmissiveNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectEmissiveNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		success = gObjectEmissiveNonIndexedProgram.createShader(NULL, NULL);  	} @@ -2586,7 +2767,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectEmissiveNonIndexedWaterProgram.mShaderFiles.clear();  		gObjectEmissiveNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectEmissiveNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectEmissiveNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectEmissiveNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		gObjectEmissiveNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  		success = gObjectEmissiveNonIndexedWaterProgram.createShader(NULL, NULL);  	} @@ -2603,7 +2784,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightNoColorProgram.mShaderFiles.clear();  		gObjectFullbrightNoColorProgram.mShaderFiles.push_back(make_pair("objects/fullbrightNoColorV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectFullbrightNoColorProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectFullbrightNoColorProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectFullbrightNoColorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		success = gObjectFullbrightNoColorProgram.createShader(NULL, NULL);  	} @@ -2618,7 +2799,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightNoColorWaterProgram.mShaderFiles.clear();  		gObjectFullbrightNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightNoColorV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectFullbrightNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectFullbrightNoColorWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectFullbrightNoColorWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		gObjectFullbrightNoColorWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  		success = gObjectFullbrightNoColorWaterProgram.createShader(NULL, NULL);  	} @@ -2635,7 +2816,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectShinyNonIndexedProgram.mShaderFiles.clear();  		gObjectShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB));		 -		gObjectShinyNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectShinyNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		success = gObjectShinyNonIndexedProgram.createShader(NULL, NULL);  	} @@ -2651,7 +2832,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectShinyNonIndexedWaterProgram.mShaderFiles.clear();  		gObjectShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));  		gObjectShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB)); -		gObjectShinyNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectShinyNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		gObjectShinyNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  		success = gObjectShinyNonIndexedWaterProgram.createShader(NULL, NULL);  	} @@ -2668,7 +2849,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.clear();  		gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectFullbrightShinyNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectFullbrightShinyNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		success = gObjectFullbrightShinyNonIndexedProgram.createShader(NULL, NULL);  	} @@ -2685,7 +2866,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.clear();  		gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectFullbrightShinyNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectFullbrightShinyNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		gObjectFullbrightShinyNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  		success = gObjectFullbrightShinyNonIndexedWaterProgram.createShader(NULL, NULL);  	} @@ -2698,7 +2879,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gImpostorProgram.mShaderFiles.clear();  		gImpostorProgram.mShaderFiles.push_back(make_pair("objects/impostorV.glsl", GL_VERTEX_SHADER_ARB));  		gImpostorProgram.mShaderFiles.push_back(make_pair("objects/impostorF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gImpostorProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gImpostorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		success = gImpostorProgram.createShader(NULL, NULL);  	} @@ -2715,7 +2896,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectPreviewProgram.mShaderFiles.clear();  		gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectPreviewProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectPreviewProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		success = gObjectPreviewProgram.createShader(NULL, NULL);  		gObjectPreviewProgram.mFeatures.hasLighting = true;  	} @@ -2732,7 +2913,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectSimpleProgram.mShaderFiles.clear();  		gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectSimpleProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectSimpleProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		success = gObjectSimpleProgram.createShader(NULL, NULL);  	} @@ -2752,7 +2933,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectSimpleImpostorProgram.mShaderFiles.clear();  		gObjectSimpleImpostorProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectSimpleImpostorProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectSimpleImpostorProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectSimpleImpostorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		success = gObjectSimpleImpostorProgram.createShader(NULL, NULL);  	} @@ -2769,7 +2950,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectSimpleWaterProgram.mShaderFiles.clear();  		gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectSimpleWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectSimpleWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		gObjectSimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  		success = gObjectSimpleWaterProgram.createShader(NULL, NULL);  	} @@ -2787,7 +2968,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectBumpProgram.mShaderFiles.clear();  		gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectBumpProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectBumpProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		success = gObjectBumpProgram.createShader(NULL, NULL);  		if (success)  		{ //lldrawpoolbump assumes "texture0" has channel 0 and "texture1" has channel 1 @@ -2812,7 +2993,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectSimpleAlphaMaskProgram.mShaderFiles.clear();  		gObjectSimpleAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectSimpleAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectSimpleAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectSimpleAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		success = gObjectSimpleAlphaMaskProgram.createShader(NULL, NULL);  	} @@ -2829,7 +3010,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectSimpleWaterAlphaMaskProgram.mShaderFiles.clear();  		gObjectSimpleWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectSimpleWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectSimpleWaterAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectSimpleWaterAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		gObjectSimpleWaterAlphaMaskProgram.mShaderGroup = LLGLSLShader::SG_WATER;  		success = gObjectSimpleWaterAlphaMaskProgram.createShader(NULL, NULL);  	} @@ -2846,7 +3027,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightProgram.mShaderFiles.clear();  		gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectFullbrightProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		success = gObjectFullbrightProgram.createShader(NULL, NULL);  	} @@ -2861,7 +3042,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightWaterProgram.mShaderFiles.clear();  		gObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectFullbrightWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectFullbrightWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		gObjectFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  		success = gObjectFullbrightWaterProgram.createShader(NULL, NULL);  	} @@ -2878,7 +3059,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectEmissiveProgram.mShaderFiles.clear();  		gObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectEmissiveProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		success = gObjectEmissiveProgram.createShader(NULL, NULL);  	} @@ -2893,7 +3074,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectEmissiveWaterProgram.mShaderFiles.clear();  		gObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectEmissiveWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectEmissiveWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		gObjectEmissiveWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  		success = gObjectEmissiveWaterProgram.createShader(NULL, NULL);  	} @@ -2911,7 +3092,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightAlphaMaskProgram.mShaderFiles.clear();  		gObjectFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectFullbrightAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		success = gObjectFullbrightAlphaMaskProgram.createShader(NULL, NULL);  	} @@ -2927,7 +3108,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightWaterAlphaMaskProgram.mShaderFiles.clear();  		gObjectFullbrightWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectFullbrightWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectFullbrightWaterAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectFullbrightWaterAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		gObjectFullbrightWaterAlphaMaskProgram.mShaderGroup = LLGLSLShader::SG_WATER;  		success = gObjectFullbrightWaterAlphaMaskProgram.createShader(NULL, NULL);  	} @@ -2944,7 +3125,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectShinyProgram.mShaderFiles.clear();  		gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB));		 -		gObjectShinyProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		success = gObjectShinyProgram.createShader(NULL, NULL);  	} @@ -2960,7 +3141,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectShinyWaterProgram.mShaderFiles.clear();  		gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));  		gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB)); -		gObjectShinyWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectShinyWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		gObjectShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  		success = gObjectShinyWaterProgram.createShader(NULL, NULL);  	} @@ -2977,7 +3158,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightShinyProgram.mShaderFiles.clear();  		gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectFullbrightShinyProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		success = gObjectFullbrightShinyProgram.createShader(NULL, NULL);  	} @@ -2994,12 +3175,12 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightShinyWaterProgram.mShaderFiles.clear();  		gObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectFullbrightShinyWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectFullbrightShinyWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		gObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  		success = gObjectFullbrightShinyWaterProgram.createShader(NULL, NULL);  	} -	if (mVertexShaderLevel[SHADER_AVATAR] > 0) +	if (mShaderLevel[SHADER_AVATAR] > 0)  	{ //load hardware skinned attachment shaders  		if (success)  		{ @@ -3015,7 +3196,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectSimpleProgram.mShaderFiles.clear();  			gSkinnedObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB));  			gSkinnedObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); -			gSkinnedObjectSimpleProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +			gSkinnedObjectSimpleProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  			success = gSkinnedObjectSimpleProgram.createShader(NULL, NULL);  		} @@ -3033,7 +3214,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectFullbrightProgram.mShaderFiles.clear();  			gSkinnedObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB));  			gSkinnedObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); -			gSkinnedObjectFullbrightProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +			gSkinnedObjectFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  			success = gSkinnedObjectFullbrightProgram.createShader(NULL, NULL);  		} @@ -3050,7 +3231,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectEmissiveProgram.mShaderFiles.clear();  			gSkinnedObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/emissiveSkinnedV.glsl", GL_VERTEX_SHADER_ARB));  			gSkinnedObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); -			gSkinnedObjectEmissiveProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +			gSkinnedObjectEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  			success = gSkinnedObjectEmissiveProgram.createShader(NULL, NULL);  		} @@ -3067,7 +3248,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectEmissiveWaterProgram.mShaderFiles.clear();  			gSkinnedObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/emissiveSkinnedV.glsl", GL_VERTEX_SHADER_ARB));  			gSkinnedObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -			gSkinnedObjectEmissiveWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +			gSkinnedObjectEmissiveWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  			success = gSkinnedObjectEmissiveWaterProgram.createShader(NULL, NULL);  		} @@ -3085,7 +3266,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectFullbrightShinyProgram.mShaderFiles.clear();  			gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB));  			gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); -			gSkinnedObjectFullbrightShinyProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +			gSkinnedObjectFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  			success = gSkinnedObjectFullbrightShinyProgram.createShader(NULL, NULL);  		} @@ -3103,7 +3284,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectShinySimpleProgram.mShaderFiles.clear();  			gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB));  			gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB)); -			gSkinnedObjectShinySimpleProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +			gSkinnedObjectShinySimpleProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  			success = gSkinnedObjectShinySimpleProgram.createShader(NULL, NULL);  		} @@ -3124,7 +3305,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectSimpleWaterProgram.mShaderFiles.clear();  			gSkinnedObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB));  			gSkinnedObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -			gSkinnedObjectSimpleWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +			gSkinnedObjectSimpleWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  			success = gSkinnedObjectSimpleWaterProgram.createShader(NULL, NULL);  		} @@ -3143,7 +3324,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectFullbrightWaterProgram.mShaderFiles.clear();  			gSkinnedObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB));  			gSkinnedObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -			gSkinnedObjectFullbrightWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +			gSkinnedObjectFullbrightWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  			success = gSkinnedObjectFullbrightWaterProgram.createShader(NULL, NULL);  		} @@ -3163,7 +3344,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.clear();  			gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB));  			gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -			gSkinnedObjectFullbrightShinyWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +			gSkinnedObjectFullbrightShinyWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  			success = gSkinnedObjectFullbrightShinyWaterProgram.createShader(NULL, NULL);  		} @@ -3183,14 +3364,14 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.clear();  			gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB));  			gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -			gSkinnedObjectShinySimpleWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +			gSkinnedObjectShinySimpleWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  			success = gSkinnedObjectShinySimpleWaterProgram.createShader(NULL, NULL);  		}  	}  	if( !success )  	{ -		mVertexShaderLevel[SHADER_OBJECT] = 0; +		mShaderLevel[SHADER_OBJECT] = 0;  		return FALSE;  	} @@ -3201,7 +3382,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()  {  	BOOL success = TRUE; -	if (mVertexShaderLevel[SHADER_AVATAR] == 0) +	if (mShaderLevel[SHADER_AVATAR] == 0)  	{  		gAvatarProgram.unload();  		gAvatarWaterProgram.unload(); @@ -3224,7 +3405,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()  		gAvatarProgram.mShaderFiles.clear();  		gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER_ARB));  		gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gAvatarProgram.mShaderLevel = mVertexShaderLevel[SHADER_AVATAR]; +		gAvatarProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR];  		success = gAvatarProgram.createShader(NULL, NULL);  		if (success) @@ -3242,15 +3423,15 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()  			gAvatarWaterProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER_ARB));  			gAvatarWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));  			// Note: no cloth under water: -			gAvatarWaterProgram.mShaderLevel = llmin(mVertexShaderLevel[SHADER_AVATAR], 1);	 +			gAvatarWaterProgram.mShaderLevel = llmin(mShaderLevel[SHADER_AVATAR], 1);	  			gAvatarWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;				  			success = gAvatarWaterProgram.createShader(NULL, NULL);  		}  		/// Keep track of avatar levels -		if (gAvatarProgram.mShaderLevel != mVertexShaderLevel[SHADER_AVATAR]) +		if (gAvatarProgram.mShaderLevel != mShaderLevel[SHADER_AVATAR])  		{ -			mMaxAvatarShaderLevel = mVertexShaderLevel[SHADER_AVATAR] = gAvatarProgram.mShaderLevel; +			mMaxAvatarShaderLevel = mShaderLevel[SHADER_AVATAR] = gAvatarProgram.mShaderLevel;  		}  	} @@ -3262,7 +3443,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()  		gAvatarPickProgram.mShaderFiles.clear();  		gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarV.glsl", GL_VERTEX_SHADER_ARB));  		gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gAvatarPickProgram.mShaderLevel = mVertexShaderLevel[SHADER_AVATAR]; +		gAvatarPickProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR];  		success = gAvatarPickProgram.createShader(NULL, NULL);  	} @@ -3280,13 +3461,13 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()  		gAvatarEyeballProgram.mShaderFiles.clear();  		gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballV.glsl", GL_VERTEX_SHADER_ARB));  		gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gAvatarEyeballProgram.mShaderLevel = mVertexShaderLevel[SHADER_AVATAR]; +		gAvatarEyeballProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR];  		success = gAvatarEyeballProgram.createShader(NULL, NULL);  	}  	if( !success )  	{ -		mVertexShaderLevel[SHADER_AVATAR] = 0; +		mShaderLevel[SHADER_AVATAR] = 0;  		mMaxAvatarShaderLevel = 0;  		return FALSE;  	} @@ -3298,7 +3479,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  {  	BOOL success = TRUE; -	if (mVertexShaderLevel[SHADER_INTERFACE] == 0) +	if (mShaderLevel[SHADER_INTERFACE] == 0)  	{  		gHighlightProgram.unload();  		return TRUE; @@ -3310,7 +3491,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  		gHighlightProgram.mShaderFiles.clear();  		gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER_ARB));  		gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gHighlightProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];		 +		gHighlightProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];		  		success = gHighlightProgram.createShader(NULL, NULL);  	} @@ -3320,7 +3501,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  		gHighlightNormalProgram.mShaderFiles.clear();  		gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightNormV.glsl", GL_VERTEX_SHADER_ARB));  		gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gHighlightNormalProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];		 +		gHighlightNormalProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];		  		success = gHighlightNormalProgram.createShader(NULL, NULL);  	} @@ -3330,7 +3511,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  		gHighlightSpecularProgram.mShaderFiles.clear();  		gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightSpecV.glsl", GL_VERTEX_SHADER_ARB));  		gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gHighlightSpecularProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];		 +		gHighlightSpecularProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];		  		success = gHighlightSpecularProgram.createShader(NULL, NULL);  	} @@ -3340,7 +3521,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  		gUIProgram.mShaderFiles.clear();  		gUIProgram.mShaderFiles.push_back(make_pair("interface/uiV.glsl", GL_VERTEX_SHADER_ARB));  		gUIProgram.mShaderFiles.push_back(make_pair("interface/uiF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gUIProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; +		gUIProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];  		success = gUIProgram.createShader(NULL, NULL);  	} @@ -3350,7 +3531,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  		gPathfindingProgram.mShaderFiles.clear();  		gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingV.glsl", GL_VERTEX_SHADER_ARB));  		gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gPathfindingProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; +		gPathfindingProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];  		success = gPathfindingProgram.createShader(NULL, NULL);  	} @@ -3360,7 +3541,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  		gPathfindingNoNormalsProgram.mShaderFiles.clear();  		gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingNoNormalV.glsl", GL_VERTEX_SHADER_ARB));  		gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gPathfindingNoNormalsProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; +		gPathfindingNoNormalsProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];  		success = gPathfindingNoNormalsProgram.createShader(NULL, NULL);  	} @@ -3370,7 +3551,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  		gCustomAlphaProgram.mShaderFiles.clear();  		gCustomAlphaProgram.mShaderFiles.push_back(make_pair("interface/customalphaV.glsl", GL_VERTEX_SHADER_ARB));  		gCustomAlphaProgram.mShaderFiles.push_back(make_pair("interface/customalphaF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gCustomAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; +		gCustomAlphaProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];  		success = gCustomAlphaProgram.createShader(NULL, NULL);  	} @@ -3380,7 +3561,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  		gSplatTextureRectProgram.mShaderFiles.clear();  		gSplatTextureRectProgram.mShaderFiles.push_back(make_pair("interface/splattexturerectV.glsl", GL_VERTEX_SHADER_ARB));  		gSplatTextureRectProgram.mShaderFiles.push_back(make_pair("interface/splattexturerectF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gSplatTextureRectProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; +		gSplatTextureRectProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];  		success = gSplatTextureRectProgram.createShader(NULL, NULL);  		if (success)  		{ @@ -3396,7 +3577,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  		gGlowCombineProgram.mShaderFiles.clear();  		gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineV.glsl", GL_VERTEX_SHADER_ARB));  		gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gGlowCombineProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; +		gGlowCombineProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];  		success = gGlowCombineProgram.createShader(NULL, NULL);  		if (success)  		{ @@ -3413,7 +3594,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  		gGlowCombineFXAAProgram.mShaderFiles.clear();  		gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAV.glsl", GL_VERTEX_SHADER_ARB));  		gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gGlowCombineFXAAProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; +		gGlowCombineFXAAProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];  		success = gGlowCombineFXAAProgram.createShader(NULL, NULL);  		if (success)  		{ @@ -3431,7 +3612,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  		gTwoTextureAddProgram.mShaderFiles.clear();  		gTwoTextureAddProgram.mShaderFiles.push_back(make_pair("interface/twotextureaddV.glsl", GL_VERTEX_SHADER_ARB));  		gTwoTextureAddProgram.mShaderFiles.push_back(make_pair("interface/twotextureaddF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gTwoTextureAddProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; +		gTwoTextureAddProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];  		success = gTwoTextureAddProgram.createShader(NULL, NULL);  		if (success)  		{ @@ -3448,7 +3629,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  		gTwoTextureCompareProgram.mShaderFiles.clear();  		gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareV.glsl", GL_VERTEX_SHADER_ARB));  		gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gTwoTextureCompareProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; +		gTwoTextureCompareProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];  		success = gTwoTextureCompareProgram.createShader(NULL, NULL);  		if (success)  		{ @@ -3465,7 +3646,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  		gOneTextureFilterProgram.mShaderFiles.clear();  		gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterV.glsl", GL_VERTEX_SHADER_ARB));  		gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gOneTextureFilterProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; +		gOneTextureFilterProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];  		success = gOneTextureFilterProgram.createShader(NULL, NULL);  		if (success)  		{ @@ -3481,7 +3662,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  		gOneTextureNoColorProgram.mShaderFiles.clear();  		gOneTextureNoColorProgram.mShaderFiles.push_back(make_pair("interface/onetexturenocolorV.glsl", GL_VERTEX_SHADER_ARB));  		gOneTextureNoColorProgram.mShaderFiles.push_back(make_pair("interface/onetexturenocolorF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gOneTextureNoColorProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; +		gOneTextureNoColorProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];  		success = gOneTextureNoColorProgram.createShader(NULL, NULL);  		if (success)  		{ @@ -3496,7 +3677,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  		gSolidColorProgram.mShaderFiles.clear();  		gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorV.glsl", GL_VERTEX_SHADER_ARB));  		gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gSolidColorProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; +		gSolidColorProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];  		success = gSolidColorProgram.createShader(NULL, NULL);  		if (success)  		{ @@ -3512,7 +3693,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  		gOcclusionProgram.mShaderFiles.clear();  		gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionV.glsl", GL_VERTEX_SHADER_ARB));  		gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gOcclusionProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; +		gOcclusionProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];  		success = gOcclusionProgram.createShader(NULL, NULL);  	} @@ -3522,7 +3703,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  		gOcclusionCubeProgram.mShaderFiles.clear();  		gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionCubeV.glsl", GL_VERTEX_SHADER_ARB));  		gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gOcclusionCubeProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; +		gOcclusionCubeProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];  		success = gOcclusionCubeProgram.createShader(NULL, NULL);  	} @@ -3532,7 +3713,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  		gDebugProgram.mShaderFiles.clear();  		gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugV.glsl", GL_VERTEX_SHADER_ARB));  		gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDebugProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; +		gDebugProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];  		success = gDebugProgram.createShader(NULL, NULL);  	} @@ -3542,7 +3723,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  		gClipProgram.mShaderFiles.clear();  		gClipProgram.mShaderFiles.push_back(make_pair("interface/clipV.glsl", GL_VERTEX_SHADER_ARB));  		gClipProgram.mShaderFiles.push_back(make_pair("interface/clipF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gClipProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; +		gClipProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];  		success = gClipProgram.createShader(NULL, NULL);  	} @@ -3552,7 +3733,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  		gDownsampleDepthProgram.mShaderFiles.clear();  		gDownsampleDepthProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthV.glsl", GL_VERTEX_SHADER_ARB));  		gDownsampleDepthProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDownsampleDepthProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; +		gDownsampleDepthProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];  		success = gDownsampleDepthProgram.createShader(NULL, NULL);  	} @@ -3562,7 +3743,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  		gBenchmarkProgram.mShaderFiles.clear();  		gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkV.glsl", GL_VERTEX_SHADER_ARB));  		gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gBenchmarkProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; +		gBenchmarkProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];  		success = gBenchmarkProgram.createShader(NULL, NULL);  	} @@ -3572,7 +3753,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  		gDownsampleDepthRectProgram.mShaderFiles.clear();  		gDownsampleDepthRectProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthV.glsl", GL_VERTEX_SHADER_ARB));  		gDownsampleDepthRectProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthRectF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDownsampleDepthRectProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; +		gDownsampleDepthRectProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];  		success = gDownsampleDepthRectProgram.createShader(NULL, NULL);  	} @@ -3582,13 +3763,13 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  		gAlphaMaskProgram.mShaderFiles.clear();  		gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskV.glsl", GL_VERTEX_SHADER_ARB));  		gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; +		gAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];  		success = gAlphaMaskProgram.createShader(NULL, NULL);  	}  	if( !success )  	{ -		mVertexShaderLevel[SHADER_INTERFACE] = 0; +		mShaderLevel[SHADER_INTERFACE] = 0;  		return FALSE;  	} @@ -3599,7 +3780,7 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()  {  	BOOL success = TRUE; -	if (mVertexShaderLevel[SHADER_WINDLIGHT] < 2) +	if (mShaderLevel[SHADER_WINDLIGHT] < 2)  	{  		gWLSkyProgram.unload();  		gWLCloudProgram.unload(); @@ -3612,7 +3793,7 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()  #if USE_ADVANCED_ATMOSPHERICS  // disabled until we can determine why low-end machines crash during this init... -    if (mVertexShaderLevel[SHADER_WINDLIGHT] > 1) +    if (gSavedSettings.getBOOL("RenderUseAdvancedAtmospherics") && mShaderLevel[SHADER_WINDLIGHT] > 2)      {          // Prepare precomputed atmospherics textures using libatmosphere          LLAtmosphere::initClass(); @@ -3629,7 +3810,7 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()          gWLSkyProgram.mFeatures.hasGamma = true;  		gWLSkyProgram.mShaderFiles.push_back(make_pair("windlight/skyV.glsl", GL_VERTEX_SHADER_ARB));  		gWLSkyProgram.mShaderFiles.push_back(make_pair("windlight/skyF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gWLSkyProgram.mShaderLevel = mVertexShaderLevel[SHADER_WINDLIGHT]; +		gWLSkyProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT];  		gWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY;  		success = gWLSkyProgram.createShader(NULL, NULL);  	} @@ -3644,7 +3825,7 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()          gWLCloudProgram.mFeatures.hasGamma = true;  		gWLCloudProgram.mShaderFiles.push_back(make_pair("windlight/cloudsV.glsl", GL_VERTEX_SHADER_ARB));  		gWLCloudProgram.mShaderFiles.push_back(make_pair("windlight/cloudsF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gWLCloudProgram.mShaderLevel = mVertexShaderLevel[SHADER_WINDLIGHT]; +		gWLCloudProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT];  		gWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY;  		success = gWLCloudProgram.createShader(NULL, NULL);  	} @@ -3662,7 +3843,7 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()  		gWLSunProgram.mShaderGroup = LLGLSLShader::SG_SKY;  		gWLSunProgram.mShaderFiles.push_back(make_pair("windlight/sunDiscV.glsl", GL_VERTEX_SHADER_ARB));  		gWLSunProgram.mShaderFiles.push_back(make_pair("windlight/sunDiscF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gWLSunProgram.mShaderLevel = mVertexShaderLevel[SHADER_WINDLIGHT]; +		gWLSunProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT];  		gWLSunProgram.mShaderGroup = LLGLSLShader::SG_SKY;  		success = gWLSunProgram.createShader(NULL, NULL);  	} @@ -3680,7 +3861,7 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()  		gWLMoonProgram.mShaderGroup = LLGLSLShader::SG_SKY;  		gWLMoonProgram.mShaderFiles.push_back(make_pair("windlight/moonV.glsl", GL_VERTEX_SHADER_ARB));  		gWLMoonProgram.mShaderFiles.push_back(make_pair("windlight/moonF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gWLMoonProgram.mShaderLevel = mVertexShaderLevel[SHADER_WINDLIGHT]; +		gWLMoonProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT];  		gWLMoonProgram.mShaderGroup = LLGLSLShader::SG_SKY;  		success = gWLMoonProgram.createShader(NULL, NULL);  	} @@ -3692,7 +3873,7 @@ BOOL LLViewerShaderMgr::loadTransformShaders()  {  	BOOL success = TRUE; -	if (mVertexShaderLevel[SHADER_TRANSFORM] < 1) +	if (mShaderLevel[SHADER_TRANSFORM] < 1)  	{  		gTransformPositionProgram.unload();  		gTransformTexCoordProgram.unload(); @@ -3707,7 +3888,7 @@ BOOL LLViewerShaderMgr::loadTransformShaders()  		gTransformPositionProgram.mName = "Position Transform Shader";  		gTransformPositionProgram.mShaderFiles.clear();  		gTransformPositionProgram.mShaderFiles.push_back(make_pair("transform/positionV.glsl", GL_VERTEX_SHADER_ARB)); -		gTransformPositionProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM]; +		gTransformPositionProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM];  		const char* varyings[] = {  			"position_out", @@ -3722,7 +3903,7 @@ BOOL LLViewerShaderMgr::loadTransformShaders()  		gTransformTexCoordProgram.mName = "TexCoord Transform Shader";  		gTransformTexCoordProgram.mShaderFiles.clear();  		gTransformTexCoordProgram.mShaderFiles.push_back(make_pair("transform/texcoordV.glsl", GL_VERTEX_SHADER_ARB)); -		gTransformTexCoordProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM]; +		gTransformTexCoordProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM];  		const char* varyings[] = {  			"texcoord_out", @@ -3736,7 +3917,7 @@ BOOL LLViewerShaderMgr::loadTransformShaders()  		gTransformNormalProgram.mName = "Normal Transform Shader";  		gTransformNormalProgram.mShaderFiles.clear();  		gTransformNormalProgram.mShaderFiles.push_back(make_pair("transform/normalV.glsl", GL_VERTEX_SHADER_ARB)); -		gTransformNormalProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM]; +		gTransformNormalProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM];  		const char* varyings[] = {  			"normal_out", @@ -3750,7 +3931,7 @@ BOOL LLViewerShaderMgr::loadTransformShaders()  		gTransformColorProgram.mName = "Color Transform Shader";  		gTransformColorProgram.mShaderFiles.clear();  		gTransformColorProgram.mShaderFiles.push_back(make_pair("transform/colorV.glsl", GL_VERTEX_SHADER_ARB)); -		gTransformColorProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM]; +		gTransformColorProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM];  		const char* varyings[] = {  			"color_out", @@ -3764,7 +3945,7 @@ BOOL LLViewerShaderMgr::loadTransformShaders()  		gTransformTangentProgram.mName = "Binormal Transform Shader";  		gTransformTangentProgram.mShaderFiles.clear();  		gTransformTangentProgram.mShaderFiles.push_back(make_pair("transform/binormalV.glsl", GL_VERTEX_SHADER_ARB)); -		gTransformTangentProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM]; +		gTransformTangentProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM];  		const char* varyings[] = {  			"tangent_out", diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 250f8f1ee3..75438bcff7 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -48,7 +48,7 @@ public:  	void initAttribsAndUniforms(void);  	void setShaders();  	void unloadShaders(); -	S32 getVertexShaderLevel(S32 type); +    S32  getShaderLevel(S32 type);  	BOOL loadBasicShaders();  	BOOL loadShadersEffects();  	BOOL loadShadersDeferred(); @@ -60,7 +60,7 @@ public:  	BOOL loadShadersWindLight();  	BOOL loadTransformShaders(); -	std::vector<S32> mVertexShaderLevel; +	std::vector<S32> mShaderLevel;  	S32	mMaxAvatarShaderLevel;  	enum EShaderClass @@ -325,6 +325,10 @@ extern LLGLSLShader			gDeferredSkinnedFullbrightShinyProgram;  extern LLGLSLShader			gDeferredSkinnedFullbrightProgram;  extern LLGLSLShader			gNormalMapGenProgram; +extern LLGLSLShader			gDeferredGenSkyShProgram; +extern LLGLSLShader			gDeferredGatherSkyShProgram; +extern LLGLSLShader			gDeferredShVisProgram; +  // Deferred materials shaders  extern LLGLSLShader			gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];  extern LLGLSLShader			gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2]; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 321f774210..cc030dfb60 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -2950,7 +2950,7 @@ void LLVOAvatar::idleUpdateLoadingEffect()  void LLVOAvatar::idleUpdateWindEffect()  {  	// update wind effect -	if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) >= LLDrawPoolAvatar::SHADER_LEVEL_CLOTH)) +	if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) >= LLDrawPoolAvatar::SHADER_LEVEL_CLOTH))  	{  		F32 hover_strength = 0.f;  		F32 time_delta = mRippleTimer.getElapsedTimeF32() - mRippleTimeLast; @@ -4651,7 +4651,7 @@ U32 LLVOAvatar::renderSkinned()  		}  	} -	if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) <= 0) +	if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) <= 0)  	{  		if (mNeedsSkin)  		{ diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index d30bb260e1..54ec238fde 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -48,42 +48,156 @@  #include "llworld.h"  #include "pipeline.h"  #include "lldrawpoolwlsky.h" -#include "v3colorutil.h" - -#include "llsettingssky.h" -#include "llenvironment.h" - -#include "lltrace.h" -#include "llfasttimer.h" +#include "llwlparammanager.h" +#include "llwaterparammanager.h"  #undef min  #undef max -namespace +#if LL_WINDOWS +#pragma optimize("", off) +#endif + +static const S32 NUM_TILES_X = 8; +static const S32 NUM_TILES_Y = 4; +static const S32 NUM_TILES = NUM_TILES_X * NUM_TILES_Y; + +// Heavenly body constants +static const F32 SUN_DISK_RADIUS	= 0.5f; +static const F32 MOON_DISK_RADIUS	= SUN_DISK_RADIUS * 0.9f; +static const F32 SUN_INTENSITY = 1e5; + +// Texture coordinates: +static const LLVector2 TEX00 = LLVector2(0.f, 0.f); +static const LLVector2 TEX01 = LLVector2(0.f, 1.f); +static const LLVector2 TEX10 = LLVector2(1.f, 0.f); +static const LLVector2 TEX11 = LLVector2(1.f, 1.f); + +// Exported globals +LLUUID gSunTextureID = IMG_SUN; +LLUUID gMoonTextureID = IMG_MOON; + +class LLFastLn  { -    const S32 NUM_TILES_X = 8; -    const S32 NUM_TILES_Y = 4; -    const S32 NUM_TILES = NUM_TILES_X * NUM_TILES_Y; +public: +	LLFastLn()  +	{ +		mTable[0] = 0; +		for( S32 i = 1; i < 257; i++ ) +		{ +			mTable[i] = log((F32)i); +		} +	} + +	F32 ln( F32 x ) +	{ +		const F32 OO_255 = 0.003921568627450980392156862745098f; +		const F32 LN_255 = 5.5412635451584261462455391880218f; + +		if( x < OO_255 ) +		{ +			return log(x); +		} +		else +		if( x < 1 ) +		{ +			x *= 255.f; +			S32 index = llfloor(x); +			F32 t = x - index; +			F32 low = mTable[index]; +			F32 high = mTable[index + 1]; +			return low + t * (high - low) - LN_255; +		} +		else +		if( x <= 255 ) +		{ +			S32 index = llfloor(x); +			F32 t = x - index; +			F32 low = mTable[index]; +			F32 high = mTable[index + 1]; +			return low + t * (high - low); +		} +		else +		{ +			return log( x ); +		} +	} + +	F32 pow( F32 x, F32 y ) +	{ +		return (F32)LL_FAST_EXP(y * ln(x)); +	} + + +private: +	F32 mTable[257]; // index 0 is unused +}; + +static LLFastLn gFastLn; -    // Heavenly body constants -    const F32 SUN_DISK_RADIUS	= 0.5f; -    const F32 MOON_DISK_RADIUS	= SUN_DISK_RADIUS * 0.9f; -    const F32 SUN_INTENSITY = 1e5; -    // Texture coordinates: -    const LLVector2 TEX00 = LLVector2(0.f, 0.f); -    const LLVector2 TEX01 = LLVector2(0.f, 1.f); -    const LLVector2 TEX10 = LLVector2(1.f, 0.f); -    const LLVector2 TEX11 = LLVector2(1.f, 1.f); +// Functions used a lot. -    const F32 LIGHT_DIRECTION_THRESHOLD = (F32) cosf(DEG_TO_RAD * 1.f); -    const F32 COLOR_CHANGE_THRESHOLD = 0.01f; +inline F32 LLHaze::calcPhase(const F32 cos_theta) const +{ +	const F32 g2 = mG * mG; +	const F32 den = 1 + g2 - 2 * mG * cos_theta; +	return (1 - g2) * gFastLn.pow(den, -1.5); +} + +inline void color_pow(LLColor3 &col, const F32 e) +{ +	col.mV[0] = gFastLn.pow(col.mV[0], e); +	col.mV[1] = gFastLn.pow(col.mV[1], e); +	col.mV[2] = gFastLn.pow(col.mV[2], e); +} -    LLTrace::BlockTimerStatHandle FTM_VOSKY_UPDATETIMER("VOSky Update Timer Tick"); -    LLTrace::BlockTimerStatHandle FTM_VOSKY_UPDATEFORCED("VOSky Update Forced"); +inline LLColor3 color_norm(const LLColor3 &col) +{ +	const F32 m = color_max(col); +	if (m > 1.f) +	{ +		return 1.f/m * col; +	} +	else return col; +} + +inline void color_gamma_correct(LLColor3 &col) +{ +	const F32 gamma_inv = 1.f/1.2f; +	if (col.mV[0] != 0.f) +	{ +		col.mV[0] = gFastLn.pow(col.mV[0], gamma_inv); +	} +	if (col.mV[1] != 0.f) +	{ +		col.mV[1] = gFastLn.pow(col.mV[1], gamma_inv); +	} +	if (col.mV[2] != 0.f) +	{ +		col.mV[2] = gFastLn.pow(col.mV[2], gamma_inv); +	} +} -    F32Seconds UPDATE_EXPRY(2.0f); +static LLColor3 calc_air_sca_sea_level() +{ +	static LLColor3 WAVE_LEN(675, 520, 445); +	static LLColor3 refr_ind = refr_ind_calc(WAVE_LEN); +	static LLColor3 n21 = refr_ind * refr_ind - LLColor3(1, 1, 1); +	static LLColor3 n4 = n21 * n21; +	static LLColor3 wl2 = WAVE_LEN * WAVE_LEN * 1e-6f; +	static LLColor3 wl4 = wl2 * wl2; +	static LLColor3 mult_const = fsigma * 2.0f/ 3.0f * 1e24f * (F_PI * F_PI) * n4; +	static F32 dens_div_N = F32( ATM_SEA_LEVEL_NDENS / Ndens2); +	return dens_div_N * color_div ( mult_const, wl4 );  } + +// static constants. +LLColor3 const LLHaze::sAirScaSeaLevel = calc_air_sca_sea_level(); +F32 const LLHaze::sAirScaIntense = color_intens(LLHaze::sAirScaSeaLevel);	 +F32 const LLHaze::sAirScaAvg = LLHaze::sAirScaIntense / 3.f; + +  /***************************************  		SkyTex  ***************************************/ @@ -139,32 +253,6 @@ LLSkyTex::~LLSkyTex()  	mSkyDirs = NULL;  } -S32 LLSkyTex::getResolution() -{ -    return sResolution; -} - -S32 LLSkyTex::getCurrent() -{ -    return sCurrent; -} - -S32 LLSkyTex::stepCurrent() { -    sCurrent++; -    sCurrent &= 1; -    return sCurrent; -} - -S32 LLSkyTex::getNext() -{ -    return ((sCurrent+1) & 1); -} - -S32 LLSkyTex::getWhich(const BOOL curr) -{ -    int tex = curr ? sCurrent : getNext(); -    return tex; -}  void LLSkyTex::initEmpty(const S32 tex)  { @@ -205,6 +293,9 @@ void LLSkyTex::create(const F32 brightness)  	createGLImage(sCurrent);  } + + +  void LLSkyTex::createGLImage(S32 which)  {	  	mTexture[which]->createGLTexture(0, mImageRaw[which], 0, TRUE, LLGLTexture::LOCAL); @@ -213,175 +304,14 @@ void LLSkyTex::createGLImage(S32 which)  void LLSkyTex::bindTexture(BOOL curr)  { -    int tex = getWhich(curr); -	gGL.getTexUnit(0)->bind(mTexture[tex], true); -} - -LLImageRaw* LLSkyTex::getImageRaw(BOOL curr) -{ -    int tex = getWhich(curr); -    return mImageRaw[tex]; -} - -/*************************************** -    LLHeavenBody -***************************************/ - -F32	LLHeavenBody::sInterpVal = 0; - -LLHeavenBody::LLHeavenBody(const F32 rad) -: mDirectionCached(LLVector3(0,0,0)), -  mDirection(LLVector3(0,0,0)), -  mIntensity(0.f), -  mDiskRadius(rad), -  mDraw(FALSE), -  mHorizonVisibility(1.f), -  mVisibility(1.f), -  mVisible(FALSE) -{ -	mColor.setToBlack(); -	mColorCached.setToBlack(); -} - -const LLVector3& LLHeavenBody::getDirection() const -{ -    return mDirection; -} - -void LLHeavenBody::setDirection(const LLVector3 &direction) -{ -    mDirection = direction; -} - -void LLHeavenBody::setAngularVelocity(const LLVector3 &ang_vel) -{ -    mAngularVelocity = ang_vel; -} - -const LLVector3& LLHeavenBody::getAngularVelocity() const -{ -    return mAngularVelocity; -} - -const LLVector3& LLHeavenBody::getDirectionCached() const -{ -    return mDirectionCached; -} - -void LLHeavenBody::renewDirection() -{ -    mDirectionCached = mDirection; -} - -const LLColor3& LLHeavenBody::getColorCached() const -{ -    return mColorCached; -} - -void LLHeavenBody::setColorCached(const LLColor3& c) -{ -    mColorCached = c; -} - -const LLColor3& LLHeavenBody::getColor() const -{ -    return mColor; -} - -void LLHeavenBody::setColor(const LLColor3& c) -{ -    mColor = c; -} - -void LLHeavenBody::renewColor() -{ -    mColorCached = mColor; -} - -F32 LLHeavenBody::interpVal() -{ -    return sInterpVal; -} - -void LLHeavenBody::setInterpVal(const F32 v) -{ -    sInterpVal = v; -} - -LLColor3 LLHeavenBody::getInterpColor() const -{ -	return sInterpVal * mColor + (1 - sInterpVal) * mColorCached; -} - -const F32& LLHeavenBody::getVisibility() const -{ -    return mVisibility; -} - -void LLHeavenBody::setVisibility(const F32 c) -{ -    mVisibility = c; -} - -bool LLHeavenBody::isVisible() const -{ -    return mVisible; -} - -void LLHeavenBody::setVisible(const bool v) -{ -    mVisible = v; -} - -const F32& LLHeavenBody::getIntensity() const -{ -    return mIntensity; -} - -void LLHeavenBody::setIntensity(const F32 c) -{ -    mIntensity = c; -} - -void LLHeavenBody::setDiskRadius(const F32 radius) -{ -    mDiskRadius = radius; -} - -F32	LLHeavenBody::getDiskRadius() const -{ -    return mDiskRadius; -} - -void LLHeavenBody::setDraw(const bool draw) -{ -    mDraw = draw; -} - -bool LLHeavenBody::getDraw() const -{ -    return mDraw; -} - -const LLVector3& LLHeavenBody::corner(const S32 n) const -{ -    return mQuadCorner[n]; -} - -LLVector3& LLHeavenBody::corner(const S32 n) -{ -    return mQuadCorner[n]; -} - -const LLVector3* LLHeavenBody::corners() const -{ -    return mQuadCorner; +	gGL.getTexUnit(0)->bind(mTexture[getWhich(curr)], true);  }  /***************************************  		Sky  ***************************************/ +F32	LLHeavenBody::sInterpVal = 0;  S32 LLVOSky::sResolution = LLSkyTex::getResolution();  S32 LLVOSky::sTileResX = sResolution/NUM_TILES_X; @@ -400,15 +330,32 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)  	mWorldScale(1.f),  	mBumpSunDir(0.f, 0.f, 1.f)  { +	bool error = false; +	  	/// WL PARAMS +	dome_radius = 1.f; +	dome_offset_ratio = 0.f; +	sunlight_color = LLColor3(); +	ambient = LLColor3(); +	gamma = 1.f; +	lightnorm = LLVector4(); +	blue_density = LLColor3(); +	blue_horizon = LLColor3(); +	haze_density = 0.f; +	haze_horizon = 1.f; +	density_multiplier = 0.f; +	max_y = 0.f; +	glow = LLColor3(); +	cloud_shadow = 0.f; +	cloud_color = LLColor3(); +	cloud_scale = 0.f; +	cloud_pos_density1 = LLColor3(); +	cloud_pos_density2 = LLColor3();  	mInitialized = FALSE;  	mbCanSelect = FALSE;  	mUpdateTimer.reset(); -    mForceUpdateThrottle.setTimerExpirySec(UPDATE_EXPRY); -    mForceUpdateThrottle.reset(); -  	for (S32 i = 0; i < 6; i++)  	{  		mSkyTex[i].init(); @@ -423,13 +370,33 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)  	mAtmHeight = ATM_HEIGHT;  	mEarthCenter = LLVector3(mCameraPosAgent.mV[0], mCameraPosAgent.mV[1], -EARTH_RADIUS); +	mSunDefaultPosition = LLVector3(LLWLParamManager::getInstance()->mCurParams.getVector("lightnorm", error)); +	if (gSavedSettings.getBOOL("SkyOverrideSimSunPosition")) +	{ +		initSunDirection(mSunDefaultPosition, LLVector3(0, 0, 0)); +	} +	mAmbientScale = gSavedSettings.getF32("SkyAmbientScale"); +	mNightColorShift = gSavedSettings.getColor3("SkyNightColorShift"); +	mFogColor.mV[VRED] = mFogColor.mV[VGREEN] = mFogColor.mV[VBLUE] = 0.5f; +	mFogColor.mV[VALPHA] = 0.0f; +	mFogRatio = 1.2f; +  	mSun.setIntensity(SUN_INTENSITY);  	mMoon.setIntensity(0.1f * SUN_INTENSITY); +	mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); +	mSunTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); +	mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); +	mMoonTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); +	mBloomTexturep = LLViewerTextureManager::getFetchedTexture(IMG_BLOOM1); +	mBloomTexturep->setNoDelete() ; +	mBloomTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); +  	mHeavenlyBodyUpdated = FALSE ;  	mDrawRefl = 0; -	mInterpVal = 0.f;     +	mHazeConcentration = 0.f; +	mInterpVal = 0.f;  } @@ -443,32 +410,11 @@ LLVOSky::~LLVOSky()  void LLVOSky::init()  { -    llassert(!mInitialized); - -    // Update sky at least once to get correct initial sun/moon directions and lighting calcs performed -    LLEnvironment::instance().getCurrentSky()->update(); - -	updateDirections(); - -    LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - -    // invariants across whole sky tex process... -    m_atmosphericsVars.blue_density = psky->getBlueDensity();     -    m_atmosphericsVars.blue_horizon = psky->getBlueHorizon(); -    m_atmosphericsVars.haze_density = psky->getHazeDensity(); -    m_atmosphericsVars.haze_horizon = psky->getHazeHorizon(); -    m_atmosphericsVars.density_multiplier = psky->getDensityMultiplier(); -    m_atmosphericsVars.max_y = psky->getMaxY(); -    m_atmosphericsVars.sun_norm = LLEnvironment::instance().getClampedSunNorm(); -    m_atmosphericsVars.sunlight = psky->getSunlightColor(); -    m_atmosphericsVars.ambient = psky->getAmbientColor();     -    m_atmosphericsVars.glow = psky->getGlow(); -    m_atmosphericsVars.cloud_shadow = psky->getCloudShadow(); -    m_atmosphericsVars.dome_radius = psky->getDomeRadius(); -    m_atmosphericsVars.dome_offset = psky->getDomeOffset(); -    m_atmosphericsVars.light_atten = psky->getLightAttenuation(m_atmosphericsVars.max_y); -    m_atmosphericsVars.light_transmittance = psky->getLightTransmittance(); -    m_atmosphericsVars.gamma = psky->getGamma(); +   	const F32 haze_int = color_intens(mHaze.calcSigSca(0)); +	mHazeConcentration = haze_int / +		(color_intens(LLHaze::calcAirSca(0)) + haze_int); + +	calcAtmospherics();  	// Initialize the cached normalized direction vectors  	for (S32 side = 0; side < 6; ++side) @@ -476,7 +422,7 @@ void LLVOSky::init()  		for (S32 tile = 0; tile < NUM_TILES; ++tile)  		{  			initSkyTextureDirs(side, tile); -			createSkyTexture(m_atmosphericsVars, side, tile, false); +			createSkyTexture(side, tile);  		}  	} @@ -487,107 +433,9 @@ void LLVOSky::init()  	}  	initCubeMap(); -  	mInitialized = true;  	mHeavenlyBodyUpdated = FALSE ; - -    mRainbowMap = LLViewerTextureManager::getFetchedTexture(psky->getRainbowTextureId(), FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); -    mHaloMap    = LLViewerTextureManager::getFetchedTexture(psky->getHaloTextureId(),  FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); -} - - -void LLVOSky::calc() -{ -    LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - -    // invariants across whole sky tex process... -    m_atmosphericsVars.blue_density = psky->getBlueDensity();     -    m_atmosphericsVars.blue_horizon = psky->getBlueHorizon(); -    m_atmosphericsVars.haze_density = psky->getHazeDensity(); -    m_atmosphericsVars.haze_horizon = psky->getHazeHorizon(); -    m_atmosphericsVars.density_multiplier = psky->getDensityMultiplier(); -    m_atmosphericsVars.max_y = psky->getMaxY(); -    m_atmosphericsVars.sun_norm = LLEnvironment::instance().getClampedSunNorm(); -    m_atmosphericsVars.sunlight = psky->getSunlightColor(); -    m_atmosphericsVars.ambient = psky->getAmbientColor();     -    m_atmosphericsVars.glow = psky->getGlow(); -    m_atmosphericsVars.cloud_shadow = psky->getCloudShadow(); -    m_atmosphericsVars.dome_radius = psky->getDomeRadius(); -    m_atmosphericsVars.dome_offset = psky->getDomeOffset(); -    m_atmosphericsVars.light_atten = psky->getLightAttenuation(m_atmosphericsVars.max_y); -    m_atmosphericsVars.light_transmittance = psky->getLightTransmittance(); -    m_atmosphericsVars.gamma = psky->getGamma(); - -	LLColor3 vary_HazeColor; -	LLColor3 vary_SunlightColor; -	LLColor3 vary_AmbientColor; -	{ -		// Initialize temp variables -		LLColor3 sunlight = m_atmosphericsVars.sunlight; - -		// Sunlight attenuation effect (hue and brightness) due to atmosphere -		// this is used later for sunlight modulation at various altitudes -		LLColor3 light_atten = -			(m_atmosphericsVars.blue_density * 1.0 + smear(m_atmosphericsVars.haze_density * 0.25f)) * (m_atmosphericsVars.density_multiplier * m_atmosphericsVars.max_y); - -		// Calculate relative weights -		LLColor3 temp2(0.f, 0.f, 0.f); -		LLColor3 temp1 = m_atmosphericsVars.blue_density + smear(m_atmosphericsVars.haze_density); -		LLColor3 blue_weight = componentDiv(m_atmosphericsVars.blue_density, temp1); -		LLColor3 haze_weight = componentDiv(smear(m_atmosphericsVars.haze_density), temp1); - -		// Compute sunlight from P & lightnorm (for long rays like sky) -		/// USE only lightnorm. -		// temp2[1] = llmax(0.f, llmax(0.f, Pn[1]) * 1.0f + lightnorm[1] ); -		F32 lighty = getSun().getDirection().mV[2]; -		temp2.mV[1] = llmax(0.f, lighty); -		if(temp2.mV[1] > 0.f) -		{ -			temp2.mV[1] = 1.f / temp2.mV[1]; -		} -		componentMultBy(sunlight, componentExp((light_atten * -1.f) * temp2.mV[1])); - -		// Distance -		temp2.mV[2] = m_atmosphericsVars.density_multiplier; - -		// Transparency (-> temp1) -		temp1 = componentExp((temp1 * -1.f) * temp2.mV[2]); - -		// vary_AtmosAttenuation = temp1;  - -		//increase ambient when there are more clouds -		LLColor3 tmpAmbient = m_atmosphericsVars.ambient + (smear(1.f) - m_atmosphericsVars.ambient) * m_atmosphericsVars.cloud_shadow * 0.5f; - -		//haze color -		vary_HazeColor = -			(m_atmosphericsVars.blue_horizon * blue_weight * (sunlight * (1.f - m_atmosphericsVars.cloud_shadow) + tmpAmbient)	 -			+ componentMult(m_atmosphericsVars.haze_horizon * haze_weight, sunlight * (1.f - m_atmosphericsVars.cloud_shadow) * temp2.mV[0] + tmpAmbient) -				 );	 - -		//brightness of surface both sunlight and ambient -		vary_SunlightColor = componentMult(sunlight, temp1) * 1.f; -		vary_SunlightColor.clamp(); -		vary_SunlightColor = smear(1.0f) - vary_SunlightColor; -		vary_SunlightColor = componentPow(vary_SunlightColor, m_atmosphericsVars.gamma); -		vary_SunlightColor = smear(1.0f) - vary_SunlightColor; -		vary_AmbientColor = componentMult(tmpAmbient, temp1) * 0.5; -		vary_AmbientColor.clamp(); -		vary_AmbientColor = smear(1.0f) - vary_AmbientColor; -		vary_AmbientColor = componentPow(vary_AmbientColor, m_atmosphericsVars.gamma); -		vary_AmbientColor = smear(1.0f) - vary_AmbientColor; - -		componentMultBy(vary_HazeColor, LLColor3(1.f, 1.f, 1.f) - temp1); - -	} - -	mSun.setColor(vary_SunlightColor); -	mMoon.setColor(LLColor3(1.0f, 1.0f, 1.0f)); - -	mSun.renewDirection(); -	mSun.renewColor(); -	mMoon.renewDirection(); -	mMoon.renewColor();  }  void LLVOSky::initCubeMap()  @@ -630,16 +478,15 @@ void LLVOSky::restoreGL()  	{  		mSkyTex[i].restoreGL();  	} +	mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); +	mSunTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); +	mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); +	mMoonTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); +	mBloomTexturep = LLViewerTextureManager::getFetchedTexture(IMG_BLOOM1); +	mBloomTexturep->setNoDelete() ; +	mBloomTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); -    LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - -    if (psky) -    { -        setSunTextures(psky->getSunTextureId(), psky->getNextSunTextureId()); -        setMoonTextures(psky->getMoonTextureId(), psky->getNextMoonTextureId()); -    } - -	updateDirections(); +	calcAtmospherics();	  	if (gSavedSettings.getBOOL("RenderWater") && gGLManager.mHasCubeMap  	    && LLCubeMap::sUseCubeMaps) @@ -655,11 +502,10 @@ void LLVOSky::restoreGL()  		if(cube_map)  		{  			cube_map->init(images); +			mForceUpdate = TRUE;  		}  	} -    mForceUpdate = TRUE; -  	if (mDrawable)  	{  		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); @@ -699,7 +545,7 @@ void LLVOSky::initSkyTextureDirs(const S32 side, const S32 tile)  	}  } -void LLVOSky::createSkyTexture(AtmosphericsVars& vars, const S32 side, const S32 tile, bool skip_sky_tex) +void LLVOSky::createSkyTexture(const S32 side, const S32 tile)  {  	S32 tile_x = tile % NUM_TILES_X;  	S32 tile_y = tile / NUM_TILES_X; @@ -708,55 +554,495 @@ void LLVOSky::createSkyTexture(AtmosphericsVars& vars, const S32 side, const S32  	S32 tile_y_pos = tile_y * sTileResY;  	S32 x, y; -    if (!skip_sky_tex) -    { -        for (y = tile_y_pos; y < (tile_y_pos + sTileResY); ++y) -	    { -		    for (x = tile_x_pos; x < (tile_x_pos + sTileResX); ++x) -		    { -                mSkyTex[side].setPixel(m_legacyAtmospherics.calcSkyColorInDir(vars, mSkyTex[side].getDir(x, y)), x, y); -		    } -	    } -    } -  	for (y = tile_y_pos; y < (tile_y_pos + sTileResY); ++y)  	{  		for (x = tile_x_pos; x < (tile_x_pos + sTileResX); ++x)  		{ -			mShinyTex[side].setPixel(m_legacyAtmospherics.calcSkyColorInDir(vars, mSkyTex[side].getDir(x, y), true), x, y); +			mSkyTex[side].setPixel(calcSkyColorInDir(mSkyTex[side].getDir(x, y)), x, y); +			mShinyTex[side].setPixel(calcSkyColorInDir(mSkyTex[side].getDir(x, y), true), x, y);  		}  	}  } -void LLVOSky::updateDirections(void) +static inline LLColor3 componentDiv(LLColor3 const &left, LLColor3 const & right) +{ +	return LLColor3(left.mV[0]/right.mV[0], +					 left.mV[1]/right.mV[1], +					 left.mV[2]/right.mV[2]); +} + + +static inline LLColor3 componentMult(LLColor3 const &left, LLColor3 const & right) +{ +	return LLColor3(left.mV[0]*right.mV[0], +					 left.mV[1]*right.mV[1], +					 left.mV[2]*right.mV[2]); +} + + +static inline LLColor3 componentExp(LLColor3 const &v) +{ +	return LLColor3(exp(v.mV[0]), +					 exp(v.mV[1]), +					 exp(v.mV[2])); +} + +static inline LLColor3 componentPow(LLColor3 const &v, F32 exponent) +{ +	return LLColor3(pow(v.mV[0], exponent), +					pow(v.mV[1], exponent), +					pow(v.mV[2], exponent)); +} + +static inline LLColor3 componentSaturate(LLColor3 const &v) +{ +	return LLColor3(std::max(std::min(v.mV[0], 1.f), 0.f), +					 std::max(std::min(v.mV[1], 1.f), 0.f), +					 std::max(std::min(v.mV[2], 1.f), 0.f)); +} + + +static inline LLColor3 componentSqrt(LLColor3 const &v) +{ +	return LLColor3(sqrt(v.mV[0]), +					 sqrt(v.mV[1]), +					 sqrt(v.mV[2])); +} + +static inline void componentMultBy(LLColor3 & left, LLColor3 const & right)  { -    LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); +	left.mV[0] *= right.mV[0]; +	left.mV[1] *= right.mV[1]; +	left.mV[2] *= right.mV[2]; +} -    mLastSunLightingDirection  = mSun.getDirection(); -    mLastMoonLightingDirection = mMoon.getDirection(); +static inline LLColor3 colorMix(LLColor3 const & left, LLColor3 const & right, F32 amount) +{ +	return (left + ((right - left) * amount)); +} -    mSun.setDirection(psky->getSunDirection()); -	mMoon.setDirection(psky->getMoonDirection()); +static inline LLColor3 smear(F32 val) +{ +	return LLColor3(val, val, val); +} -    mSun.setColor(psky->getSunlightColor()); -	mMoon.setColor(psky->getMoonDiffuse()); +void LLVOSky::initAtmospherics(void) +{	 +	bool error; +	 +	// uniform parameters for convenience +	dome_radius = LLWLParamManager::getInstance()->getDomeRadius(); +	dome_offset_ratio = LLWLParamManager::getInstance()->getDomeOffset(); +	sunlight_color = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("sunlight_color", error)); +	ambient = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("ambient", error)); +	//lightnorm = LLWLParamManager::getInstance()->mCurParams.getVector("lightnorm", error); +	gamma = LLWLParamManager::getInstance()->mCurParams.getFloat("gamma", error); +	blue_density = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("blue_density", error)); +	blue_horizon = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("blue_horizon", error)); +	haze_density = LLWLParamManager::getInstance()->mCurParams.getFloat("haze_density", error); +	haze_horizon = LLWLParamManager::getInstance()->mCurParams.getFloat("haze_horizon", error); +	density_multiplier = LLWLParamManager::getInstance()->mCurParams.getFloat("density_multiplier", error); +	max_y = LLWLParamManager::getInstance()->mCurParams.getFloat("max_y", error); +	glow = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("glow", error)); +	cloud_shadow = LLWLParamManager::getInstance()->mCurParams.getFloat("cloud_shadow", error); +	cloud_color = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("cloud_color", error)); +	cloud_scale = LLWLParamManager::getInstance()->mCurParams.getFloat("cloud_scale", error); +	cloud_pos_density1 = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("cloud_pos_density1", error)); +	cloud_pos_density2 = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("cloud_pos_density2", error)); + +	// light norm is different.  We need the sun's direction, not the light direction +	// which could be from the moon.  And we need to clamp it +	// just like for the gpu +	LLVector3 sunDir = gSky.getSunDirection(); + +	// CFR_TO_OGL +	lightnorm = LLVector4(sunDir.mV[1], sunDir.mV[2], sunDir.mV[0], 0); +	unclamped_lightnorm = lightnorm; +	if(lightnorm.mV[1] < -0.1f) +	{ +		lightnorm.mV[1] = -0.1f; +	} +	 +} + +LLColor4 LLVOSky::calcSkyColorInDir(const LLVector3 &dir, bool isShiny) +{ +	F32 saturation = 0.3f; +	if (dir.mV[VZ] < -0.02f) +	{ +		LLColor4 col = LLColor4(llmax(mFogColor[0],0.2f), llmax(mFogColor[1],0.2f), llmax(mFogColor[2],0.22f),0.f); +		if (isShiny) +		{ +			LLColor3 desat_fog = LLColor3(mFogColor); +			F32 brightness = desat_fog.brightness(); +			// So that shiny somewhat shows up at night. +			if (brightness < 0.15f) +			{ +				brightness = 0.15f; +				desat_fog = smear(0.15f); +			} +			LLColor3 greyscale = smear(brightness); +			desat_fog = desat_fog * saturation + greyscale * (1.0f - saturation); +			if (!gPipeline.canUseWindLightShaders()) +			{ +				col = LLColor4(desat_fog, 0.f); +			} +			else  +			{ +				col = LLColor4(desat_fog * 0.5f, 0.f); +			} +		} +		float x = 1.0f-fabsf(-0.1f-dir.mV[VZ]); +		x *= x; +		col.mV[0] *= x*x; +		col.mV[1] *= powf(x, 2.5f); +		col.mV[2] *= x*x*x; +		return col; +	} + +	// undo OGL_TO_CFR_ROTATION and negate vertical direction. +	LLVector3 Pn = LLVector3(-dir[1] , -dir[2], -dir[0]); + +	LLColor3 vary_HazeColor(0,0,0); +	LLColor3 vary_CloudColorSun(0,0,0); +	LLColor3 vary_CloudColorAmbient(0,0,0); +	F32 vary_CloudDensity(0); +	LLVector2 vary_HorizontalProjection[2]; +	vary_HorizontalProjection[0] = LLVector2(0,0); +	vary_HorizontalProjection[1] = LLVector2(0,0); + +	calcSkyColorWLVert(Pn, vary_HazeColor, vary_CloudColorSun, vary_CloudColorAmbient, +						vary_CloudDensity, vary_HorizontalProjection); +	 +	LLColor3 sky_color =  calcSkyColorWLFrag(Pn, vary_HazeColor, vary_CloudColorSun, vary_CloudColorAmbient,  +								vary_CloudDensity, vary_HorizontalProjection); +	if (isShiny) +	{ +		F32 brightness = sky_color.brightness(); +		LLColor3 greyscale = smear(brightness); +		sky_color = sky_color * saturation + greyscale * (1.0f - saturation); +		sky_color *= (0.5f + 0.5f * brightness); +	} +	return LLColor4(sky_color, 0.0f); +} + +// turn on floating point precision +// in vs2003 for this function.  Otherwise +// sky is aliased looking 7:10 - 8:50 +#if LL_MSVC && __MSVC_VER__ < 8 +#pragma optimize("p", on) +#endif + +void LLVOSky::calcSkyColorWLVert(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLColor3 & vary_CloudColorSun,  +							LLColor3 & vary_CloudColorAmbient, F32 & vary_CloudDensity,  +							LLVector2 vary_HorizontalProjection[2]) +{ +	// project the direction ray onto the sky dome. +	F32 phi = acos(Pn[1]); +	F32 sinA = sin(F_PI - phi); +	if (fabsf(sinA) < 0.01f) +	{ //avoid division by zero +		sinA = 0.01f; +	} + +	F32 Plen = dome_radius * sin(F_PI + phi + asin(dome_offset_ratio * sinA)) / sinA; + +	Pn *= Plen; + +	vary_HorizontalProjection[0] = LLVector2(Pn[0], Pn[2]); +	vary_HorizontalProjection[0] /= - 2.f * Plen; + +	// Set altitude +	if (Pn[1] > 0.f) +	{ +		Pn *= (max_y / Pn[1]); +	} +	else +	{ +		Pn *= (-32000.f / Pn[1]); +	} + +	Plen = Pn.length(); +	Pn /= Plen; + +	// Initialize temp variables +	LLColor3 sunlight = sunlight_color; + +	// Sunlight attenuation effect (hue and brightness) due to atmosphere +	// this is used later for sunlight modulation at various altitudes +	LLColor3 light_atten = +		(blue_density * 1.0 + smear(haze_density * 0.25f)) * (density_multiplier * max_y); + +	// Calculate relative weights +	LLColor3 temp2(0.f, 0.f, 0.f); +	LLColor3 temp1 = blue_density + smear(haze_density); +	LLColor3 blue_weight = componentDiv(blue_density, temp1); +	LLColor3 haze_weight = componentDiv(smear(haze_density), temp1); + +	// Compute sunlight from P & lightnorm (for long rays like sky) +	temp2.mV[1] = llmax(F_APPROXIMATELY_ZERO, llmax(0.f, Pn[1]) * 1.0f + lightnorm[1] ); + +	temp2.mV[1] = 1.f / temp2.mV[1]; +	componentMultBy(sunlight, componentExp((light_atten * -1.f) * temp2.mV[1])); + +	// Distance +	temp2.mV[2] = Plen * density_multiplier; + +	// Transparency (-> temp1) +	temp1 = componentExp((temp1 * -1.f) * temp2.mV[2]); + + +	// Compute haze glow +	temp2.mV[0] = Pn * LLVector3(lightnorm); + +	temp2.mV[0] = 1.f - temp2.mV[0]; +		// temp2.x is 0 at the sun and increases away from sun +	temp2.mV[0] = llmax(temp2.mV[0], .001f);	 +		// Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) +	temp2.mV[0] *= glow.mV[0]; +		// Higher glow.x gives dimmer glow (because next step is 1 / "angle") +	temp2.mV[0] = pow(temp2.mV[0], glow.mV[2]); +		// glow.z should be negative, so we're doing a sort of (1 / "angle") function + +	// Add "minimum anti-solar illumination" +	temp2.mV[0] += .25f; + + +	// Haze color above cloud +	vary_HazeColor = (blue_horizon * blue_weight * (sunlight + ambient) +				+ componentMult(haze_horizon * haze_weight, sunlight * temp2.mV[0] + ambient) +			 );	 + +	// Increase ambient when there are more clouds +	LLColor3 tmpAmbient = ambient + (LLColor3::white - ambient) * cloud_shadow * 0.5f; + +	// Dim sunlight by cloud shadow percentage +	sunlight *= (1.f - cloud_shadow); + +	// Haze color below cloud +	LLColor3 additiveColorBelowCloud = (blue_horizon * blue_weight * (sunlight + tmpAmbient) +				+ componentMult(haze_horizon * haze_weight, sunlight * temp2.mV[0] + tmpAmbient) +			 );	 + +	// Final atmosphere additive +	componentMultBy(vary_HazeColor, LLColor3::white - temp1); + +	sunlight = sunlight_color; +	temp2.mV[1] = llmax(0.f, lightnorm[1] * 2.f); +	temp2.mV[1] = 1.f / temp2.mV[1]; +	componentMultBy(sunlight, componentExp((light_atten * -1.f) * temp2.mV[1])); + +	// Attenuate cloud color by atmosphere +	temp1 = componentSqrt(temp1);	//less atmos opacity (more transparency) below clouds + +	// At horizon, blend high altitude sky color towards the darker color below the clouds +	vary_HazeColor += +		componentMult(additiveColorBelowCloud - vary_HazeColor, LLColor3::white - componentSqrt(temp1)); +		 +	if (Pn[1] < 0.f) +	{ +		// Eric's original:  +		// LLColor3 dark_brown(0.143f, 0.129f, 0.114f); +		LLColor3 dark_brown(0.082f, 0.076f, 0.066f); +		LLColor3 brown(0.430f, 0.386f, 0.322f); +		LLColor3 sky_lighting = sunlight + ambient; +		F32 haze_brightness = vary_HazeColor.brightness(); + +		if (Pn[1] < -0.05f) +		{ +			vary_HazeColor = colorMix(dark_brown, brown, -Pn[1] * 0.9f) * sky_lighting * haze_brightness; +		} +		 +		if (Pn[1] > -0.1f) +		{ +			vary_HazeColor = colorMix(LLColor3::white * haze_brightness, vary_HazeColor, fabs((Pn[1] + 0.05f) * -20.f)); +		} +	} +} + +#if LL_MSVC && __MSVC_VER__ < 8 +#pragma optimize("p", off) +#endif + +LLColor3 LLVOSky::calcSkyColorWLFrag(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLColor3 & vary_CloudColorSun,  +							LLColor3 & vary_CloudColorAmbient, F32 & vary_CloudDensity,  +							LLVector2 vary_HorizontalProjection[2]) +{ +	LLColor3 res; + +	LLColor3 color0 = vary_HazeColor; +	 +	if (!gPipeline.canUseWindLightShaders()) +	{ +		LLColor3 color1 = color0 * 2.0f; +		color1 = smear(1.f) - componentSaturate(color1); +		componentPow(color1, gamma); +		res = smear(1.f) - color1; +	}  +	else  +	{ +		res = color0; +	} + +#	ifndef LL_RELEASE_FOR_DOWNLOAD + +	LLColor3 color2 = 2.f * color0; + +	LLColor3 color3 = LLColor3(1.f, 1.f, 1.f) - componentSaturate(color2); +	componentPow(color3, gamma); +	color3 = LLColor3(1.f, 1.f, 1.f) - color3; + +	static enum { +		OUT_DEFAULT		= 0, +		OUT_SKY_BLUE	= 1, +		OUT_RED			= 2, +		OUT_PN			= 3, +		OUT_HAZE		= 4, +	} debugOut = OUT_DEFAULT; + +	switch(debugOut)  +	{ +		case OUT_DEFAULT: +			break; +		case OUT_SKY_BLUE: +			res = LLColor3(0.4f, 0.4f, 0.9f); +			break; +		case OUT_RED: +			res = LLColor3(1.f, 0.f, 0.f); +			break; +		case OUT_PN: +			res = LLColor3(Pn[0], Pn[1], Pn[2]); +			break; +		case OUT_HAZE: +			res = vary_HazeColor; +			break; +	} +#	endif // LL_RELEASE_FOR_DOWNLOAD +	return res; +} + +LLColor3 LLVOSky::createDiffuseFromWL(LLColor3 diffuse, LLColor3 ambient, LLColor3 sundiffuse, LLColor3 sunambient) +{ +	return componentMult(diffuse, sundiffuse) * 4.0f + +			componentMult(ambient, sundiffuse) * 2.0f + sunambient; +} + +LLColor3 LLVOSky::createAmbientFromWL(LLColor3 ambient, LLColor3 sundiffuse, LLColor3 sunambient) +{ +	return (componentMult(ambient, sundiffuse) + sunambient) * 0.8f; +} + + +void LLVOSky::calcAtmospherics(void) +{ +	initAtmospherics(); + +	LLColor3 vary_HazeColor; +	LLColor3 vary_SunlightColor; +	LLColor3 vary_AmbientColor; +	{ +		// Initialize temp variables +		LLColor3 sunlight = sunlight_color; + +		// Sunlight attenuation effect (hue and brightness) due to atmosphere +		// this is used later for sunlight modulation at various altitudes +		LLColor3 light_atten = +			(blue_density * 1.0 + smear(haze_density * 0.25f)) * (density_multiplier * max_y); + +		// Calculate relative weights +		LLColor3 temp2(0.f, 0.f, 0.f); +		LLColor3 temp1 = blue_density + smear(haze_density); +		LLColor3 blue_weight = componentDiv(blue_density, temp1); +		LLColor3 haze_weight = componentDiv(smear(haze_density), temp1); + +		// Compute sunlight from P & lightnorm (for long rays like sky) +		/// USE only lightnorm. +		// temp2[1] = llmax(0.f, llmax(0.f, Pn[1]) * 1.0f + lightnorm[1] ); +		 +		// and vary_sunlight will work properly with moon light +		F32 lighty = unclamped_lightnorm[1]; +		if(lighty < LLSky::NIGHTTIME_ELEVATION_COS) +		{ +			lighty = -lighty; +		} + +		temp2.mV[1] = llmax(0.f, lighty); +		if(temp2.mV[1] > 0.f) +		{ +			temp2.mV[1] = 1.f / temp2.mV[1]; +		} +		componentMultBy(sunlight, componentExp((light_atten * -1.f) * temp2.mV[1])); + +		// Distance +		temp2.mV[2] = density_multiplier; + +		// Transparency (-> temp1) +		temp1 = componentExp((temp1 * -1.f) * temp2.mV[2]); + +		// vary_AtmosAttenuation = temp1;  + +		//increase ambient when there are more clouds +		LLColor3 tmpAmbient = ambient + (smear(1.f) - ambient) * cloud_shadow * 0.5f; + +		//haze color +		vary_HazeColor = +			(blue_horizon * blue_weight * (sunlight*(1.f - cloud_shadow) + tmpAmbient)	 +			+ componentMult(haze_horizon * haze_weight, sunlight*(1.f - cloud_shadow) * temp2.mV[0] + tmpAmbient) +				 );	 + +		//brightness of surface both sunlight and ambient +		vary_SunlightColor = componentMult(sunlight, temp1) * 1.f; +		vary_SunlightColor.clamp(); +		vary_SunlightColor = smear(1.0f) - vary_SunlightColor; +		vary_SunlightColor = componentPow(vary_SunlightColor, gamma); +		vary_SunlightColor = smear(1.0f) - vary_SunlightColor; +		vary_AmbientColor = componentMult(tmpAmbient, temp1) * 0.5; +		vary_AmbientColor.clamp(); +		vary_AmbientColor = smear(1.0f) - vary_AmbientColor; +		vary_AmbientColor = componentPow(vary_AmbientColor, gamma); +		vary_AmbientColor = smear(1.0f) - vary_AmbientColor; + +		componentMultBy(vary_HazeColor, LLColor3(1.f, 1.f, 1.f) - temp1); + +	} + +	mSun.setColor(vary_SunlightColor); +	mMoon.setColor(LLColor3(1.0f, 1.0f, 1.0f));  	mSun.renewDirection();  	mSun.renewColor();  	mMoon.renewDirection();  	mMoon.renewColor(); + +	float dp = getToSunLast() * LLVector3(0,0,1.f); +	if (dp < 0) +	{ +		dp = 0; +	} + +	// Since WL scales everything by 2, there should always be at least a 2:1 brightness ratio +	// between sunlight and point lights in windlight to normalize point lights. +	F32 sun_dynamic_range = llmax(gSavedSettings.getF32("RenderSunDynamicRange"), 0.0001f); +	LLWLParamManager::getInstance()->mSceneLightStrength = 2.0f * (1.0f + sun_dynamic_range * dp); + +	mSunDiffuse = vary_SunlightColor; +	mSunAmbient = vary_AmbientColor; +	mMoonDiffuse = vary_SunlightColor; +	mMoonAmbient = vary_AmbientColor; + +	mTotalAmbient = vary_AmbientColor; +	mTotalAmbient.setAlpha(1); +	 +	mFadeColor = mTotalAmbient + (mSunDiffuse + mMoonDiffuse) * 0.5f; +	mFadeColor.setAlpha(0);  }  void LLVOSky::idleUpdate(LLAgent &agent, const F64 &time)  {  } -bool LLVOSky::updateSky() -{     -    LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - -    LLColor4 total_ambient = psky->getTotalAmbient(); - +BOOL LLVOSky::updateSky() +{  	if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY)))  	{  		return TRUE; @@ -776,13 +1062,11 @@ bool LLVOSky::updateSky()  	const S32 total_no_tiles = 6 * NUM_TILES;  	const S32 cycle_frame_no = total_no_tiles + 1; -	if (mUpdateTimer.getElapsedTimeF32() > 0.025f) +	if (mUpdateTimer.getElapsedTimeF32() > 0.001f)  	{ -        mUpdateTimer.reset(); +		mUpdateTimer.reset();  		const S32 frame = next_frame; -        mForceUpdate = mForceUpdate || (total_no_tiles == frame); -  		++next_frame;  		next_frame = next_frame % cycle_frame_no; @@ -790,150 +1074,117 @@ bool LLVOSky::updateSky()  		// sInterpVal = (F32)next_frame / cycle_frame_no;  		LLSkyTex::setInterpVal( mInterpVal );  		LLHeavenBody::setInterpVal( mInterpVal ); -		updateDirections(); - -        LLVector3 direction = mSun.getDirection(); -		direction.normalize(); -		const F32 dot_sun  = direction * mLastSunLightingDirection; -        const F32 dot_moon = direction * mLastMoonLightingDirection; +		calcAtmospherics(); -		LLColor3 delta_color; -		delta_color.setVec(mLastTotalAmbient.mV[0] - total_ambient.mV[0], -							mLastTotalAmbient.mV[1] - total_ambient.mV[1], -                            mLastTotalAmbient.mV[2] - total_ambient.mV[2]); - -        bool sun_direction_changed  = (dot_sun < LIGHT_DIRECTION_THRESHOLD); -        bool moon_direction_changed = (dot_moon < LIGHT_DIRECTION_THRESHOLD); -        bool color_changed          = (delta_color.length() >= COLOR_CHANGE_THRESHOLD); - -        mForceUpdate = mForceUpdate || sun_direction_changed; -        mForceUpdate = mForceUpdate || moon_direction_changed; -        mForceUpdate = mForceUpdate || color_changed; -        mForceUpdate = mForceUpdate || !mInitialized; - -        bool is_alm_wl_sky = gPipeline.canUseWindLightShaders(); - -        calc(); - -        if (mForceUpdate && mForceUpdateThrottle.hasExpired()) +		if (mForceUpdate || total_no_tiles == frame)  		{ -            LL_RECORD_BLOCK_TIME(FTM_VOSKY_UPDATEFORCED); - -            mForceUpdateThrottle.setTimerExpirySec(UPDATE_EXPRY); -  			LLSkyTex::stepCurrent(); -		 -			if (!direction.isExactlyZero()) +			 +			const static F32 LIGHT_DIRECTION_THRESHOLD = (F32) cos(DEG_TO_RAD * 1.f); +			const static F32 COLOR_CHANGE_THRESHOLD = 0.01f; + +			LLVector3 direction = mSun.getDirection(); +			direction.normalize(); +			const F32 dot_lighting = direction * mLastLightingDirection; + +			LLColor3 delta_color; +			delta_color.setVec(mLastTotalAmbient.mV[0] - mTotalAmbient.mV[0], +							   mLastTotalAmbient.mV[1] - mTotalAmbient.mV[1], +							   mLastTotalAmbient.mV[2] - mTotalAmbient.mV[2]); + +			if ( mForceUpdate  +				 || (((dot_lighting < LIGHT_DIRECTION_THRESHOLD) +				 || (delta_color.length() > COLOR_CHANGE_THRESHOLD) +				 || !mInitialized) +				&& !direction.isExactlyZero()))  			{ -                mLastTotalAmbient = total_ambient; +				mLastLightingDirection = direction; +				mLastTotalAmbient = mTotalAmbient;  				mInitialized = TRUE;  				if (mCubeMap)  				{ -					updateFog(LLViewerCamera::getInstance()->getFar()); - -					for (int side = 0; side < 6; side++)  +                    if (mForceUpdate)  					{ -						for (int tile = 0; tile < NUM_TILES; tile++)  +						updateFog(LLViewerCamera::getInstance()->getFar()); +						for (int side = 0; side < 6; side++)   						{ -							createSkyTexture(m_atmosphericsVars, side, tile, is_alm_wl_sky); +							for (int tile = 0; tile < NUM_TILES; tile++)  +							{ +								createSkyTexture(side, tile); +							}  						} -					} -                    int tex = mSkyTex[0].getWhich(TRUE); +						calcAtmospherics(); -					for (int side = 0; side < 6; side++)  -					{ -                        LLImageRaw* raw1 = nullptr; -                        LLImageRaw* raw2 = nullptr; - -                        if (!is_alm_wl_sky) -                        { -						    raw1 = mSkyTex[side].getImageRaw(TRUE); -						    raw2 = mSkyTex[side].getImageRaw(FALSE); -						    raw2->copy(raw1); -						    mSkyTex[side].createGLImage(tex); -                        } - -						raw1 = mShinyTex[side].getImageRaw(TRUE); -						raw2 = mShinyTex[side].getImageRaw(FALSE); -						raw2->copy(raw1); -						mShinyTex[side].createGLImage(tex); +						for (int side = 0; side < 6; side++)  +						{ +							LLImageRaw* raw1 = mSkyTex[side].getImageRaw(TRUE); +							LLImageRaw* raw2 = mSkyTex[side].getImageRaw(FALSE); +							raw2->copy(raw1); +							mSkyTex[side].createGLImage(mSkyTex[side].getWhich(FALSE)); + +							raw1 = mShinyTex[side].getImageRaw(TRUE); +							raw2 = mShinyTex[side].getImageRaw(FALSE); +							raw2->copy(raw1); +							mShinyTex[side].createGLImage(mShinyTex[side].getWhich(FALSE)); +						} +						next_frame = 0;	  					} -					next_frame = 0;	 - -			        // update the sky texture -                    if (!is_alm_wl_sky) -                    { -			            for (S32 i = 0; i < 6; ++i) -			            { -                            mSkyTex[i].create(1.0f); -			            } -                    } - -                    for (S32 i = 0; i < 6; ++i) -			        { -				        mShinyTex[i].create(1.0f); -			        } - -			        // update the environment map -			        if (mCubeMap) -			        { -				        std::vector<LLPointer<LLImageRaw> > images; -				        images.reserve(6); -				        for (S32 side = 0; side < 6; side++) -				        { -					        images.push_back(mShinyTex[side].getImageRaw(TRUE)); -				        } -				        mCubeMap->init(images); -				        gGL.getTexUnit(0)->disable(); -			        }                      				} -            } +			} + +			/// *TODO really, sky texture and env map should be shared on a single texture +			/// I'll let Brad take this at some point + +			// update the sky texture +			for (S32 i = 0; i < 6; ++i) +			{ +				mSkyTex[i].create(1.0f); +				mShinyTex[i].create(1.0f); +			} +			 +			// update the environment map +			if (mCubeMap) +			{ +				std::vector<LLPointer<LLImageRaw> > images; +				images.reserve(6); +				for (S32 side = 0; side < 6; side++) +				{ +					images.push_back(mShinyTex[side].getImageRaw(TRUE)); +				} +				mCubeMap->init(images); +				gGL.getTexUnit(0)->disable(); +			}  			gPipeline.markRebuild(gSky.mVOGroundp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); +			// *TODO: decide whether we need to update the stars vertex buffer in LLVOWLSky -Brad. +			//gPipeline.markRebuild(gSky.mVOWLSkyp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); +  			mForceUpdate = FALSE;  		} +		else +		{ +			const S32 side = frame / NUM_TILES; +			const S32 tile = frame % NUM_TILES; +			createSkyTexture(side, tile); +		}  	}  	if (mDrawable.notNull() && mDrawable->getFace(0) && !mDrawable->getFace(0)->getVertexBuffer())  	{  		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);  	} -  	return TRUE;  }  void LLVOSky::updateTextures()  { -	if (mSunTexturep[0]) +	if (mSunTexturep)  	{ -		mSunTexturep[0]->addTextureStats( (F32)MAX_IMAGE_AREA ); -    } - -    if (mSunTexturep[1]) -	{ -		mSunTexturep[1]->addTextureStats( (F32)MAX_IMAGE_AREA ); -    } - -    if (mMoonTexturep[0]) -	{ -		mMoonTexturep[0]->addTextureStats( (F32)MAX_IMAGE_AREA ); -    } - -    if (mMoonTexturep[1]) -	{ -		mMoonTexturep[1]->addTextureStats( (F32)MAX_IMAGE_AREA ); -    }    - -    if (mBloomTexturep[0]) -    { -		mBloomTexturep[0]->addTextureStats( (F32)MAX_IMAGE_AREA ); -	} - -    if (mBloomTexturep[1]) -    { -		mBloomTexturep[1]->addTextureStats( (F32)MAX_IMAGE_AREA ); +		mSunTexturep->addTextureStats( (F32)MAX_IMAGE_AREA ); +		mMoonTexturep->addTextureStats( (F32)MAX_IMAGE_AREA ); +		mBloomTexturep->addTextureStats( (F32)MAX_IMAGE_AREA );  	}  } @@ -951,121 +1202,60 @@ LLDrawable *LLVOSky::createDrawable(LLPipeline *pipeline)  		mFace[FACE_SIDE0 + i] = mDrawable->addFace(poolp, NULL);  	} -	mFace[FACE_SUN]   = mDrawable->addFace(poolp, nullptr); -	mFace[FACE_MOON]  = mDrawable->addFace(poolp, nullptr); -	mFace[FACE_BLOOM] = mDrawable->addFace(poolp, nullptr); +	mFace[FACE_SUN] = mDrawable->addFace(poolp, mSunTexturep); +	mFace[FACE_MOON] = mDrawable->addFace(poolp, mMoonTexturep); +	mFace[FACE_BLOOM] = mDrawable->addFace(poolp, mBloomTexturep);  	return mDrawable;  } -void LLVOSky::setSunScale(F32 sun_scale) -{ -    mSunScale  = sun_scale; -} - -void LLVOSky::setMoonScale(F32 moon_scale) +//by bao +//fake vertex buffer updating +//to guarantee at least updating one VBO buffer every frame +//to walk around the bug caused by ATI card --> DEV-3855 +// +void LLVOSky::createDummyVertexBuffer()  { -    mMoonScale = moon_scale; -} - -void LLVOSky::setSunTextures(const LLUUID& sun_texture, const LLUUID& sun_texture_next) -{ -    // We test the UUIDs here because we explicitly do not want the default image returned by getFetchedTexture in that case... -    mSunTexturep[0] = sun_texture.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(sun_texture, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); -    mSunTexturep[1] = sun_texture_next.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(sun_texture_next, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); - -    if (mFace[FACE_SUN]) -    { -        if (mSunTexturep[0]) -        { -	        mSunTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP); -        } - -        LLViewerTexture* current_tex0 = mFace[FACE_SUN]->getTexture(LLRender::DIFFUSE_MAP); -        LLViewerTexture* current_tex1 = mFace[FACE_SUN]->getTexture(LLRender::ALTERNATE_DIFFUSE_MAP); - -        if (current_tex0 && (mSunTexturep[0] != current_tex0) && current_tex0->isViewerMediaTexture()) -        { -            static_cast<LLViewerMediaTexture*>(current_tex0)->removeMediaFromFace(mFace[FACE_SUN]); -        } - -        if (current_tex1 && (mSunTexturep[1] != current_tex1) && current_tex1->isViewerMediaTexture()) -        { -            static_cast<LLViewerMediaTexture*>(current_tex1)->removeMediaFromFace(mFace[FACE_SUN]); -        } - -        mFace[FACE_SUN]->setTexture(LLRender::DIFFUSE_MAP, mSunTexturep[0]); - -        if (mSunTexturep[1]) -        { -	        mSunTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP);             -        } -        mFace[FACE_SUN]->setTexture(LLRender::ALTERNATE_DIFFUSE_MAP, mSunTexturep[1]); -    } -} +	if(!mFace[FACE_DUMMY]) +	{ +		LLDrawPoolSky *poolp = (LLDrawPoolSky*) gPipeline.getPool(LLDrawPool::POOL_SKY); +		mFace[FACE_DUMMY] = mDrawable->addFace(poolp, NULL); +	} -void LLVOSky::setMoonTextures(const LLUUID& moon_texture, const LLUUID& moon_texture_next) -{ -    LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - -    mMoonTexturep[0] = moon_texture.isNull()      ? nullptr : LLViewerTextureManager::getFetchedTexture(moon_texture, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); -    mMoonTexturep[1] = moon_texture_next.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(moon_texture_next, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); - -    if (mFace[FACE_MOON]) -    { -        if (mMoonTexturep[0]) -        { -	        mMoonTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP); -        } -        mFace[FACE_MOON]->setTexture(LLRender::DIFFUSE_MAP, mMoonTexturep[0]); -     -        if (mMoonTexturep[1]) -        { -	        mMoonTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP); -            mFace[FACE_MOON]->setTexture(LLRender::ALTERNATE_DIFFUSE_MAP, mMoonTexturep[1]); -        } -    } +	if(!mFace[FACE_DUMMY]->getVertexBuffer()) +	{ +		LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB); +		buff->allocateBuffer(1, 1, TRUE); +		mFace[FACE_DUMMY]->setVertexBuffer(buff); +	}  } -void LLVOSky::setCloudNoiseTextures(const LLUUID& cloud_noise_texture, const LLUUID& cloud_noise_texture_next) -{ -    LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - -    mCloudNoiseTexturep[0] = cloud_noise_texture.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(cloud_noise_texture, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); -    mCloudNoiseTexturep[1] = cloud_noise_texture_next.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(cloud_noise_texture_next, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); - -    if (mCloudNoiseTexturep[0]) -    { -	    mCloudNoiseTexturep[0]->setAddressMode(LLTexUnit::TAM_WRAP); -    } +static LLTrace::BlockTimerStatHandle FTM_RENDER_FAKE_VBO_UPDATE("Fake VBO Update"); -    if (mCloudNoiseTexturep[1]) -    { -	    mCloudNoiseTexturep[1]->setAddressMode(LLTexUnit::TAM_WRAP); -    } -} - -void LLVOSky::setBloomTextures(const LLUUID& bloom_texture, const LLUUID& bloom_texture_next) -{ -    LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); +void LLVOSky::updateDummyVertexBuffer() +{	 +	if(!LLVertexBuffer::sEnableVBOs) +		return ; -    LLUUID bloom_tex = bloom_texture.isNull() ? psky->GetDefaultBloomTextureId() : bloom_texture; -    LLUUID bloom_tex_next = bloom_texture_next.isNull() ? (bloom_texture.isNull() ? psky->GetDefaultBloomTextureId() : bloom_texture) : bloom_texture_next; +	if(mHeavenlyBodyUpdated) +	{ +		mHeavenlyBodyUpdated = FALSE ; +		return ; +	} -    mBloomTexturep[0] = bloom_tex.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(bloom_tex, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); -    mBloomTexturep[1] = bloom_tex_next.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(bloom_tex_next, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); +	LL_RECORD_BLOCK_TIME(FTM_RENDER_FAKE_VBO_UPDATE) ; -    if (mBloomTexturep[0]) -    { -	    mBloomTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP); -    } +	if(!mFace[FACE_DUMMY] || !mFace[FACE_DUMMY]->getVertexBuffer()) +		createDummyVertexBuffer() ; -    if (mBloomTexturep[1]) -    { -	    mBloomTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP); -    } +	LLStrider<LLVector3> vertices ; +	mFace[FACE_DUMMY]->getVertexBuffer()->getVertexStrider(vertices,  0); +	*vertices = mCameraPosAgent ; +	mFace[FACE_DUMMY]->getVertexBuffer()->flush();  } - +//---------------------------------- +//end of fake vertex buffer updating +//----------------------------------  static LLTrace::BlockTimerStatHandle FTM_GEO_SKY("Sky Geometry");  BOOL LLVOSky::updateGeometry(LLDrawable *drawable) @@ -1081,7 +1271,6 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable)  	}  	mCameraPosAgent = drawable->getPositionAgent(); -  	mEarthCenter.mV[0] = mCameraPosAgent.mV[0];  	mEarthCenter.mV[1] = mCameraPosAgent.mV[1]; @@ -1155,40 +1344,64 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable)  	LLVector3 up = right % look_at;  	right.normalize();  	up.normalize(); -     -    bool draw_sun  = updateHeavenlyBodyGeometry(drawable, mSunScale, FACE_SUN, mSun, up, right); -    bool draw_moon = updateHeavenlyBodyGeometry(drawable, mMoonScale, FACE_MOON, mMoon, up, right); - -    draw_sun  &= LLEnvironment::getInstance()->getIsSunUp(); -    draw_moon &= LLEnvironment::getInstance()->getIsMoonUp(); -	mSun.setDraw(draw_sun); -	mMoon.setDraw(draw_moon); +	const static F32 elevation_factor = 0.0f/sResolution; +	const F32 cos_max_angle = cosHorizon(elevation_factor); +	mSun.setDraw(updateHeavenlyBodyGeometry(drawable, FACE_SUN, TRUE, mSun, cos_max_angle, up, right)); +	mMoon.setDraw(updateHeavenlyBodyGeometry(drawable, FACE_MOON, FALSE, mMoon, cos_max_angle, up, right));  	const F32 water_height = gAgent.getRegion()->getWaterHeight() + 0.01f;  		// LLWorld::getInstance()->getWaterHeight() + 0.01f;  	const F32 camera_height = mCameraPosAgent.mV[2];  	const F32 height_above_water = camera_height - water_height; -	bool sun_flag = FALSE; +	BOOL sun_flag = FALSE; +  	if (mSun.isVisible()) -	{         -        sun_flag = !mMoon.isVisible() || ((look_at * mSun.getDirection()) > 0); +	{ +		if (mMoon.isVisible()) +		{ +			sun_flag = look_at * mSun.getDirection() > 0; +		} +		else +		{ +			sun_flag = TRUE; +		}  	} -    bool above_water = (height_above_water > 0); -    bool render_ref  = above_water && gPipeline.getPool(LLDrawPool::POOL_WATER)->getVertexShaderLevel() == 0; -    setDrawRefl(above_water ? (sun_flag ? 0 : 1) : -1); -    if (render_ref) -	{         -        updateReflectionGeometry(drawable, height_above_water, mSun); -    } +	if (height_above_water > 0) +	{ +		BOOL render_ref = gPipeline.getPool(LLDrawPool::POOL_WATER)->getVertexShaderLevel() == 0; + +		if (sun_flag) +		{ +			setDrawRefl(0); +			if (render_ref) +			{ +				updateReflectionGeometry(drawable, height_above_water, mSun); +			} +		} +		else +		{ +			setDrawRefl(1); +			if (render_ref) +			{ +				updateReflectionGeometry(drawable, height_above_water, mMoon); +			} +		} +	} +	else +	{ +		setDrawRefl(-1); +	}  	LLPipeline::sCompiles++;  	return TRUE;  } -bool LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, F32 scale, const S32 f, LLHeavenBody& hb, const LLVector3 &up, const LLVector3 &right) +BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, const BOOL is_sun, +										 LLHeavenBody& hb, const F32 cos_max_angle, +										 const LLVector3 &up, const LLVector3 &right)  {  	mHeavenlyBodyUpdated = TRUE ; @@ -1199,28 +1412,52 @@ bool LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, F32 scale, const  	S32 index_offset;  	LLFace *facep; -	LLVector3 to_dir   = hb.getDirection(); +	LLVector3 to_dir = hb.getDirection(); + +	if (!is_sun) +	{ +		to_dir.mV[2] = llmax(to_dir.mV[2]+0.1f, 0.1f); +	}  	LLVector3 draw_pos = to_dir * HEAVENLY_BODY_DIST; +  	LLVector3 hb_right = to_dir % LLVector3::z_axis;  	LLVector3 hb_up = hb_right % to_dir;  	hb_right.normalize();  	hb_up.normalize(); -    const F32 enlargm_factor = ( 1 - to_dir.mV[2] ); +	//const static F32 cos_max_turn = sqrt(3.f) / 2; // 30 degrees +	//const F32 cos_turn_right = 1. / (llmax(cos_max_turn, hb_right * right)); +	//const F32 cos_turn_up = 1. / llmax(cos_max_turn, hb_up * up); + +	const F32 enlargm_factor = ( 1 - to_dir.mV[2] );  	F32 horiz_enlargement = 1 + enlargm_factor * 0.3f;  	F32 vert_enlargement = 1 + enlargm_factor * 0.2f; -	const LLVector3 scaled_right = horiz_enlargement * scale * HEAVENLY_BODY_DIST * HEAVENLY_BODY_FACTOR * hb.getDiskRadius() * hb_right; -	const LLVector3 scaled_up    = vert_enlargement  * scale * HEAVENLY_BODY_DIST * HEAVENLY_BODY_FACTOR * hb.getDiskRadius() * hb_up; +	// Parameters for the water reflection +	hb.setU(HEAVENLY_BODY_FACTOR * horiz_enlargement * hb.getDiskRadius() * hb_right); +	hb.setV(HEAVENLY_BODY_FACTOR * vert_enlargement * hb.getDiskRadius() * hb_up); +	// End of parameters for the water reflection + +	const LLVector3 scaled_right = HEAVENLY_BODY_DIST * hb.getU(); +	const LLVector3 scaled_up = HEAVENLY_BODY_DIST * hb.getV(); +	//const LLVector3 scaled_right = horiz_enlargement * HEAVENLY_BODY_SCALE * hb.getDiskRadius() * hb_right;//right; +	//const LLVector3 scaled_up = vert_enlargement * HEAVENLY_BODY_SCALE * hb.getDiskRadius() * hb_up;//up;  	LLVector3 v_clipped[4]; -	v_clipped[0] = draw_pos - scaled_right + scaled_up; -	v_clipped[1] = draw_pos - scaled_right - scaled_up; -	v_clipped[2] = draw_pos + scaled_right + scaled_up; -	v_clipped[3] = draw_pos + scaled_right - scaled_up; +	hb.corner(0) = draw_pos - scaled_right + scaled_up; +	hb.corner(1) = draw_pos - scaled_right - scaled_up; +	hb.corner(2) = draw_pos + scaled_right + scaled_up; +	hb.corner(3) = draw_pos + scaled_right - scaled_up; + +	F32 t_left, t_right; +	if (!clip_quad_to_horizon(t_left, t_right, v_clipped, hb.corners(), cos_max_angle)) +	{ +		hb.setVisible(FALSE); +		return FALSE; +	}  	hb.setVisible(TRUE);  	facep = mFace[f];  @@ -1270,9 +1507,164 @@ bool LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, F32 scale, const  	facep->getVertexBuffer()->flush(); +	if (is_sun) +	{ +		if ((t_left > 0) && (t_right > 0)) +		{ +			F32 t = (t_left + t_right) * 0.5f; +			mSun.setHorizonVisibility(0.5f * (1 + cos(t * F_PI))); +		} +		else +		{ +			mSun.setHorizonVisibility(); +		} +		updateSunHaloGeometry(drawable); +	} +  	return TRUE;  } + + + +// Clips quads with top and bottom sides parallel to horizon. + +BOOL clip_quad_to_horizon(F32& t_left, F32& t_right, LLVector3 v_clipped[4], +						  const LLVector3 v_corner[4], const F32 cos_max_angle) +{ +	t_left = clip_side_to_horizon(v_corner[1], v_corner[0], cos_max_angle); +	t_right = clip_side_to_horizon(v_corner[3], v_corner[2], cos_max_angle); + +	if ((t_left >= 1) || (t_right >= 1)) +	{ +		return FALSE; +	} + +	//const BOOL left_clip = (t_left > 0); +	//const BOOL right_clip = (t_right > 0); + +	//if (!left_clip && !right_clip) +	{ +		for (S32 vtx = 0; vtx < 4; ++vtx) +		{ +			v_clipped[vtx]  = v_corner[vtx]; +		} +	} +/*	else +	{ +		v_clipped[0] = v_corner[0]; +		v_clipped[1] = left_clip ? ((1 - t_left) * v_corner[1] + t_left * v_corner[0]) +									: v_corner[1]; +		v_clipped[2] = v_corner[2]; +		v_clipped[3] = right_clip ? ((1 - t_right) * v_corner[3] + t_right * v_corner[2]) +									: v_corner[3]; +	}*/ + +	return TRUE; +} + + +F32 clip_side_to_horizon(const LLVector3& V0, const LLVector3& V1, const F32 cos_max_angle) +{ +	const LLVector3 V = V1 - V0; +	const F32 k2 = 1.f/(cos_max_angle * cos_max_angle) - 1; +	const F32 A = V.mV[0] * V.mV[0] + V.mV[1] * V.mV[1] - k2 * V.mV[2] * V.mV[2]; +	const F32 B = V0.mV[0] * V.mV[0] + V0.mV[1] * V.mV[1] - k2 * V0.mV[2] * V.mV[2]; +	const F32 C = V0.mV[0] * V0.mV[0] + V0.mV[1] * V0.mV[1] - k2 * V0.mV[2] * V0.mV[2]; + +	if (fabs(A) < 1e-7) +	{ +		return -0.1f;	// v0 is cone origin and v1 is on the surface of the cone. +	} + +	const F32 det = sqrt(B*B - A*C); +	const F32 t1 = (-B - det) / A; +	const F32 t2 = (-B + det) / A; +	const F32 z1 = V0.mV[2] + t1 * V.mV[2]; +	const F32 z2 = V0.mV[2] + t2 * V.mV[2]; +	if (z1 * cos_max_angle < 0) +	{ +		return t2; +	} +	else if (z2 * cos_max_angle < 0) +	{ +		return t1; +	} +	else if ((t1 < 0) || (t1 > 1)) +	{ +		return t2; +	} +	else +	{ +		return t1; +	} +} + + +void LLVOSky::updateSunHaloGeometry(LLDrawable *drawable ) +{ +#if 0 +	const LLVector3* v_corner = mSun.corners(); + +	LLStrider<LLVector3> verticesp; +	LLStrider<LLVector3> normalsp; +	LLStrider<LLVector2> texCoordsp; +	LLStrider<U16> indicesp; +	S32 index_offset; +	LLFace *face; + +	const LLVector3 right = 2 * (v_corner[2] - v_corner[0]); +	LLVector3 up = 2 * (v_corner[2] - v_corner[3]); +	up.normalize(); +	F32 size = right.length(); +	up = size * up; +	const LLVector3 draw_pos = 0.25 * (v_corner[0] + v_corner[1] + v_corner[2] + v_corner[3]); +	 +	LLVector3 v_glow_corner[4]; + +	v_glow_corner[0] = draw_pos - right + up; +	v_glow_corner[1] = draw_pos - right - up; +	v_glow_corner[2] = draw_pos + right + up; +	v_glow_corner[3] = draw_pos + right - up; + +	face = mFace[FACE_BLOOM];  + +	if (face->mVertexBuffer.isNull()) +	{ +		face->setSize(4, 6); +		face->setGeomIndex(0); +		face->setIndicesIndex(0); +		face->mVertexBuffer = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); +		face->mVertexBuffer->allocateBuffer(4, 6, TRUE); +	} + +	index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp); +	if (-1 == index_offset) +	{ +		return; +	} + +	for (S32 vtx = 0; vtx < 4; ++vtx) +	{ +		*(verticesp++)  = v_glow_corner[vtx] + mCameraPosAgent; +	} + +	*(texCoordsp++) = TEX01; +	*(texCoordsp++) = TEX00; +	*(texCoordsp++) = TEX11; +	*(texCoordsp++) = TEX10; + +	*indicesp++ = index_offset + 0; +	*indicesp++ = index_offset + 2; +	*indicesp++ = index_offset + 1; + +	*indicesp++ = index_offset + 1; +	*indicesp++ = index_offset + 2; +	*indicesp++ = index_offset + 3; +#endif +} + +  F32 dtReflection(const LLVector3& p, F32 cos_dir_from_top, F32 sin_dir_from_top, F32 diff_angl_dir)  {  	LLVector3 P = p; @@ -1334,6 +1726,9 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,  	LLVector3 look_at_right = look_at % LLVector3::z_axis;  	look_at_right.normalize(); +	const static F32 cos_horizon_angle = cosHorizon(0.0f/sResolution); +	//const static F32 horizon_angle = acos(cos_horizon_angle); +  	const F32 enlargm_factor = ( 1 - to_dir.mV[2] );  	F32 horiz_enlargement = 1 + enlargm_factor * 0.3f;  	F32 vert_enlargement = 1 + enlargm_factor * 0.2f; @@ -1348,10 +1743,22 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,  	LLVector3 top_hb = v_corner[0] = stretch_corner[0] = hb_pos - Right + Up;  	v_corner[1] = stretch_corner[1] = hb_pos - Right - Up; +	F32 dt_hor, dt; +	dt_hor = clip_side_to_horizon(v_corner[1], v_corner[0], cos_horizon_angle); +  	LLVector2 TEX0t = TEX00;  	LLVector2 TEX1t = TEX10;  	LLVector3 lower_corner = v_corner[1]; +	if ((dt_hor > 0) && (dt_hor < 1)) +	{ +		TEX0t = LLVector2(0, dt_hor); +		TEX1t = LLVector2(1, dt_hor); +		lower_corner = (1 - dt_hor) * v_corner[1] + dt_hor * v_corner[0]; +	} +	else +		dt_hor = llmax(0.0f, llmin(1.0f, dt_hor)); +  	top_hb.normalize();  	const F32 cos_angle_of_view = fabs(top_hb.mV[VZ]);  	const F32 extension = llmin (5.0f, 1.0f / cos_angle_of_view); @@ -1363,6 +1770,9 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,  	stretch_corner[0] = lower_corner + extension * (stretch_corner[0] - lower_corner);  	stretch_corner[1] = lower_corner + extension * (stretch_corner[1] - lower_corner); +	dt = dt_hor; + +  	F32 cos_dir_from_top[2];  	LLVector3 dir = stretch_corner[0]; @@ -1451,8 +1861,9 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,  		F32 dt_tex = dtReflection(P, cos_dir_from_top[0], sin_dir_from_top, diff_angl_dir); -		TEX0tt = LLVector2(0, dt_tex); -		TEX1tt = LLVector2(1, dt_tex); +		dt = dt_tex; +		TEX0tt = LLVector2(0, dt); +		TEX1tt = LLVector2(1, dt);  		quads++;  	}  	else @@ -1463,225 +1874,408 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,  	LLFace *face = mFace[FACE_REFLECTION];  -    if (face) -    { -        if (!face->getVertexBuffer() || quads * 4 != face->getGeomCount()) -        { -            face->setSize(quads * 4, quads * 6); -            LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); -			if (!buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE)) +	if (!face->getVertexBuffer() || quads*4 != face->getGeomCount()) +	{ +		face->setSize(quads * 4, quads * 6); +		LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); +		if (!buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE)) +		{ +			LL_WARNS() << "Failed to allocate Vertex Buffer for vosky to " +				<< face->getGeomCount() << " vertices and " +				<< face->getIndicesCount() << " indices" << LL_ENDL; +		} +		face->setIndicesIndex(0); +		face->setGeomIndex(0); +		face->setVertexBuffer(buff); +	} +	 +	LLStrider<LLVector3> verticesp; +	LLStrider<LLVector3> normalsp; +	LLStrider<LLVector2> texCoordsp; +	LLStrider<U16> indicesp; +	S32 index_offset; +	 +	index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp); +	if (-1 == index_offset) +	{ +		return; +	} + +	LLColor3 hb_col3 = HB.getInterpColor(); +	hb_col3.clamp(); +	const LLColor4 hb_col = LLColor4(hb_col3); + +	const F32 min_attenuation = 0.4f; +	const F32 max_attenuation = 0.7f; +	const F32 attenuation = min_attenuation +		+ cos_angle_of_view * (max_attenuation - min_attenuation); + +	LLColor4 hb_refl_col = (1-attenuation) * hb_col + attenuation * mFogColor; +	face->setFaceColor(hb_refl_col); +	 +	LLVector3 v_far[2]; +	v_far[0] = v_refl_corner[1]; +	v_far[1] = v_refl_corner[3]; + +	if(dt_clip > 0) +	{ +		if (dt_clip >= 1) +		{ +			for (S32 vtx = 0; vtx < 4; ++vtx) +			{ +				F32 ratio = far_clip / v_refl_corner[vtx].length(); +				*(verticesp++) = v_refl_corner[vtx] = ratio * v_refl_corner[vtx] + mCameraPosAgent; +			} +			const LLVector3 draw_pos = 0.25 * +				(v_refl_corner[0] + v_refl_corner[1] + v_refl_corner[2] + v_refl_corner[3]); +			face->mCenterAgent = draw_pos; +		} +		else +		{ +			F32 ratio = far_clip / v_refl_corner[1].length(); +			v_sprite_corner[1] = v_refl_corner[1] * ratio; + +			ratio = far_clip / v_refl_corner[3].length(); +			v_sprite_corner[3] = v_refl_corner[3] * ratio; + +			v_refl_corner[1] = (1 - dt_clip) * v_refl_corner[1] + dt_clip * v_refl_corner[0]; +			v_refl_corner[3] = (1 - dt_clip) * v_refl_corner[3] + dt_clip * v_refl_corner[2]; +			v_sprite_corner[0] = v_refl_corner[1]; +			v_sprite_corner[2] = v_refl_corner[3]; + +			for (S32 vtx = 0; vtx < 4; ++vtx)  			{ -				LL_WARNS() << "Failed to allocate Vertex Buffer for vosky to " -					<< face->getGeomCount() << " vertices and " -					<< face->getIndicesCount() << " indices" << LL_ENDL; +				*(verticesp++) = v_sprite_corner[vtx] + mCameraPosAgent;  			} -            face->setIndicesIndex(0); -            face->setGeomIndex(0); -            face->setVertexBuffer(buff); -        } - -        LLStrider<LLVector3> verticesp; -        LLStrider<LLVector3> normalsp; -        LLStrider<LLVector2> texCoordsp; -        LLStrider<U16> indicesp; -        S32 index_offset; - -        index_offset = face->getGeometry(verticesp, normalsp, texCoordsp, indicesp); -        if (-1 == index_offset) -        { -            return; -        } - -        LLColor3 hb_col3 = HB.getInterpColor(); -        hb_col3.clamp(); -        const LLColor4 hb_col = LLColor4(hb_col3); - -        const F32 min_attenuation = 0.4f; -        const F32 max_attenuation = 0.7f; -        const F32 attenuation = min_attenuation -            + cos_angle_of_view * (max_attenuation - min_attenuation); - -        LLColor4 hb_refl_col = (1 - attenuation) * hb_col + attenuation * getSkyFogColor(); -        face->setFaceColor(hb_refl_col); - -        LLVector3 v_far[2]; -        v_far[0] = v_refl_corner[1]; -        v_far[1] = v_refl_corner[3]; - -        if (dt_clip > 0) -        { -            if (dt_clip >= 1) -            { -                for (S32 vtx = 0; vtx < 4; ++vtx) -                { -                    F32 ratio = far_clip / v_refl_corner[vtx].length(); -                    *(verticesp++) = v_refl_corner[vtx] = ratio * v_refl_corner[vtx] + mCameraPosAgent; -                } -                const LLVector3 draw_pos = 0.25 * -                    (v_refl_corner[0] + v_refl_corner[1] + v_refl_corner[2] + v_refl_corner[3]); -                face->mCenterAgent = draw_pos; -            } -            else -            { -                F32 ratio = far_clip / v_refl_corner[1].length(); -                v_sprite_corner[1] = v_refl_corner[1] * ratio; - -                ratio = far_clip / v_refl_corner[3].length(); -                v_sprite_corner[3] = v_refl_corner[3] * ratio; - -                v_refl_corner[1] = (1 - dt_clip) * v_refl_corner[1] + dt_clip * v_refl_corner[0]; -                v_refl_corner[3] = (1 - dt_clip) * v_refl_corner[3] + dt_clip * v_refl_corner[2]; -                v_sprite_corner[0] = v_refl_corner[1]; -                v_sprite_corner[2] = v_refl_corner[3]; - -                for (S32 vtx = 0; vtx < 4; ++vtx) -                { -                    *(verticesp++) = v_sprite_corner[vtx] + mCameraPosAgent; -                } - -                const LLVector3 draw_pos = 0.25 * -                    (v_refl_corner[0] + v_sprite_corner[1] + v_refl_corner[2] + v_sprite_corner[3]); -                face->mCenterAgent = draw_pos; -            } - -            *(texCoordsp++) = TEX0tt; -            *(texCoordsp++) = TEX0t; -            *(texCoordsp++) = TEX1tt; -            *(texCoordsp++) = TEX1t; - -            *indicesp++ = index_offset + 0; -            *indicesp++ = index_offset + 2; -            *indicesp++ = index_offset + 1; - -            *indicesp++ = index_offset + 1; -            *indicesp++ = index_offset + 2; -            *indicesp++ = index_offset + 3; - -            index_offset += 4; -        } - -        if (dt_clip < 1) -        { -            if (dt_clip <= 0) -            { -                const LLVector3 draw_pos = 0.25 * -                    (v_refl_corner[0] + v_refl_corner[1] + v_refl_corner[2] + v_refl_corner[3]); -                face->mCenterAgent = draw_pos; -            } - -            const F32 raws_inv = 1.f / raws; -            const F32 cols_inv = 1.f / cols; -            LLVector3 left = v_refl_corner[0] - v_refl_corner[1]; -            LLVector3 right = v_refl_corner[2] - v_refl_corner[3]; -            left *= raws_inv; -            right *= raws_inv; - -            for (S32 raw = 0; raw < raws; ++raw) -            { -                F32 dt_v0 = raw * raws_inv; -                F32 dt_v1 = (raw + 1) * raws_inv; -                const LLVector3 BL = v_refl_corner[1] + (F32)raw * left; -                const LLVector3 BR = v_refl_corner[3] + (F32)raw * right; -                const LLVector3 EL = BL + left; -                const LLVector3 ER = BR + right; -                dt_v0 = dt_v1 = dtReflection(EL, cos_dir_from_top[0], sin_dir_from_top, diff_angl_dir); -                for (S32 col = 0; col < cols; ++col) -                { -                    F32 dt_h0 = col * cols_inv; -                    *(verticesp++) = (1 - dt_h0) * EL + dt_h0 * ER + mCameraPosAgent; -                    *(verticesp++) = (1 - dt_h0) * BL + dt_h0 * BR + mCameraPosAgent; -                    F32 dt_h1 = (col + 1) * cols_inv; -                    *(verticesp++) = (1 - dt_h1) * EL + dt_h1 * ER + mCameraPosAgent; -                    *(verticesp++) = (1 - dt_h1) * BL + dt_h1 * BR + mCameraPosAgent; - -                    *(texCoordsp++) = LLVector2(dt_h0, dt_v1); -                    *(texCoordsp++) = LLVector2(dt_h0, dt_v0); -                    *(texCoordsp++) = LLVector2(dt_h1, dt_v1); -                    *(texCoordsp++) = LLVector2(dt_h1, dt_v0); - -                    *indicesp++ = index_offset + 0; -                    *indicesp++ = index_offset + 2; -                    *indicesp++ = index_offset + 1; - -                    *indicesp++ = index_offset + 1; -                    *indicesp++ = index_offset + 2; -                    *indicesp++ = index_offset + 3; - -                    index_offset += 4; -                } -            } -        } - -        face->getVertexBuffer()->flush(); -    } + +			const LLVector3 draw_pos = 0.25 * +				(v_refl_corner[0] + v_sprite_corner[1] + v_refl_corner[2] + v_sprite_corner[3]); +			face->mCenterAgent = draw_pos; +		} + +		*(texCoordsp++) = TEX0tt; +		*(texCoordsp++) = TEX0t; +		*(texCoordsp++) = TEX1tt; +		*(texCoordsp++) = TEX1t; + +		*indicesp++ = index_offset + 0; +		*indicesp++ = index_offset + 2; +		*indicesp++ = index_offset + 1; + +		*indicesp++ = index_offset + 1; +		*indicesp++ = index_offset + 2; +		*indicesp++ = index_offset + 3; + +		index_offset += 4; +	} + +	if (dt_clip < 1) +	{ +		if (dt_clip <= 0) +		{ +			const LLVector3 draw_pos = 0.25 * +				(v_refl_corner[0] + v_refl_corner[1] + v_refl_corner[2] + v_refl_corner[3]); +			face->mCenterAgent = draw_pos; +		} + +		const F32 raws_inv = 1.f/raws; +		const F32 cols_inv = 1.f/cols; +		LLVector3 left	= v_refl_corner[0] - v_refl_corner[1]; +		LLVector3 right = v_refl_corner[2] - v_refl_corner[3]; +		left *= raws_inv; +		right *= raws_inv; + +		F32 dt_raw = dt; + +		for (S32 raw = 0; raw < raws; ++raw) +		{ +			F32 dt_v0 = raw * raws_inv; +			F32 dt_v1 = (raw + 1) * raws_inv; +			const LLVector3 BL = v_refl_corner[1] + (F32)raw * left; +			const LLVector3 BR = v_refl_corner[3] + (F32)raw * right; +			const LLVector3 EL = BL + left; +			const LLVector3 ER = BR + right; +			dt_v0 = dt_raw; +			dt_raw = dt_v1 = dtReflection(EL, cos_dir_from_top[0], sin_dir_from_top, diff_angl_dir); +			for (S32 col = 0; col < cols; ++col) +			{ +				F32 dt_h0 = col * cols_inv; +				*(verticesp++) = (1 - dt_h0) * EL + dt_h0 * ER + mCameraPosAgent; +				*(verticesp++) = (1 - dt_h0) * BL + dt_h0 * BR + mCameraPosAgent; +				F32 dt_h1 = (col + 1) * cols_inv; +				*(verticesp++) = (1 - dt_h1) * EL + dt_h1 * ER + mCameraPosAgent; +				*(verticesp++) = (1 - dt_h1) * BL + dt_h1 * BR + mCameraPosAgent; + +				*(texCoordsp++) = LLVector2(dt_h0, dt_v1); +				*(texCoordsp++) = LLVector2(dt_h0, dt_v0); +				*(texCoordsp++) = LLVector2(dt_h1, dt_v1); +				*(texCoordsp++) = LLVector2(dt_h1, dt_v0); + +				*indicesp++ = index_offset + 0; +				*indicesp++ = index_offset + 2; +				*indicesp++ = index_offset + 1; + +				*indicesp++ = index_offset + 1; +				*indicesp++ = index_offset + 2; +				*indicesp++ = index_offset + 3; + +				index_offset += 4; +			} +		} +	} + +	face->getVertexBuffer()->flush();  } + + +  void LLVOSky::updateFog(const F32 distance)  { -    LLEnvironment& environment = LLEnvironment::instance(); -    if (environment.getCurrentSky() != nullptr) -    { -        LLVector3 light_dir = LLVector3(environment.getClampedLightNorm()); -        m_legacyAtmospherics.updateFog(distance, light_dir); -    } -} +	if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOG)) +	{ +		if (!LLGLSLShader::sNoFixedFunction) +		{ +			glFogf(GL_FOG_DENSITY, 0); +			glFogfv(GL_FOG_COLOR, (F32 *) &LLColor4::white.mV); +			glFogf(GL_FOG_END, 1000000.f); +		} +		return; +	} -void LLVOSky::setSunAndMoonDirectionsCFR(const LLVector3 &sun_dir_cfr, const LLVector3 &moon_dir_cfr) -{ -    mSun.setDirection(sun_dir_cfr);	 -	mMoon.setDirection(moon_dir_cfr); +	const BOOL hide_clip_plane = TRUE; +	LLColor4 target_fog(0.f, 0.2f, 0.5f, 0.f); -	// Push the sun "South" as it approaches directly overhead so that we can always see bump mapping -	// on the upward facing faces of cubes. -    { -	    // Same as dot product with the up direction + clamp. -	    F32 sunDot = llmax(0.f, sun_dir_cfr.mV[2]); -	    sunDot *= sunDot;	 +	const F32 water_height = gAgent.getRegion() ? gAgent.getRegion()->getWaterHeight() : 0.f; +	// LLWorld::getInstance()->getWaterHeight(); +	F32 camera_height = gAgentCamera.getCameraPositionAgent().mV[2]; + +	F32 near_clip_height = LLViewerCamera::getInstance()->getAtAxis().mV[VZ] * LLViewerCamera::getInstance()->getNear(); +	camera_height += near_clip_height; + +	F32 fog_distance = 0.f; +	LLColor3 res_color[3]; + +	LLColor3 sky_fog_color = LLColor3::white; +	LLColor3 render_fog_color = LLColor3::white; -	    // Create normalized vector that has the sunDir pushed south about an hour and change. -	    LLVector3 adjustedDir = (sun_dir_cfr + LLVector3(0.f, -0.70711f, 0.70711f)) * 0.5f; +	LLVector3 tosun = getToSunLast(); +	const F32 tosun_z = tosun.mV[VZ]; +	tosun.mV[VZ] = 0.f; +	tosun.normalize(); +	LLVector3 perp_tosun; +	perp_tosun.mV[VX] = -tosun.mV[VY]; +	perp_tosun.mV[VY] = tosun.mV[VX]; +	LLVector3 tosun_45 = tosun + perp_tosun; +	tosun_45.normalize(); -	    // Blend between normal sun dir and adjusted sun dir based on how close we are -	    // to having the sun overhead. -	    mBumpSunDir = adjustedDir * sunDot + sun_dir_cfr * (1.0f - sunDot); -	    mBumpSunDir.normalize(); -    } +	F32 delta = 0.06f; +	tosun.mV[VZ] = delta; +	perp_tosun.mV[VZ] = delta; +	tosun_45.mV[VZ] = delta; +	tosun.normalize(); +	perp_tosun.normalize(); +	tosun_45.normalize(); -	updateDirections(); +	// Sky colors, just slightly above the horizon in the direction of the sun, perpendicular to the sun, and at a 45 degree angle to the sun. +	initAtmospherics(); +	res_color[0] = calcSkyColorInDir(tosun); +	res_color[1] = calcSkyColorInDir(perp_tosun); +	res_color[2] = calcSkyColorInDir(tosun_45); -    mForceUpdate = true; +	sky_fog_color = color_norm(res_color[0] + res_color[1] + res_color[2]); + +	F32 full_off = -0.25f; +	F32 full_on = 0.00f; +	F32 on = (tosun_z - full_off) / (full_on - full_off); +	on = llclamp(on, 0.01f, 1.f); +	sky_fog_color *= 0.5f * on; + + +	// We need to clamp these to non-zero, in order for the gamma correction to work. 0^y = ??? +	S32 i; +	for (i = 0; i < 3; i++) +	{ +		sky_fog_color.mV[i] = llmax(0.0001f, sky_fog_color.mV[i]); +	} + +	color_gamma_correct(sky_fog_color); + +	render_fog_color = sky_fog_color; + +	F32 fog_density = 0.f; +	fog_distance = mFogRatio * distance; +	 +	if (camera_height > water_height) +	{ +		LLColor4 fog(render_fog_color); +		if (!LLGLSLShader::sNoFixedFunction) +		{ +			glFogfv(GL_FOG_COLOR, fog.mV); +		} +		mGLFogCol = fog; + +		if (hide_clip_plane) +		{ +			// For now, set the density to extend to the cull distance. +			const F32 f_log = 2.14596602628934723963618357029f; // sqrt(fabs(log(0.01f))) +			fog_density = f_log/fog_distance; +			if (!LLGLSLShader::sNoFixedFunction) +			{ +				glFogi(GL_FOG_MODE, GL_EXP2); +			} +		} +		else +		{ +			const F32 f_log = 4.6051701859880913680359829093687f; // fabs(log(0.01f)) +			fog_density = (f_log)/fog_distance; +			if (!LLGLSLShader::sNoFixedFunction) +			{ +				glFogi(GL_FOG_MODE, GL_EXP); +			} +		} +	} +	else +	{ +		F32 depth = water_height - camera_height; +		 +		// get the water param manager variables +		float water_fog_density = LLWaterParamManager::getInstance()->getFogDensity(); +		LLColor4 water_fog_color(LLDrawPoolWater::sWaterFogColor.mV); +		 +		// adjust the color based on depth.  We're doing linear approximations +		float depth_scale = gSavedSettings.getF32("WaterGLFogDepthScale"); +		float depth_modifier = 1.0f - llmin(llmax(depth / depth_scale, 0.01f),  +			gSavedSettings.getF32("WaterGLFogDepthFloor")); + +		LLColor4 fogCol = water_fog_color * depth_modifier; +		fogCol.setAlpha(1); + +		// set the gl fog color +		mGLFogCol = fogCol; + +		// set the density based on what the shaders use +		fog_density = water_fog_density * gSavedSettings.getF32("WaterGLFogDensityScale"); + +		if (!LLGLSLShader::sNoFixedFunction) +		{ +			glFogfv(GL_FOG_COLOR, (F32 *) &fogCol.mV); +			glFogi(GL_FOG_MODE, GL_EXP2); +		} +	} + +	mFogColor = sky_fog_color; +	mFogColor.setAlpha(1); +	LLDrawPoolWater::sWaterFogEnd = fog_distance*2.2f; + +	if (!LLGLSLShader::sNoFixedFunction) +	{ +		LLGLSFog gls_fog; +		glFogf(GL_FOG_END, fog_distance*2.2f); +		glFogf(GL_FOG_DENSITY, fog_density); +		glHint(GL_FOG_HINT, GL_NICEST); +	} +	stop_glerror();  } -void LLVOSky::setSunDirectionCFR(const LLVector3 &sun_dir_cfr) + +// Functions used a lot. +F32 color_norm_pow(LLColor3& col, F32 e, BOOL postmultiply)  { -    mSun.setDirection(sun_dir_cfr);	 +	F32 mv = color_max(col); +	if (0 == mv) +	{ +		return 0; +	} -	// Push the sun "South" as it approaches directly overhead so that we can always see bump mapping -	// on the upward facing faces of cubes. -    { -	    // Same as dot product with the up direction + clamp. -	    F32 sunDot = llmax(0.f, sun_dir_cfr.mV[2]); -	    sunDot *= sunDot;	 +	col *= 1.f / mv; +	color_pow(col, e); +	if (postmultiply) +	{ +		col *= mv; +	} +	return mv; +} -	    // Create normalized vector that has the sunDir pushed south about an hour and change. -	    LLVector3 adjustedDir = (sun_dir_cfr + LLVector3(0.f, -0.70711f, 0.70711f)) * 0.5f; +// Returns angle (RADIANs) between the horizontal projection of "v" and the x_axis. +// Range of output is 0.0f to 2pi //359.99999...f +// Returns 0.0f when "v" = +/- z_axis. +F32 azimuth(const LLVector3 &v) +{ +	F32 azimuth = 0.0f; +	if (v.mV[VX] == 0.0f) +	{ +		if (v.mV[VY] > 0.0f) +		{ +			azimuth = F_PI * 0.5f; +		} +		else if (v.mV[VY] < 0.0f) +		{ +			azimuth = F_PI * 1.5f;// 270.f; +		} +	} +	else +	{ +		azimuth = (F32) atan(v.mV[VY] / v.mV[VX]); +		if (v.mV[VX] < 0.0f) +		{ +			azimuth += F_PI; +		} +		else if (v.mV[VY] < 0.0f) +		{ +			azimuth += F_PI * 2; +		} +	}	 +	return azimuth; +} -	    // Blend between normal sun dir and adjusted sun dir based on how close we are -	    // to having the sun overhead. -	    mBumpSunDir = adjustedDir * sunDot + sun_dir_cfr * (1.0f - sunDot); -	    mBumpSunDir.normalize(); -    } +void LLVOSky::initSunDirection(const LLVector3 &sun_dir, const LLVector3 &sun_ang_velocity) +{ +	LLVector3 sun_direction = (sun_dir.length() == 0) ? LLVector3::x_axis : sun_dir; +	sun_direction.normalize(); +	mSun.setDirection(sun_direction); +	mSun.renewDirection(); +	mSun.setAngularVelocity(sun_ang_velocity); +	mMoon.setDirection(-mSun.getDirection()); +	mMoon.renewDirection(); +	mLastLightingDirection = mSun.getDirection(); -	updateDirections(); +	calcAtmospherics(); -    mForceUpdate = true; +	if ( !mInitialized ) +	{ +		init(); +		LLSkyTex::stepCurrent(); +	}		  } -void LLVOSky::setMoonDirectionCFR(const LLVector3 &moon_dir_cfr) +void LLVOSky::setSunDirection(const LLVector3 &sun_dir, const LLVector3 &sun_ang_velocity)  { -	mMoon.setDirection(moon_dir_cfr); - -	updateDirections(); +	LLVector3 sun_direction = (sun_dir.length() == 0) ? LLVector3::x_axis : sun_dir; +	sun_direction.normalize(); -    mForceUpdate = true; +	// Push the sun "South" as it approaches directly overhead so that we can always see bump mapping +	// on the upward facing faces of cubes. +	LLVector3 newDir = sun_direction; + +	// Same as dot product with the up direction + clamp. +	F32 sunDot = llmax(0.f, newDir.mV[2]); +	sunDot *= sunDot;	 + +	// Create normalized vector that has the sunDir pushed south about an hour and change. +	LLVector3 adjustedDir = (newDir + LLVector3(0.f, -0.70711f, 0.70711f)) * 0.5f; + +	// Blend between normal sun dir and adjusted sun dir based on how close we are +	// to having the sun overhead. +	mBumpSunDir = adjustedDir * sunDot + newDir * (1.0f - sunDot); +	mBumpSunDir.normalize(); + +	F32 dp = mLastLightingDirection * sun_direction; +	mSun.setDirection(sun_direction); +	mSun.setAngularVelocity(sun_ang_velocity); +	mMoon.setDirection(-sun_direction); +	calcAtmospherics(); +	if (dp < 0.995f) { //the sun jumped a great deal, update immediately +		mForceUpdate = TRUE; +	}  } diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 6ebc38109a..9c761cc4a6 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5859,7 +5859,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  		spec_mask = spec_mask | LLVertexBuffer::MAP_EMISSIVE;  	} -	BOOL batch_textures = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1; +	BOOL batch_textures = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1;  	if (batch_textures)  	{ diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index e651280265..828910c9c0 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -340,7 +340,6 @@ bool	LLPipeline::sRenderFrameTest = false;  bool	LLPipeline::sRenderAttachedLights = true;  bool	LLPipeline::sRenderAttachedParticles = true;  bool	LLPipeline::sRenderDeferred = false; -bool	LLPipeline::sRenderingWaterReflection = false;  bool    LLPipeline::sMemAllocationThrottled = false;  S32		LLPipeline::sVisibleLightCount = 0;  F32		LLPipeline::sMinRenderSize = 0.f; @@ -882,17 +881,24 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)  	if (LLPipeline::sRenderDeferred)  	{ +        U32 water_buffer_res = (U32) llmax(gSavedSettings.getS32("RenderWaterRefResolution"), 512);  		S32 shadow_detail = RenderShadowDetail;  		bool ssao = RenderDeferredSSAO; -		const U32 occlusion_divisor = 3; +		const U32 occlusion_divisor = 4;  		//allocate deferred rendering color buffers  		if (!mDeferredScreen.allocate(resX, resY, GL_SRGB8_ALPHA8, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;  		if (!mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; + +        if (!mWaterDeferredScreen.allocate(water_buffer_res, water_buffer_res, GL_SRGB8_ALPHA8, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; +		if (!mWaterDeferredDepth.allocate(water_buffer_res,  water_buffer_res, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; +        if (!mWaterOcclusionDepth.allocate(water_buffer_res >> 1, water_buffer_res >> 1, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; +  		if (!mOcclusionDepth.allocate(resX/occlusion_divisor, resY/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;  		if (!addDeferredAttachments(mDeferredScreen)) return false; -	 +    	if (!addDeferredAttachments(mWaterDeferredScreen)) return false; +  		GLuint screenFormat = GL_RGBA16;  		if (gGLManager.mIsATI)  		{ @@ -917,10 +923,12 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)  		if (shadow_detail > 0 || ssao || RenderDepthOfField || samples > 0)  		{ //only need mDeferredLight for shadows OR ssao OR dof OR fxaa  			if (!mDeferredLight.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false; +            if (!mWaterDeferredLight.allocate(water_buffer_res, water_buffer_res, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;  		}  		else  		{  			mDeferredLight.release(); +            mWaterDeferredLight.release();  		}  		F32 scale = RenderShadowResolutionScale; @@ -930,11 +938,14 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)  		if (shadow_detail > 0)  		{ //allocate 4 sun shadow maps  			for (U32 i = 0; i < 4; i++) -			{ -		        //allocate VSM sun shadow map(s) -				if ((shadow_detail > 3) && !mShadow[i].allocate(sun_shadow_map_width, sun_shadow_map_height, GL_RGBA16F_ARB, FALSE, FALSE, LLTexUnit::TT_TEXTURE)) +			{		         +				if (shadow_detail > 3)                  { -                    return false; +                    //allocate VSM sun shadow map(s) +                    if (!mShadow[i].allocate(sun_shadow_map_width, sun_shadow_map_height, GL_RGBA16F_ARB, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) +                    { +                        return false; +                    }                  }                  else if (!mShadow[i].allocate(sun_shadow_map_width, sun_shadow_map_height, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE))                  { @@ -955,12 +966,17 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)  			}  		} -// for EEP atmospherics -		bool allocated_inscatter = mInscatter.allocate(resX >> 2, resY >> 2, GL_RGBA16F_ARB, FALSE, FALSE, LLTexUnit::TT_TEXTURE); -        	if (!allocated_inscatter) -        	{ -        	    return false; -        	} +        // for EEP atmospherics +        bool allocated_sh0 = mSkySH.allocate(64, 64, GL_RGBA16F_ARB, FALSE, FALSE, LLTexUnit::TT_TEXTURE); +        if (!allocated_sh0) +        { +        	return false; +        } +        else +        { +            mSkySH.addColorAttachment(GL_RGBA16F_ARB); +			mSkySH.addColorAttachment(GL_RGBA16F_ARB); +        }  		U32 width = (U32) (resX*scale);  		U32 height = width; @@ -1002,12 +1018,17 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)  	else  	{  		mDeferredLight.release(); -				 +        mWaterDeferredLight.release(); +  		releaseShadowTargets(); +  		mFXAABuffer.release();  		mScreen.release();  		mDeferredScreen.release(); //make sure to release any render targets that share a depth buffer with mDeferredScreen first  		mDeferredDepth.release(); +        mWaterDeferredScreen.release(); //make sure to release any render targets that share a depth buffer with mWaterDeferredScreen first +		mWaterDeferredDepth.release(); +        mWaterOcclusionDepth.release();  		mOcclusionDepth.release();  		if (!mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;		 @@ -1197,12 +1218,13 @@ void LLPipeline::releaseScreenBuffers()  	mPhysicsDisplay.release();  	mDeferredScreen.release();  	mDeferredDepth.release(); +    mWaterDeferredScreen.release(); +	mWaterDeferredDepth.release();  	mDeferredLight.release(); +    mWaterDeferredLight.release(); +    mWaterOcclusionDepth.release();  	mOcclusionDepth.release(); -		  	releaseShadowTargets(); - -	mInscatter.release();  } @@ -1227,19 +1249,13 @@ void LLPipeline::createGLBuffers()  	updateRenderDeferred(); -	bool materials_in_water = false; - -#if MATERIALS_IN_REFLECTIONS -	materials_in_water = gSavedSettings.getS32("RenderWaterMaterials"); -#endif -  	if (LLPipeline::sWaterReflections)  	{ //water reflection texture  		U32 res = (U32) llmax(gSavedSettings.getS32("RenderWaterRefResolution"), 512); -			 +  		// Set up SRGB targets if we're doing deferred-path reflection rendering  		// -		if (LLPipeline::sRenderDeferred && materials_in_water) +		if (LLPipeline::sRenderDeferred)  		{  			mWaterRef.allocate(res,res,GL_SRGB8_ALPHA8,TRUE,FALSE);  			//always use FBO for mWaterDis so it can be used for avatar texture bakes @@ -1247,10 +1263,10 @@ void LLPipeline::createGLBuffers()  		}  		else  		{ -		mWaterRef.allocate(res,res,GL_RGBA,TRUE,FALSE); -		//always use FBO for mWaterDis so it can be used for avatar texture bakes -		mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE, true); -	} +		    mWaterRef.allocate(res,res,GL_RGBA,TRUE,FALSE); +		    //always use FBO for mWaterDis so it can be used for avatar texture bakes +		    mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE, true); +	    }  	}  	mHighlight.allocate(256,256,GL_RGBA, FALSE, FALSE); @@ -1422,7 +1438,7 @@ bool LLPipeline::canUseVertexShaders()  bool LLPipeline::canUseWindLightShaders() const  { -    bool usingWindlight = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1; +    bool usingWindlight = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1;      bool haveShaders    = ((gWLSkyProgram.mProgramObject != 0) || (gDeferredWLSkyProgram.mProgramObject != 0));  	return (!LLPipeline::sDisableShaders && haveShaders && usingWindlight);  } @@ -1430,7 +1446,7 @@ bool LLPipeline::canUseWindLightShaders() const  bool LLPipeline::canUseWindLightShadersOnObjects() const  {  	return (canUseWindLightShaders()  -		&& LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0); +		&& LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0);  }  bool LLPipeline::canUseAntiAliasing() const @@ -1459,7 +1475,7 @@ void LLPipeline::enableShadows(const bool enable_shadows)  S32 LLPipeline::getMaxLightingDetail() const  { -	/*if (mVertexShaderLevel[SHADER_OBJECT] >= LLDrawPoolSimple::SHADER_LEVEL_LOCAL_LIGHTS) +	/*if (mShaderLevel[SHADER_OBJECT] >= LLDrawPoolSimple::SHADER_LEVEL_LOCAL_LIGHTS)  	{  		return 3;  	} @@ -2405,7 +2421,11 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl  	if (to_texture)  	{ -		if (LLPipeline::sRenderDeferred) +        if (LLPipeline::sRenderDeferred && LLPipeline::sReflectionRender)     +		{ +			mWaterOcclusionDepth.bindTarget(); +		} +		else if (LLPipeline::sRenderDeferred)  		{  			mOcclusionDepth.bindTarget();  		} @@ -2432,10 +2452,6 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl  	LLGLDisable test(GL_ALPHA_TEST);  	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - -// 	glh::matrix4f modelview = get_last_modelview(); -// 	glh::matrix4f proj = get_last_projection(); -  	LLGLDepthTest depth(GL_TRUE, GL_FALSE);  	bool bound_shader = false; @@ -2457,6 +2473,10 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl      camera.disableUserClipPlane(); +    bool use_far_clip = LLPipeline::sUseFarClip; + +    LLPipeline::sUseFarClip = false; +  	for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();   			iter != LLWorld::getInstance()->getRegionList().end(); ++iter)  	{ @@ -2483,6 +2503,8 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl  		}  	} +    LLPipeline::sUseFarClip = use_far_clip; +  	if (bound_shader)  	{  		gOcclusionCubeProgram.unbind(); @@ -2519,9 +2541,11 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl  		sCull->pushDrawable(gSky.mVOWLSkyp->mDrawable);  	} -    if (hasRenderType(LLPipeline::RENDER_TYPE_WATER)) +    bool render_water = !sReflectionRender && (hasRenderType(LLPipeline::RENDER_TYPE_WATER) || hasRenderType(LLPipeline::RENDER_TYPE_VOIDWATER)); + +    if (render_water)      { -        LLWorld::getInstance()->precullWaterObjects(camera, sCull, hasRenderType(LLPipeline::RENDER_TYPE_VOIDWATER)); +        LLWorld::getInstance()->precullWaterObjects(camera, sCull, render_water);      }  	gGL.matrixMode(LLRender::MM_PROJECTION); @@ -2536,7 +2560,11 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl  	if (to_texture)  	{ -		if (LLPipeline::sRenderDeferred) +        if (LLPipeline::sRenderDeferred && LLPipeline::sReflectionRender)     +		{ +			mWaterOcclusionDepth.flush(); +		} +		else if (LLPipeline::sRenderDeferred)  		{  			mOcclusionDepth.flush();  		} @@ -2622,7 +2650,7 @@ void LLPipeline::downsampleMinMaxDepthBuffer(LLRenderTarget& source, LLRenderTar  	{  		scratch_space->copyContents(source,  			0, 0, source.getWidth(), source.getHeight(), -			0, 0, scratch_space->getWidth(), scratch_space->getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); +			0, 0, scratch_space->getWidth(), scratch_space->getHeight(), source.hasStencil() ? GL_DEPTH_BUFFER_BIT : GL_COLOR_BUFFER_BIT, GL_NEAREST);  	}  	dest.bindTarget(); @@ -2681,7 +2709,7 @@ void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& d  	{  		scratch_space->copyContents(source,   									0, 0, source.getWidth(), source.getHeight(),  -									0, 0, scratch_space->getWidth(), scratch_space->getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); +									0, 0, scratch_space->getWidth(), scratch_space->getHeight(), source.hasStencil() ? (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT) : GL_COLOR_BUFFER_BIT, GL_NEAREST);  	}  	dest.bindTarget(); @@ -4244,7 +4272,7 @@ void LLPipeline::renderHighlights()  		//gGL.setSceneBlendType(LLRender::BT_ALPHA);  	} -	if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) +	if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))  	{  		gHighlightProgram.bind();  		gGL.diffuseColor4f(1,1,1,0.5f); @@ -4291,7 +4319,7 @@ void LLPipeline::renderHighlights()  	// have touch-handlers.  	mHighlightFaces.clear(); -	if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0) +	if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)  	{  		gHighlightProgram.unbind();  	} @@ -4300,7 +4328,7 @@ void LLPipeline::renderHighlights()  	if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::NORMAL_MAP))  	{  		color.setVec(1.0f, 0.5f, 0.5f, 0.5f); -		if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) +		if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))  		{  			gHighlightNormalProgram.bind();  			gGL.diffuseColor4f(1,1,1,0.5f); @@ -4321,7 +4349,7 @@ void LLPipeline::renderHighlights()  			facep->renderSelected(mFaceSelectImagep, color);  		} -		if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) +		if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))  		{  			gHighlightNormalProgram.unbind();  		} @@ -4330,7 +4358,7 @@ void LLPipeline::renderHighlights()  	if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::SPECULAR_MAP))  	{  		color.setVec(0.0f, 0.3f, 1.0f, 0.8f); -		if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) +		if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))  		{  			gHighlightSpecularProgram.bind();  			gGL.diffuseColor4f(1,1,1,0.5f); @@ -4351,7 +4379,7 @@ void LLPipeline::renderHighlights()  			facep->renderSelected(mFaceSelectImagep, color);  		} -		if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) +		if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))  		{  			gHighlightSpecularProgram.unbind();  		} @@ -4639,63 +4667,46 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)  	LLGLState::checkTextureChannels();  	LLGLState::checkClientArrays(); -	U32 cur_type = 0; -  	gGL.setColorMask(true, true); -	 -	pool_set_t::iterator iter1 = mPools.begin(); -	while ( iter1 != mPools.end() ) +	pool_set_t::iterator iter = mPools.begin(); +	while ( iter != mPools.end() )  	{ -		LLDrawPool *poolp = *iter1; -		 -		cur_type = poolp->getType(); +		LLDrawPool* poolp = *iter;		 +        llassert(poolp != nullptr); +        if (poolp) +        { +            U32 pool_type = poolp->getType(); +            S32 deferred_passes = poolp->getNumDeferredPasses(); +		    if (hasRenderType(pool_type) && (deferred_passes > 0)) +		    { +			    LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLRENDER); -		pool_set_t::iterator iter2 = iter1; -		if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0) -		{ -			LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLRENDER); +			    gGLLastMatrix = NULL; +			    gGL.loadMatrix(gGLModelView); -			gGLLastMatrix = NULL; -			gGL.loadMatrix(gGLModelView); -		 -			for( S32 i = 0; i < poolp->getNumDeferredPasses(); i++ ) -			{ -				LLVertexBuffer::unbind(); -				poolp->beginDeferredPass(i); -				for (iter2 = iter1; iter2 != mPools.end(); iter2++) -				{ -					LLDrawPool *p = *iter2; -					if (p->getType() != cur_type) -					{ -						break; -					} -										 -					if ( !p->getSkipRenderFlag() ) { p->renderDeferred(i); } -				} -				poolp->endDeferredPass(i); -				LLVertexBuffer::unbind(); +			    for( S32 i = 0; i < deferred_passes; i++ ) +			    { +                    LLVertexBuffer::unbind(); +                    stop_glerror(); -				if (gDebugGL || gDebugPipeline) -				{ -					LLGLState::checkStates(); -				} -			} -		} -		else -		{ -			// Skip all pools of this type -			for (iter2 = iter1; iter2 != mPools.end(); iter2++) -			{ -				LLDrawPool *p = *iter2; -				if (p->getType() != cur_type) -				{ -					break; -				} -			} -		} -		iter1 = iter2; -		stop_glerror(); +				    poolp->beginDeferredPass(i); +		            poolp->renderDeferred(i); +				    poolp->endDeferredPass(i); + +                    // per-pass validation that our conception of current GL state is correct +				    if (gDebugGL || gDebugPipeline) +				    { +					    LLGLState::checkStates(); +				    } +			    } + +                LLVertexBuffer::unbind(); +                stop_glerror(); +		    } +        } + +        iter++;  	}  	gGLLastMatrix = NULL; @@ -4733,7 +4744,8 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)  			gGLLastMatrix = NULL;  			gGL.loadMatrix(gGLModelView);  			LLGLSLShader::bindNoShader(); -			doOcclusion(camera, mScreen, mOcclusionDepth, &mDeferredDepth); + +			doOcclusion(camera, mScreen, sReflectionRender ? mWaterOcclusionDepth : mOcclusionDepth, sReflectionRender ? &mWaterDeferredDepth : &mDeferredDepth);  			gGL.setColorMask(true, false);  		} @@ -5370,6 +5382,55 @@ void LLPipeline::renderDebug()  	visible_selected_groups.clear(); +    if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SH) && gSavedSettings.getBOOL("RenderUseAdvancedAtmospherics") && LLPipeline::sRenderDeferred) +    { +        bindDeferredShader(gDeferredShVisProgram); + +        S32 l1r_channel = gDeferredShVisProgram.enableTexture(LLShaderMgr::SH_INPUT_L1R, gPipeline.mSkySH.getUsage()); +	    if (l1r_channel > -1) +	    { +		    gPipeline.mSkySH.bindTexture(0,l1r_channel); +		    gGL.getTexUnit(l1r_channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); +	    } +		 +        S32 l1b_channel = gDeferredShVisProgram.enableTexture(LLShaderMgr::SH_INPUT_L1G, gPipeline.mSkySH.getUsage()); +	    if (l1b_channel > -1) +	    { +		    gPipeline.mSkySH.bindTexture(1,l1b_channel); +		    gGL.getTexUnit(l1b_channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); +	    } + +        S32 l1g_channel = gDeferredShVisProgram.enableTexture(LLShaderMgr::SH_INPUT_L1B, gPipeline.mSkySH.getUsage()); +	    if (l1g_channel > -1) +	    { +		    gPipeline.mSkySH.bindTexture(2,l1g_channel); +		    gGL.getTexUnit(l1g_channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); +	    } +         +        LLGLDisable   blend(GL_BLEND); +		LLGLDepthTest depth(GL_FALSE, GL_FALSE, GL_ALWAYS); + +        LLVector3 pos = LLViewerCamera::instance().getOrigin(); +        pos += LLViewerCamera::instance().getAtAxis() * 10.0f; + +        gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); + +        gGL.begin(LLRender::TRIANGLES); +		gGL.texCoord2f(0.0f, 0.0f); +		gGL.vertex2f(-1,-1); +		 +		gGL.texCoord2f(0.0f, 1.0f); +		gGL.vertex2f(-1,3); +		 +		gGL.texCoord2f(1.0f, 0.0f); +		gGL.vertex2f(3,-1); +		 +		gGL.end(); +		gGL.flush(); + +        unbindDeferredShader(gDeferredShVisProgram); +    } +  	if (LLGLSLShader::sNoFixedFunction)  	{  		gUIProgram.bind(); @@ -7556,6 +7617,8 @@ static LLTrace::BlockTimerStatHandle FTM_RENDER_BLOOM("Bloom");  void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)  { +    LLRenderTarget* deferred_light_target = LLPipeline::sReflectionRender ? &mWaterDeferredLight : &mDeferredLight; +  	if (!(gPipeline.canUseVertexShaders() &&  		sRenderGlow))  	{ @@ -7847,7 +7910,7 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)  			F32 magnification = focal_length/(subject_distance-focal_length);  			{ //build diffuse+bloom+CoF -				mDeferredLight.bindTarget(); +				deferred_light_target->bindTarget();  				shader = &gDeferredCoFProgram;  				bindDeferredShader(*shader); @@ -7878,7 +7941,7 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)  				gGL.end();  				unbindDeferredShader(*shader); -				mDeferredLight.flush(); +				deferred_light_target->flush();  			}  			U32 dof_width = (U32) (mScreen.getWidth()*CameraDoFResScale); @@ -7891,10 +7954,10 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)  				shader = &gDeferredPostProgram;  				bindDeferredShader(*shader); -				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); +				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, deferred_light_target->getUsage());  				if (channel > -1)  				{ -					mDeferredLight.bindTexture(0, channel); +					deferred_light_target->bindTexture(0, channel);  				}  				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); @@ -7920,8 +7983,8 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)  			{ //combine result based on alpha  				if (multisample)  				{ -					mDeferredLight.bindTarget(); -					glViewport(0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight()); +					deferred_light_target->bindTarget(); +					glViewport(0, 0, deferred_light_target->getWidth(), deferred_light_target->getHeight());  				}  				else  				{ @@ -7970,7 +8033,7 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)  				if (multisample)  				{ -					mDeferredLight.flush(); +					deferred_light_target->flush();  				}  			}  		} @@ -7978,7 +8041,7 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)  		{  			if (multisample)  			{ -				mDeferredLight.bindTarget(); +				deferred_light_target->bindTarget();  			}  			LLGLSLShader* shader = &gDeferredPostNoDoFProgram; @@ -8013,7 +8076,7 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)  			if (multisample)  			{ -				mDeferredLight.flush(); +				deferred_light_target->flush();  			}  		} @@ -8031,10 +8094,10 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)  			shader->bind();  			shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height); -			S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); +			S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, deferred_light_target->getUsage());  			if (channel > -1)  			{ -				mDeferredLight.bindTexture(0, channel); +				deferred_light_target->bindTexture(0, channel);  			}  			gGL.begin(LLRender::TRIANGLE_STRIP); @@ -8045,7 +8108,7 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)  			gGL.flush(); -			shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); +			shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, deferred_light_target->getUsage());  			shader->unbind();  			mFXAABuffer.flush(); @@ -8209,63 +8272,69 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)  static LLTrace::BlockTimerStatHandle FTM_BIND_DEFERRED("Bind Deferred"); -void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 noise_map) +void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target)  {  	LL_RECORD_BLOCK_TIME(FTM_BIND_DEFERRED); -	if (noise_map == 0xFFFFFFFF) -	{ -		noise_map = mNoiseMap; -	} +    LLRenderTarget* deferred_target       = LLPipeline::sReflectionRender ? &mWaterDeferredScreen : &mDeferredScreen; +    LLRenderTarget* deferred_depth_target = LLPipeline::sReflectionRender ? &mWaterDeferredDepth  : &mDeferredDepth; +    LLRenderTarget* deferred_light_target = LLPipeline::sReflectionRender ? &mWaterDeferredLight  : &mDeferredLight;  	shader.bind();  	S32 channel = 0; -	channel = shader.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredScreen.getUsage()); +	channel = shader.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, deferred_target->getUsage());  	if (channel > -1)  	{ -		mDeferredScreen.bindTexture(0,channel); +		deferred_target->bindTexture(0,channel);  		gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);  	} -	channel = shader.enableTexture(LLShaderMgr::DEFERRED_SPECULAR, mDeferredScreen.getUsage()); +	channel = shader.enableTexture(LLShaderMgr::DEFERRED_SPECULAR, deferred_target->getUsage());  	if (channel > -1)  	{ -		mDeferredScreen.bindTexture(1, channel); +		deferred_target->bindTexture(1, channel);  		gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);  	} -	channel = shader.enableTexture(LLShaderMgr::DEFERRED_NORMAL, mDeferredScreen.getUsage()); +	channel = shader.enableTexture(LLShaderMgr::DEFERRED_NORMAL, deferred_target->getUsage());  	if (channel > -1)  	{ -		mDeferredScreen.bindTexture(2, channel); +		deferred_target->bindTexture(2, channel);  		gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);  	} -	channel = shader.enableTexture(LLShaderMgr::DEFERRED_DEPTH, mDeferredDepth.getUsage()); +	channel = shader.enableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_depth_target->getUsage());  	if (channel > -1)  	{ -		gGL.getTexUnit(channel)->bind(&mDeferredDepth, TRUE); +		gGL.getTexUnit(channel)->bind(deferred_depth_target, TRUE);  		stop_glerror(); -		 -		//glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);		 -		//glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_DEPTH_TEXTURE_MODE_ARB, GL_ALPHA);		 +    } -		stop_glerror(); +	glh::matrix4f projection = get_current_projection(); +	glh::matrix4f inv_proj   = projection.inverse(); -		glh::matrix4f projection = get_current_projection(); -		glh::matrix4f inv_proj = projection.inverse(); -		 -		shader.uniformMatrix4fv(LLShaderMgr::INVERSE_PROJECTION_MATRIX, 1, FALSE, inv_proj.m); -		shader.uniform4f(LLShaderMgr::VIEWPORT, (F32) gGLViewport[0], -									(F32) gGLViewport[1], -									(F32) gGLViewport[2], -									(F32) gGLViewport[3]); -	} +    if (shader.getUniformLocation(LLShaderMgr::INVERSE_PROJECTION_MATRIX) != -1) +    { +        shader.uniformMatrix4fv(LLShaderMgr::INVERSE_PROJECTION_MATRIX, 1, FALSE, inv_proj.m); +    } + +    if (shader.getUniformLocation(LLShaderMgr::VIEWPORT) != -1) +    { +	    shader.uniform4f(LLShaderMgr::VIEWPORT, (F32) gGLViewport[0], +								    (F32) gGLViewport[1], +								    (F32) gGLViewport[2], +								    (F32) gGLViewport[3]); +    } + +    if (sReflectionRender && shader.getUniformLocation(LLShaderMgr::MODELVIEW_MATRIX)) +    { +        shader.uniformMatrix4fv(LLShaderMgr::MODELVIEW_MATRIX, 1, FALSE, mReflectionModelView.m);             +    }  	channel = shader.enableTexture(LLShaderMgr::DEFERRED_NOISE);  	if (channel > -1)  	{ -		gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, noise_map); +		gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap);  		gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);  	} @@ -8277,17 +8346,11 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n  	stop_glerror(); -	channel = shader.enableTexture(LLShaderMgr::DEFERRED_LIGHT, mDeferredLight.getUsage()); +    light_target = light_target ? light_target : deferred_light_target; +	channel = shader.enableTexture(LLShaderMgr::DEFERRED_LIGHT, light_target->getUsage());  	if (channel > -1)  	{ -		if (light_index > 0) -		{ -			mScreen.bindTexture(0, channel); -		} -		else -		{ -			mDeferredLight.bindTexture(0, channel); -		} +        light_target->bindTexture(0, channel);  		gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);  	} @@ -8343,12 +8406,10 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n  		}  	} -	stop_glerror(); -  	F32 mat[16*6];  	for (U32 i = 0; i < 16; i++)  	{ -		mat[i] = mSunShadowMatrix[0].m[i]; +		mat[i]    = mSunShadowMatrix[0].m[i];  		mat[i+16] = mSunShadowMatrix[1].m[i];  		mat[i+32] = mSunShadowMatrix[2].m[i];  		mat[i+48] = mSunShadowMatrix[3].m[i]; @@ -8378,6 +8439,34 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n  		}  	} +    if (gAtmosphere) +    { +        // bind precomputed textures necessary for calculating sun and sky luminance +        channel = shader.enableTexture(LLShaderMgr::TRANSMITTANCE_TEX, LLTexUnit::TT_TEXTURE); +	    if (channel > -1) +        { +            shader.bindTexture(LLShaderMgr::TRANSMITTANCE_TEX, gAtmosphere->getTransmittance()); +        } + +        channel = shader.enableTexture(LLShaderMgr::SCATTER_TEX, LLTexUnit::TT_TEXTURE_3D); +	    if (channel > -1) +        { +            shader.bindTexture(LLShaderMgr::SCATTER_TEX, gAtmosphere->getScattering()); +        } + +        channel = shader.enableTexture(LLShaderMgr::SINGLE_MIE_SCATTER_TEX, LLTexUnit::TT_TEXTURE_3D); +	    if (channel > -1) +        { +            shader.bindTexture(LLShaderMgr::SINGLE_MIE_SCATTER_TEX, gAtmosphere->getMieScattering()); +        } + +        channel = shader.enableTexture(LLShaderMgr::ILLUMINANCE_TEX, LLTexUnit::TT_TEXTURE); +	    if (channel > -1) +        { +            shader.bindTexture(LLShaderMgr::ILLUMINANCE_TEX, gAtmosphere->getIlluminance()); +        } +    } +  	shader.uniform4fv(LLShaderMgr::DEFERRED_SHADOW_CLIP, 1, mSunClipPlanes.mV);  	shader.uniform1f(LLShaderMgr::DEFERRED_SUN_WASH, RenderDeferredSunWash);  	shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_NOISE, RenderShadowNoise); @@ -8404,7 +8493,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n  	F32 shadow_bias_error = RenderShadowBiasError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2])/3000.f;      F32 shadow_bias       = RenderShadowBias + shadow_bias_error; -	shader.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredScreen.getWidth(), mDeferredScreen.getHeight()); +	shader.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, deferred_target->getWidth(), deferred_target->getHeight());  	shader.uniform1f(LLShaderMgr::DEFERRED_NEAR_CLIP, LLViewerCamera::getInstance()->getNear()*2.f);  	shader.uniform1f (LLShaderMgr::DEFERRED_SHADOW_OFFSET, RenderShadowOffset); //*shadow_offset_error);  	shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_BIAS, shadow_bias); @@ -8454,21 +8543,24 @@ static LLTrace::BlockTimerStatHandle FTM_PROJECTORS("Projectors");  static LLTrace::BlockTimerStatHandle FTM_POST("Post"); -void LLPipeline::renderDeferredLighting() +void LLPipeline::renderDeferredLighting(LLRenderTarget* screen_target)  {  	if (!sCull)  	{  		return;  	} +    LLRenderTarget* deferred_target       = LLPipeline::sReflectionRender ? &mWaterDeferredScreen : &mDeferredScreen; +    LLRenderTarget* deferred_depth_target = LLPipeline::sReflectionRender ? &mWaterDeferredDepth  : &mDeferredDepth; +    LLRenderTarget* deferred_light_target = LLPipeline::sReflectionRender ? &mWaterDeferredLight  : &mDeferredLight; +  	{  		LL_RECORD_BLOCK_TIME(FTM_RENDER_DEFERRED); -  		LLViewerCamera* camera = LLViewerCamera::getInstance();  		{  			LLGLDepthTest depth(GL_TRUE); -			mDeferredDepth.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), -							0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);	 +			deferred_depth_target->copyContents(*deferred_target, 0, 0, deferred_target->getWidth(), deferred_target->getHeight(), +							0, 0, deferred_depth_target->getWidth(), deferred_depth_target->getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);	  		}  		LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); @@ -8535,13 +8627,13 @@ void LLPipeline::renderDeferredLighting()  		if (RenderDeferredSSAO || RenderShadowDetail > 0)  		{ -			mDeferredLight.bindTarget(); +			deferred_light_target->bindTarget();  			{ //paint shadow/SSAO light map (direct lighting lightmap)  				LL_RECORD_BLOCK_TIME(FTM_SUN_SHADOW); -				bindDeferredShader(gDeferredSunProgram, 0); +				bindDeferredShader(gDeferredSunProgram, deferred_light_target);  				mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);  				glClearColor(1,1,1,1); -				mDeferredLight.clear(GL_COLOR_BUFFER_BIT); +				deferred_light_target->clear(GL_COLOR_BUFFER_BIT);  				glClearColor(0,0,0,0);  				glh::matrix4f inv_trans = get_current_modelview().inverse().transpose(); @@ -8564,7 +8656,7 @@ void LLPipeline::renderDeferredLighting()  				}  				gDeferredSunProgram.uniform3fv(sOffset, slice, offset); -				gDeferredSunProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredLight.getWidth(), mDeferredLight.getHeight()); +				gDeferredSunProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, deferred_light_target->getWidth(), deferred_light_target->getHeight());  				{  					LLGLDisable blend(GL_BLEND); @@ -8576,16 +8668,16 @@ void LLPipeline::renderDeferredLighting()  				unbindDeferredShader(gDeferredSunProgram);  			} -			mDeferredLight.flush(); +			deferred_light_target->flush();  		}  		if (RenderDeferredSSAO)  		{ //soften direct lighting lightmap  			LL_RECORD_BLOCK_TIME(FTM_SOFTEN_SHADOW);  			//blur lightmap -			mScreen.bindTarget(); +			screen_target->bindTarget();  			glClearColor(1,1,1,1); -			mScreen.clear(GL_COLOR_BUFFER_BIT); +			screen_target->clear(GL_COLOR_BUFFER_BIT);  			glClearColor(0,0,0,0);  			bindDeferredShader(gDeferredBlurLightProgram); @@ -8621,12 +8713,13 @@ void LLPipeline::renderDeferredLighting()  				stop_glerror();  			} -			mScreen.flush(); +			screen_target->flush();  			unbindDeferredShader(gDeferredBlurLightProgram); -			bindDeferredShader(gDeferredBlurLightProgram, 1); +			bindDeferredShader(gDeferredBlurLightProgram, screen_target); +  			mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); -			mDeferredLight.bindTarget(); +			deferred_light_target->bindTarget();  			gDeferredBlurLightProgram.uniform2f(sDelta, 0.f, 1.f); @@ -8637,7 +8730,7 @@ void LLPipeline::renderDeferredLighting()  				mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);  				stop_glerror();  			} -			mDeferredLight.flush(); +			deferred_light_target->flush();  			unbindDeferredShader(gDeferredBlurLightProgram);  		} @@ -8649,19 +8742,42 @@ void LLPipeline::renderDeferredLighting()  		gGL.popMatrix();  		stop_glerror(); -		mScreen.bindTarget(); +		screen_target->bindTarget();  		// clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky  		glClearColor(0,0,0,0); -		mScreen.clear(GL_COLOR_BUFFER_BIT); +		screen_target->clear(GL_COLOR_BUFFER_BIT);  		if (RenderDeferredAtmospheric) -		{ //apply sunlight contribution  +		{ //apply sunlight contribution +            LLGLSLShader& soften_shader = LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram; +  			LL_RECORD_BLOCK_TIME(FTM_ATMOSPHERICS); -			bindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram);	 +			bindDeferredShader(soften_shader);	  			{  				LLGLDepthTest depth(GL_FALSE);  				LLGLDisable blend(GL_BLEND);  				LLGLDisable test(GL_ALPHA_TEST); +                 +                S32 l1r_channel = soften_shader.enableTexture(LLShaderMgr::SH_INPUT_L1R, mSkySH.getUsage()); +	            if (l1r_channel > -1) +	            { +		            mSkySH.bindTexture(0,l1r_channel); +		            gGL.getTexUnit(l1r_channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); +	            } +		 +                S32 l1b_channel = soften_shader.enableTexture(LLShaderMgr::SH_INPUT_L1G, mSkySH.getUsage()); +	            if (l1b_channel > -1) +	            { +		            mSkySH.bindTexture(1,l1b_channel); +		            gGL.getTexUnit(l1b_channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); +	            } + +                S32 l1g_channel = soften_shader.enableTexture(LLShaderMgr::SH_INPUT_L1B, mSkySH.getUsage()); +	            if (l1g_channel > -1) +	            { +		            mSkySH.bindTexture(2,l1g_channel); +		            gGL.getTexUnit(l1g_channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); +	            }  				//full screen blit  				gGL.pushMatrix(); @@ -8747,8 +8863,7 @@ void LLPipeline::renderDeferredLighting()  					}  					const LLViewerObject *vobj = drawablep->getVObj(); -					if(vobj && vobj->getAvatar() -						&& (vobj->getAvatar()->isTooComplex() || vobj->getAvatar()->isInMuteList())) +					if(vobj && vobj->getAvatar() && vobj->getAvatar()->isInMuteList())  					{  						continue;  					} @@ -8912,17 +9027,17 @@ void LLPipeline::renderDeferredLighting()  					count++;  					if (count == max_count || fullscreen_lights.empty())  					{ -						U32 idx = count-1; -						bindDeferredShader(gDeferredMultiLightProgram[idx]); -						gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count); -						gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light); -						gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col); -						gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z); -						far_z = 0.f; -						count = 0;  -      mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); -						mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); -						unbindDeferredShader(gDeferredMultiLightProgram[idx]); +                        U32 idx = count-1; +                        bindDeferredShader(gDeferredMultiLightProgram[idx]); +                        gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count); +                        gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light); +                        gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col); +                        gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z); +                        far_z = 0.f; +                        count = 0;  +                        mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); +                        mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); +                        unbindDeferredShader(gDeferredMultiLightProgram[idx]);  					}  				} @@ -8975,7 +9090,7 @@ void LLPipeline::renderDeferredLighting()  		gGL.setColorMask(true, true);  	} -	mScreen.flush(); +	screen_target->flush();  	//gamma correct lighting  	gGL.matrixMode(LLRender::MM_PROJECTION); @@ -8989,22 +9104,22 @@ void LLPipeline::renderDeferredLighting()  		LLGLDepthTest depth(GL_FALSE, GL_FALSE);  		LLVector2 tc1(0,0); -		LLVector2 tc2((F32) mScreen.getWidth()*2, -				  (F32) mScreen.getHeight()*2); +		LLVector2 tc2((F32) screen_target->getWidth()*2, +				  (F32) screen_target->getHeight()*2); -		mScreen.bindTarget(); +		screen_target->bindTarget();  		// Apply gamma correction to the frame here.  		gDeferredPostGammaCorrectProgram.bind();  		//mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);  		S32 channel = 0; -		channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); +		channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, screen_target->getUsage());  		if (channel > -1)  		{ -			mScreen.bindTexture(0,channel); +			screen_target->bindTexture(0,channel);  			gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);  		} -		gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mScreen.getWidth(), mScreen.getHeight()); +		gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, screen_target->getWidth(), screen_target->getHeight());  		F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma"); @@ -9022,9 +9137,9 @@ void LLPipeline::renderDeferredLighting()  		gGL.end(); -		gGL.getTexUnit(channel)->unbind(mScreen.getUsage()); +		gGL.getTexUnit(channel)->unbind(screen_target->getUsage());  		gDeferredPostGammaCorrectProgram.unbind(); -		mScreen.flush(); +		screen_target->flush();  	}  	gGL.matrixMode(LLRender::MM_PROJECTION); @@ -9032,7 +9147,7 @@ void LLPipeline::renderDeferredLighting()  	gGL.matrixMode(LLRender::MM_MODELVIEW);  	gGL.popMatrix();	 -	mScreen.bindTarget(); +	screen_target->bindTarget();  	{ //render non-deferred geometry (alpha, fullbright, glow)  		LLGLDisable blend(GL_BLEND); @@ -9080,565 +9195,13 @@ void LLPipeline::renderDeferredLighting()  			// Render debugging beacons.  			gObjectList.renderObjectBeacons();  			gObjectList.resetObjectBeacons(); -			gSky.addSunMoonBeacons();  		}  	} -	mScreen.flush(); +	screen_target->flush();  } -void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target) -{ -	if (!sCull) -	{ -		return; -	} - -	{ -		LL_RECORD_BLOCK_TIME(FTM_RENDER_DEFERRED); - -		LLViewerCamera* camera = LLViewerCamera::getInstance(); - -		{ -			LLGLDepthTest depth(GL_TRUE); -			mDeferredDepth.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), -							0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);	 -		} - -		LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); - -		if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) -		{ -			gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); -		} - -		//ati doesn't seem to love actually using the stencil buffer on FBO's -		LLGLDisable stencil(GL_STENCIL_TEST); -		//glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF); -		//glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - -		gGL.setColorMask(true, true); -		 -		//draw a cube around every light -		LLVertexBuffer::unbind(); - -		LLGLEnable cull(GL_CULL_FACE); -		LLGLEnable blend(GL_BLEND); - -		glh::matrix4f mat = copy_matrix(gGLModelView); - -		LLStrider<LLVector3> vert;  -		mDeferredVB->getVertexStrider(vert); -		 -		vert[0].set(-1,1,0); -		vert[1].set(-1,-3,0); -		vert[2].set(3,1,0); -		 -        const LLEnvironment& environment = LLEnvironment::instance(); - -        bool sun_up  = environment.getIsSunUp(); -        bool moon_up = environment.getIsMoonUp(); - -		{ -			setupHWLights(NULL); //to set mSun/MoonDir; -			glh::vec4f tc(mSunDir.mV); -			mat.mult_matrix_vec(tc); - -            glh::vec4f tc_moon(mMoonDir.mV); -            mTransformedMoonDir.set(tc_moon.v); -            mTransformedMoonDir.normalize(); - -            bool sun_is_primary = sun_up || !moon_up;             -            if (sun_is_primary) -            { -                mTransformedSunDir.set(tc.v); -                mTransformedSunDir.normalize(); -            } -            else -            { -                mTransformedSunDir.set(tc_moon.v); -                mTransformedSunDir.normalize(); -            } -		} - -		gGL.pushMatrix(); -		gGL.loadIdentity(); -		gGL.matrixMode(LLRender::MM_PROJECTION); -		gGL.pushMatrix(); -		gGL.loadIdentity(); - -		if (RenderDeferredSSAO || RenderShadowDetail > 0) -		{ -			mDeferredLight.bindTarget(); -			{ //paint shadow/SSAO light map (direct lighting lightmap) -				LL_RECORD_BLOCK_TIME(FTM_SUN_SHADOW); -				bindDeferredShader(gDeferredSunProgram); -				mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); -				glClearColor(1,1,1,1); -				mDeferredLight.clear(GL_COLOR_BUFFER_BIT); -				glClearColor(0,0,0,0); - -				glh::matrix4f inv_trans = get_current_modelview().inverse().transpose(); - -				const U32 slice = 32; -				F32 offset[slice*3]; -				for (U32 i = 0; i < 4; i++) -				{ -					for (U32 j = 0; j < 8; j++) -					{ -						glh::vec3f v; -						v.set_value(sinf(6.284f/8*j), cosf(6.284f/8*j), -(F32) i); -						v.normalize(); -						inv_trans.mult_matrix_vec(v); -						v.normalize(); -						offset[(i*8+j)*3+0] = v.v[0]; -						offset[(i*8+j)*3+1] = v.v[2]; -						offset[(i*8+j)*3+2] = v.v[1]; -					} -				} - -// pretty sure this doesn't work as expected since the shaders using 'shadow_offset' all declare it as a single uniform float, no array or vec -				gDeferredSunProgram.uniform3fv(LLShaderMgr::DEFERRED_SHADOW_OFFSET, slice, offset); -				gDeferredSunProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredLight.getWidth(), mDeferredLight.getHeight()); -				 -				{ -					LLGLDisable blend(GL_BLEND); -					LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); -					stop_glerror(); -					mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); -					stop_glerror(); -				} -				 -				unbindDeferredShader(gDeferredSunProgram); -			} -			mDeferredLight.flush(); -		} -				 -		stop_glerror(); -		gGL.popMatrix(); -		stop_glerror(); -		gGL.matrixMode(LLRender::MM_MODELVIEW); -		stop_glerror(); -		gGL.popMatrix(); -		stop_glerror(); - -		target->bindTarget(); - -		//clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky -		glClearColor(0,0,0,0); -		target->clear(GL_COLOR_BUFFER_BIT); -		 -		if (RenderDeferredAtmospheric) -		{ //apply sunlight contribution  -			LL_RECORD_BLOCK_TIME(FTM_ATMOSPHERICS); -			bindDeferredShader(gDeferredSoftenProgram);	 -			{ -				LLGLDepthTest depth(GL_FALSE); -				LLGLDisable blend(GL_BLEND); -				LLGLDisable test(GL_ALPHA_TEST); - -				//full screen blit -				gGL.pushMatrix(); -				gGL.loadIdentity(); -				gGL.matrixMode(LLRender::MM_PROJECTION); -				gGL.pushMatrix(); -				gGL.loadIdentity(); - -				mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); -				 -				mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); - -				gGL.popMatrix(); -				gGL.matrixMode(LLRender::MM_MODELVIEW); -				gGL.popMatrix(); -			} - -			unbindDeferredShader(gDeferredSoftenProgram); -		} - -		{ //render non-deferred geometry (fullbright, alpha, etc) -			LLGLDisable blend(GL_BLEND); -			LLGLDisable stencil(GL_STENCIL_TEST); -			gGL.setSceneBlendType(LLRender::BT_ALPHA); - -			gPipeline.pushRenderTypeMask(); -			 -			gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, -										LLPipeline::RENDER_TYPE_CLOUDS, -										LLPipeline::RENDER_TYPE_WL_SKY, -										LLPipeline::END_RENDER_TYPES); -								 -			 -			renderGeomPostDeferred(*LLViewerCamera::getInstance(), false); -			gPipeline.popRenderTypeMask(); -		} - -		bool render_local = RenderLocalLights; -				 -		if (render_local) -		{ -			gGL.setSceneBlendType(LLRender::BT_ADD); -			std::list<LLVector4> fullscreen_lights; -			LLDrawable::drawable_list_t spot_lights; -			LLDrawable::drawable_list_t fullscreen_spot_lights; - -			for (U32 i = 0; i < 2; i++) -			{ -				mTargetShadowSpotLight[i] = NULL; -			} - -			std::list<LLVector4> light_colors; - -			LLVertexBuffer::unbind(); - -			{ -				bindDeferredShader(gDeferredLightProgram); -				 -				if (mCubeVB.isNull()) -				{ -					mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB); -				} - -				mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); -				 -				LLGLDepthTest depth(GL_TRUE, GL_FALSE); -				for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter) -				{ -					LLDrawable* drawablep = *iter; -					 -					LLVOVolume* volume = drawablep->getVOVolume(); -					if (!volume) -					{ -						continue; -					} - -					if (volume->isAttachment()) -					{ -						if (!sRenderAttachedLights) -						{ -							continue; -						} -					} - - -					LLVector4a center; -					center.load3(drawablep->getPositionAgent().mV); -					const F32* c = center.getF32ptr(); -					F32 s = volume->getLightRadius()*1.5f; - -					LLColor3 col = volume->getLightColor(); -					 -					if (col.magVecSquared() < 0.001f) -					{ -						continue; -					} - -					if (s <= 0.001f) -					{ -						continue; -					} - -					LLVector4a sa; -					sa.splat(s); -					if (camera->AABBInFrustumNoFarClip(center, sa) == 0) -					{ -						continue; -					} - -					sVisibleLightCount++; -										 -					if (camera->getOrigin().mV[0] > c[0] + s + 0.2f || -						camera->getOrigin().mV[0] < c[0] - s - 0.2f || -						camera->getOrigin().mV[1] > c[1] + s + 0.2f || -						camera->getOrigin().mV[1] < c[1] - s - 0.2f || -						camera->getOrigin().mV[2] > c[2] + s + 0.2f || -						camera->getOrigin().mV[2] < c[2] - s - 0.2f) -					{ //draw box if camera is outside box -						if (render_local) -						{ -							if (volume->isLightSpotlight()) -							{ -								drawablep->getVOVolume()->updateSpotLightPriority(); -								spot_lights.push_back(drawablep); -								continue; -							} -							 -							/*col.mV[0] = powf(col.mV[0], 2.2f); -							col.mV[1] = powf(col.mV[1], 2.2f); -							col.mV[2] = powf(col.mV[2], 2.2f);*/ -							 -							LL_RECORD_BLOCK_TIME(FTM_LOCAL_LIGHTS); -							gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c); -							gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s); -							gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); -							gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f); -							gGL.syncMatrices(); -							 -							mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center)); -							stop_glerror(); -						} -					} -					else -					{	 -						if (volume->isLightSpotlight()) -						{ -							drawablep->getVOVolume()->updateSpotLightPriority(); -							fullscreen_spot_lights.push_back(drawablep); -							continue; -						} - -						glh::vec3f tc(c); -						mat.mult_matrix_vec(tc); -					 -						fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s)); -						light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f)); -					} -				} -				unbindDeferredShader(gDeferredLightProgram); -			} - -			if (!spot_lights.empty()) -			{ -				LLGLDepthTest depth(GL_TRUE, GL_FALSE); -				bindDeferredShader(gDeferredSpotLightProgram); - -				mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - -				gDeferredSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); - -				for (LLDrawable::drawable_list_t::iterator iter = spot_lights.begin(); iter != spot_lights.end(); ++iter) -				{ -					LL_RECORD_BLOCK_TIME(FTM_PROJECTORS); -					LLDrawable* drawablep = *iter; - -					LLVOVolume* volume = drawablep->getVOVolume(); - -					LLVector4a center; -					center.load3(drawablep->getPositionAgent().mV); -					const F32* c = center.getF32ptr(); -					F32 s = volume->getLightRadius()*1.5f; - -					sVisibleLightCount++; - -					setupSpotLight(gDeferredSpotLightProgram, drawablep); -					 -					LLColor3 col = volume->getLightColor(); -					/*col.mV[0] = powf(col.mV[0], 2.2f); -					col.mV[1] = powf(col.mV[1], 2.2f); -					col.mV[2] = powf(col.mV[2], 2.2f);*/ -					 -					gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c); -					gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s); -					gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); -					gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f); -					gGL.syncMatrices(); -										 -					mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center)); -				} -				gDeferredSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION); -				unbindDeferredShader(gDeferredSpotLightProgram); -			} - -			//reset mDeferredVB to fullscreen triangle -			mDeferredVB->getVertexStrider(vert); -			vert[0].set(-1,1,0); -			vert[1].set(-1,-3,0); -			vert[2].set(3,1,0); - -			{ -				LLGLDepthTest depth(GL_FALSE); - -				//full screen blit -				gGL.pushMatrix(); -				gGL.loadIdentity(); -				gGL.matrixMode(LLRender::MM_PROJECTION); -				gGL.pushMatrix(); -				gGL.loadIdentity(); - -				U32 count = 0; - -				const U32 max_count = LL_DEFERRED_MULTI_LIGHT_COUNT; -				LLVector4 light[max_count]; -				LLVector4 col[max_count]; - -				F32 far_z = 0.f; - -				while (!fullscreen_lights.empty()) -				{ -					LL_RECORD_BLOCK_TIME(FTM_FULLSCREEN_LIGHTS); -					light[count] = fullscreen_lights.front(); -					fullscreen_lights.pop_front(); -					col[count] = light_colors.front(); -					light_colors.pop_front(); -					 -					/*col[count].mV[0] = powf(col[count].mV[0], 2.2f); -					col[count].mV[1] = powf(col[count].mV[1], 2.2f); -					col[count].mV[2] = powf(col[count].mV[2], 2.2f);*/ -					 -					far_z = llmin(light[count].mV[2]-light[count].mV[3], far_z); -					//col[count] = pow4fsrgb(col[count], 2.2f); -					count++; -					if (count == max_count || fullscreen_lights.empty()) -					{ -						U32 idx = count-1; -						bindDeferredShader(gDeferredMultiLightProgram[idx]); -						gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count); -						gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light); -						gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col); -						gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z); -						far_z = 0.f; -						count = 0;  -						mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); -						mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); -					} -				} -				 -				unbindDeferredShader(gDeferredMultiLightProgram[0]); - -				bindDeferredShader(gDeferredMultiSpotLightProgram); - -				gDeferredMultiSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); - -				mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - -				for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter) -				{ -					LL_RECORD_BLOCK_TIME(FTM_PROJECTORS); -					LLDrawable* drawablep = *iter; -					 -					LLVOVolume* volume = drawablep->getVOVolume(); - -					LLVector3 center = drawablep->getPositionAgent(); -					F32* c = center.mV; -					F32 s = volume->getLightRadius()*1.5f; - -					sVisibleLightCount++; - -					glh::vec3f tc(c); -					mat.mult_matrix_vec(tc); -					 -					setupSpotLight(gDeferredMultiSpotLightProgram, drawablep); - -					LLColor3 col = volume->getLightColor(); -					 -					/*col.mV[0] = powf(col.mV[0], 2.2f); -					col.mV[1] = powf(col.mV[1], 2.2f); -					col.mV[2] = powf(col.mV[2], 2.2f);*/ -					 -					gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v); -					gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s); -					gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); -					gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f); -					mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); -				} - -				gDeferredMultiSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION); -				unbindDeferredShader(gDeferredMultiSpotLightProgram); - -				gGL.popMatrix(); -				gGL.matrixMode(LLRender::MM_MODELVIEW); -				gGL.popMatrix(); -			} -		} - -		gGL.setColorMask(true, true); -	} - -	/*target->flush(); - -	//gamma correct lighting -	gGL.matrixMode(LLRender::MM_PROJECTION); -	gGL.pushMatrix(); -	gGL.loadIdentity(); -	gGL.matrixMode(LLRender::MM_MODELVIEW); -	gGL.pushMatrix(); -	gGL.loadIdentity(); - -	{ -		LLGLDepthTest depth(GL_FALSE, GL_FALSE); - -		LLVector2 tc1(0,0); -		LLVector2 tc2((F32) target->getWidth()*2, -				  (F32) target->getHeight()*2); - -		target->bindTarget(); -		// Apply gamma correction to the frame here. -		gDeferredPostGammaCorrectProgram.bind(); -		//mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); -		S32 channel = 0; -		channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, target->getUsage()); -		if (channel > -1) -		{ -			target->bindTexture(0,channel); -			gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); -		} -		 -		gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, target->getWidth(), target->getHeight()); -		 -		F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma"); - -		gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f)); -		 -		gGL.begin(LLRender::TRIANGLE_STRIP); -		gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); -		gGL.vertex2f(-1,-1); -		 -		gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); -		gGL.vertex2f(-1,3); -		 -		gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); -		gGL.vertex2f(3,-1); -		 -		gGL.end(); -		 -		gGL.getTexUnit(channel)->unbind(target->getUsage()); -		gDeferredPostGammaCorrectProgram.unbind(); -		target->flush(); -	} - -	gGL.matrixMode(LLRender::MM_PROJECTION); -	gGL.popMatrix(); -	gGL.matrixMode(LLRender::MM_MODELVIEW); -	gGL.popMatrix();	 - -	target->bindTarget();*/ - -	{ //render non-deferred geometry (alpha, fullbright, glow) -		LLGLDisable blend(GL_BLEND); -		LLGLDisable stencil(GL_STENCIL_TEST); - -		pushRenderTypeMask(); -		andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA, -						 LLPipeline::RENDER_TYPE_FULLBRIGHT, -						 LLPipeline::RENDER_TYPE_VOLUME, -						 LLPipeline::RENDER_TYPE_GLOW, -						 LLPipeline::RENDER_TYPE_BUMP, -						 LLPipeline::RENDER_TYPE_PASS_SIMPLE, -						 LLPipeline::RENDER_TYPE_PASS_ALPHA, -						 LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK, -						 LLPipeline::RENDER_TYPE_PASS_BUMP, -						 LLPipeline::RENDER_TYPE_PASS_POST_BUMP, -						 LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT, -						 LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK, -						 LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY, -						 LLPipeline::RENDER_TYPE_PASS_GLOW, -						 LLPipeline::RENDER_TYPE_PASS_GRASS, -						 LLPipeline::RENDER_TYPE_PASS_SHINY, -						 LLPipeline::RENDER_TYPE_PASS_INVISIBLE, -						 LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY, -						 LLPipeline::RENDER_TYPE_AVATAR, -						 LLPipeline::RENDER_TYPE_ALPHA_MASK, -						 LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK, -						 END_RENDER_TYPES); -		 -		renderGeomPostDeferred(*LLViewerCamera::getInstance()); -		popRenderTypeMask(); -	} - -	//target->flush();				 -} -  void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)  {  	//construct frustum @@ -9780,12 +9343,16 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)  void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)  { +    LLRenderTarget* deferred_target       = LLPipeline::sReflectionRender ? &mWaterDeferredScreen : &mDeferredScreen; +    LLRenderTarget* deferred_depth_target = LLPipeline::sReflectionRender ? &mWaterDeferredDepth  : &mDeferredDepth; +    LLRenderTarget* deferred_light_target = LLPipeline::sReflectionRender ? &mWaterDeferredLight : &mDeferredLight; +  	stop_glerror(); -	shader.disableTexture(LLShaderMgr::DEFERRED_NORMAL, mDeferredScreen.getUsage()); -	shader.disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredScreen.getUsage()); -	shader.disableTexture(LLShaderMgr::DEFERRED_SPECULAR, mDeferredScreen.getUsage()); -	shader.disableTexture(LLShaderMgr::DEFERRED_DEPTH, mDeferredScreen.getUsage()); -	shader.disableTexture(LLShaderMgr::DEFERRED_LIGHT, mDeferredLight.getUsage()); +	shader.disableTexture(LLShaderMgr::DEFERRED_NORMAL, deferred_target->getUsage()); +	shader.disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, deferred_target->getUsage()); +	shader.disableTexture(LLShaderMgr::DEFERRED_SPECULAR, deferred_target->getUsage()); +	shader.disableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_depth_target->getUsage()); +	shader.disableTexture(LLShaderMgr::DEFERRED_LIGHT, deferred_light_target->getUsage());  	shader.disableTexture(LLShaderMgr::DIFFUSE_MAP);  	shader.disableTexture(LLShaderMgr::DEFERRED_BLOOM); @@ -9851,8 +9418,9 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  		LLCamera camera = camera_in;  		camera.setFar(camera.getFar()*0.87654321f); -		LLPipeline::sReflectionRender = true; -		 + +		LLPipeline::sReflectionRender = true;		 +  		gPipeline.pushRenderTypeMask();  		glh::matrix4f projection = get_current_projection(); @@ -9874,7 +9442,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)          camera.setOriginAndLookAt(reflect_origin, LLVector3::z_axis, reflect_interest_point);  		//plane params -		LLVector3 pnorm;       +		LLVector3 pnorm;  		S32 water_clip = 0;  		if (!LLViewerCamera::getInstance()->cameraUnderWater())  		{ //camera is above water, clip plane points up @@ -9889,20 +9457,13 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  			water_clip = -1;  		} -		bool materials_in_water = false; - -#if MATERIALS_IN_REFLECTIONS -		materials_in_water = gSavedSettings.getS32("RenderWaterMaterials"); -#endif -  		if (!LLViewerCamera::getInstance()->cameraUnderWater())  		{	//generate planar reflection map - -            LLPipeline::sRenderingWaterReflection = true; -  			//disable occlusion culling for reflection map for now  			S32 occlusion = LLPipeline::sUseOcclusion; +  			LLPipeline::sUseOcclusion = 0; +  			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);  			glClearColor(0,0,0,0); @@ -9932,6 +9493,8 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)              // convert from CFR to OGL coord sys...              mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat; +            mReflectionModelView = mat; +  			set_current_modelview(mat);  			gGL.loadMatrix(mat.m); @@ -9939,8 +9502,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  			glCullFace(GL_FRONT); -			static LLCullResult ref_result; -  			if (LLDrawPoolWater::sNeedsReflectionUpdate)  			{  				//initial sky pass (no user clip plane) @@ -9951,31 +9512,32 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  						LLPipeline::RENDER_TYPE_CLOUDS,  						LLPipeline::END_RENDER_TYPES); -					static LLCullResult result; -					updateCull(camera, result); -					stateSort(camera, result); - -					if (LLPipeline::sRenderDeferred && materials_in_water) -					{ -						mWaterRef.flush(); +                    gGL.setColorMask(true, true); +					glClearColor(0,0,0,0); -						gPipeline.grabReferences(result); -						gPipeline.mDeferredScreen.bindTarget(); -						gGL.setColorMask(true, true);						 -						glClearColor(0,0,0,0); -						gPipeline.mDeferredScreen.clear(); +					static LLCullResult sky_and_clouds; +					updateCull(camera, sky_and_clouds); +					stateSort(camera, sky_and_clouds); +                    gPipeline.grabReferences(sky_and_clouds); -						renderGeomDeferred(camera);						 +                    if (LLPipeline::sRenderDeferred) +					{ +                        gPipeline.mWaterDeferredDepth.bindTarget(); +                        gPipeline.mWaterDeferredDepth.clear(); +					    gPipeline.mWaterDeferredScreen.bindTarget(); +					    gPipeline.mWaterDeferredScreen.clear(); +						renderGeomDeferred(camera);  					}  					else  					{ -					renderGeom(camera, TRUE); +					    renderGeom(camera, TRUE);  					}					  					gPipeline.popRenderTypeMask();  				}  				gGL.setColorMask(true, false); +  				gPipeline.pushRenderTypeMask();  				clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER, @@ -10001,22 +9563,28 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  						}  					} -					LLGLUserClipPlane clip_plane(plane, mat, projection); -					LLGLDisable cull(GL_CULL_FACE); -					updateCull(camera, ref_result, water_clip, &plane); -					stateSort(camera, ref_result); +					  				}	  				if (LLDrawPoolWater::sNeedsDistortionUpdate)  				{ -					if (RenderReflectionDetail > 0) +					if (detail > 0)  					{ -						gPipeline.grabReferences(ref_result); -						LLGLUserClipPlane clip_plane(plane, mat, projection); +                        static LLCullResult reflected_objects; +                        LLGLDisable cull(GL_CULL_FACE); +					    updateCull(camera, reflected_objects); +					    stateSort(camera, reflected_objects); -						if (LLPipeline::sRenderDeferred && materials_in_water) +						gPipeline.grabReferences(reflected_objects); + +						LLGLUserClipPlane clip_plane(plane, mat, projection); +						if (LLPipeline::sRenderDeferred)  						{							  							renderGeomDeferred(camera); +                            gPipeline.mWaterDeferredScreen.flush(); +                            gPipeline.mWaterDeferredDepth.flush(); +                            mWaterRef.copyContents(gPipeline.mWaterDeferredScreen, 0, 0, gPipeline.mWaterDeferredScreen.getWidth(), gPipeline.mWaterDeferredScreen.getHeight(), +							    0, 0, gPipeline.mWaterRef.getWidth(), gPipeline.mWaterRef.getHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);	  						}  						else  						{ @@ -10025,17 +9593,9 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  				    }	  				}	 -				if (LLPipeline::sRenderDeferred && materials_in_water) -				{ -					gPipeline.mDeferredScreen.flush(); -					renderDeferredLightingToRT(&mWaterRef); -				} -  				gPipeline.popRenderTypeMask();  			}	 -            LLPipeline::sRenderingWaterReflection = false; -  			glCullFace(GL_BACK);              gGL.matrixMode(LLRender::MM_MODELVIEW);  			gGL.popMatrix(); @@ -10095,13 +9655,13 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  				gGL.setColorMask(true, false); -				if (LLPipeline::sRenderDeferred && materials_in_water) +				if (LLPipeline::sRenderDeferred)  				{										  					mWaterDis.flush(); -					gPipeline.mDeferredScreen.bindTarget(); +					gPipeline.mWaterDeferredScreen.bindTarget();  					gGL.setColorMask(true, true);  					glClearColor(0,0,0,0); -					gPipeline.mDeferredScreen.clear(); +					gPipeline.mWaterDeferredScreen.clear();  					gPipeline.grabReferences(result);  					renderGeomDeferred(camera);					  				} @@ -10122,19 +9682,20 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  					}  				} -				if (LLPipeline::sRenderDeferred && materials_in_water) +				if (LLPipeline::sRenderDeferred)  				{ -					gPipeline.mDeferredScreen.flush(); -					renderDeferredLightingToRT(&mWaterDis); +					gPipeline.mWaterDeferredScreen.flush(); +                    gPipeline.mWaterDeferredDepth.flush(); +                    mWaterDis.copyContents(gPipeline.mWaterDeferredScreen, 0, 0, gPipeline.mWaterDeferredScreen.getWidth(), gPipeline.mWaterDeferredScreen.getHeight(), +							0, 0, gPipeline.mWaterDeferredDepth.getWidth(), gPipeline.mWaterDeferredDepth.getHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);	  				}  			} -			mWaterDis.flush(); -			LLPipeline::sUnderWaterRender = false; -			 +			mWaterDis.flush();			  		}  		last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate; +        LLPipeline::sUnderWaterRender = false;  		LLPipeline::sReflectionRender = false;  		if (!LLRenderTarget::sUseFBO) @@ -10303,8 +9864,15 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera  		}  		gGL.diffuseColor4f(1,1,1,1); -		gGL.setColorMask(false, false); -	 + +        S32 shadow_detail = gSavedSettings.getS32("RenderShadowDetail"); + +        // if not using VSM, disable color writes +        if (shadow_detail <= 2) +        { +		    gGL.setColorMask(false, false); +	    } +  		LL_RECORD_BLOCK_TIME(FTM_SHADOW_SIMPLE);  		gGL.getTexUnit(0)->disable(); @@ -10640,6 +10208,183 @@ LLRenderTarget* LLPipeline::getShadowTarget(U32 i)      return &mShadow[i];  } +static LLTrace::BlockTimerStatHandle FTM_GEN_SKY_INDIRECT("Gen Sky Indirect"); + +void LLPipeline::generateSkyIndirect() +{ +	if (!sRenderDeferred || !gSavedSettings.getBOOL("RenderUseAdvancedAtmospherics")) +	{ +		return; +	} + +	LL_RECORD_BLOCK_TIME(FTM_GEN_SKY_INDIRECT); + +	gGL.setColorMask(true, true); + +	LLVertexBuffer::unbind(); + +	gGL.pushMatrix(); +	gGL.loadIdentity(); +	gGL.matrixMode(LLRender::MM_PROJECTION); +	gGL.pushMatrix(); +	gGL.loadIdentity(); + +    mSkySH.bindTarget(); + +	bindDeferredShader(gDeferredGenSkyShProgram, &mSkySH); + +	gDeferredGenSkyShProgram.bind(); + +    llassert(gAtmosphere); + +    int channel = -1; + +    if (gAtmosphere) +    { +        // bind precomputed textures necessary for calculating sun and sky luminance +        channel = gDeferredGenSkyShProgram.enableTexture(LLShaderMgr::TRANSMITTANCE_TEX, LLTexUnit::TT_TEXTURE); +	    if (channel > -1) +        { +            gDeferredGenSkyShProgram.bindTexture(LLShaderMgr::TRANSMITTANCE_TEX, gAtmosphere->getTransmittance()); +        } + +        channel = gDeferredGenSkyShProgram.enableTexture(LLShaderMgr::SCATTER_TEX, LLTexUnit::TT_TEXTURE_3D); +	    if (channel > -1) +        { +            gDeferredGenSkyShProgram.bindTexture(LLShaderMgr::SCATTER_TEX, gAtmosphere->getScattering()); +        } + +        channel = gDeferredGenSkyShProgram.enableTexture(LLShaderMgr::SINGLE_MIE_SCATTER_TEX, LLTexUnit::TT_TEXTURE_3D); +	    if (channel > -1) +        { +            gDeferredGenSkyShProgram.bindTexture(LLShaderMgr::SINGLE_MIE_SCATTER_TEX, gAtmosphere->getMieScattering()); +        } + +        channel = gDeferredGenSkyShProgram.enableTexture(LLShaderMgr::ILLUMINANCE_TEX, LLTexUnit::TT_TEXTURE); +	    if (channel > -1) +        { +            gDeferredGenSkyShProgram.bindTexture(LLShaderMgr::ILLUMINANCE_TEX, gAtmosphere->getIlluminance()); +        } +    } + +	gDeferredGenSkyShProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mSkySH.getWidth(), mSkySH.getHeight()); + +    LLStrider<LLVector3>	vertices; +	LLStrider<LLVector2>	texCoords; +	LLStrider<U16>			indices; + +    if (!mDeferredVB->allocateBuffer(4, 6, TRUE)) +	{ +		LL_WARNS() << "Failed to allocate Vertex Buffer on full screen sky update" << LL_ENDL; +	} + +	BOOL success = mDeferredVB->getVertexStrider(vertices) +			    && mDeferredVB->getTexCoord0Strider(texCoords) +			    && mDeferredVB->getIndexStrider(indices); + +	if(!success)  +	{ +		LL_ERRS() << "Failed updating WindLight fullscreen sky geometry." << LL_ENDL; +	} + +    *vertices++ = LLVector3(-1.0f, -1.0f, 0.0f); +    *vertices++ = LLVector3( 1.0f, -1.0f, 0.0f); +    *vertices++ = LLVector3(-1.0f,  1.0f, 0.0f); +    *vertices++ = LLVector3( 1.0f,  1.0f, 0.0f); + +	*texCoords++ = LLVector2(0.0f, 0.0f); +    *texCoords++ = LLVector2(1.0f, 0.0f); +    *texCoords++ = LLVector2(0.0f, 1.0f); +    *texCoords++ = LLVector2(1.0f, 1.0f); + +	*indices++ = 0; +	*indices++ = 1; +	*indices++ = 2; +    *indices++ = 1; +	*indices++ = 3; +	*indices++ = 2; + +    mDeferredVB->flush(); + +	glClearColor(0,0,0,0); +	mSkySH.clear(GL_COLOR_BUFFER_BIT); + +    LLGLDisable blend(GL_BLEND); +    LLGLDepthTest depth(GL_FALSE, GL_FALSE, GL_ALWAYS); + +    mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); +	mDeferredVB->drawRange(LLRender::TRIANGLES, 0, mDeferredVB->getNumVerts() - 1, mDeferredVB->getNumIndices(), 0); +	stop_glerror(); + +	gDeferredGenSkyShProgram.disableTexture(LLShaderMgr::TRANSMITTANCE_TEX); +	gDeferredGenSkyShProgram.disableTexture(LLShaderMgr::SCATTER_TEX); +    gDeferredGenSkyShProgram.disableTexture(LLShaderMgr::SINGLE_MIE_SCATTER_TEX); +    gDeferredGenSkyShProgram.disableTexture(LLShaderMgr::ILLUMINANCE_TEX); +    gDeferredGenSkyShProgram.uniform3fv(LLShaderMgr::DEFERRED_SUN_DIR, 1, mTransformedSunDir.mV); + +	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +	gGL.getTexUnit(0)->activate(); +	gDeferredGenSkyShProgram.unbind(); + +    mSkySH.flush(); + +#if GATHER_SKY_SH +	gDeferredGatherSkyShProgram.bind(); + +    S32 res = mSkySH[0].getWidth(); +    S32 ping = 0; + +    while (res > 1) +    { +        S32 pong = 1 - ping; +	    S32 l1r_channel = gDeferredGatherSkyShProgram.enableTexture(LLShaderMgr::SH_INPUT_L1R, mSkySH[ping].getUsage()); +	    if (l1r_channel > -1) +	    { +		    mSkySH[ping].bindTexture(0,l1r_channel); +		    gGL.getTexUnit(l1r_channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); +	    } +		 +        S32 l1b_channel = gDeferredGatherSkyShProgram.enableTexture(LLShaderMgr::SH_INPUT_L1G, mSkySH[ping].getUsage()); +	    if (l1b_channel > -1) +	    { +		    mSkySH[ping].bindTexture(1,l1b_channel); +		    gGL.getTexUnit(l1b_channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); +	    } + +        S32 l1g_channel = gDeferredGatherSkyShProgram.enableTexture(LLShaderMgr::SH_INPUT_L1B, mSkySH[ping].getUsage()); +	    if (l1g_channel > -1) +	    { +		    mSkySH[ping].bindTexture(2,l1g_channel); +		    gGL.getTexUnit(l1g_channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); +	    } + +        gDeferredGatherSkyShProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, res >> 1, res >> 1); + +        glViewport(0, 0, res >> 1, res >> 1); + +        mSkySH[pong].bindTarget(); + +        mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); +        mDeferredVB->drawRange(LLRender::TRIANGLES, 0, mDeferredVB->getNumVerts() - 1, mDeferredVB->getNumIndices(), 0); +	    stop_glerror(); +		 +        mSkySH[pong].flush(); + +	    gGL.getTexUnit(l1r_channel)->unbind(mSkySH[ping].getUsage()); +        gGL.getTexUnit(l1b_channel)->unbind(mSkySH[ping].getUsage()); +        gGL.getTexUnit(l1g_channel)->unbind(mSkySH[ping].getUsage()); + +        ping ^= 1; +        res >>= 1; +    } +#endif + +	gGL.matrixMode(LLRender::MM_PROJECTION); +	gGL.popMatrix(); +	gGL.matrixMode(LLRender::MM_MODELVIEW); +	gGL.popMatrix();	 +} +  static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW("Gen Sun Shadow");  void LLPipeline::generateSunShadow(LLCamera& camera) @@ -10654,7 +10399,6 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  	bool skip_avatar_update = false;  	if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson)  	{ -  		skip_avatar_update = true;  	} @@ -10710,7 +10454,13 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  					LLPipeline::RENDER_TYPE_PASS_NORMSPEC_EMISSIVE,  					END_RENDER_TYPES); -	gGL.setColorMask(false, false); +    S32 shadow_detail = gSavedSettings.getS32("RenderShadowDetail"); + +    // if not using VSM, disable color writes +    if (shadow_detail <= 2) +    { +		gGL.setColorMask(false, false); +	}  	//get sun view matrix diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 9977781065..66cae8bf72 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -276,17 +276,17 @@ public:  	void renderGeomDeferred(LLCamera& camera);  	void renderGeomPostDeferred(LLCamera& camera, bool do_occlusion=true);  	void renderGeomShadow(LLCamera& camera); -	void bindDeferredShader(LLGLSLShader& shader, U32 light_index = 0, U32 noise_map = 0xFFFFFFFF); +	void bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target = nullptr);  	void setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep);  	void unbindDeferredShader(LLGLSLShader& shader); -	void renderDeferredLighting(); -	void renderDeferredLightingToRT(LLRenderTarget* target); +	void renderDeferredLighting(LLRenderTarget* light_target);  	void generateWaterReflection(LLCamera& camera);  	void generateSunShadow(LLCamera& camera);      LLRenderTarget* getShadowTarget(U32 i); +    void generateSkyIndirect();  	void generateHighlight(LLCamera& camera);  	void renderHighlight(const LLViewerObject* obj, F32 fade);  	void setHighlightObject(LLDrawable* obj) { mHighlightObject = obj; } @@ -534,7 +534,8 @@ public:  		RENDER_DEBUG_ATTACHMENT_BYTES	=  0x20000000, // not used  		RENDER_DEBUG_TEXEL_DENSITY		=  0x40000000,  		RENDER_DEBUG_TRIANGLE_COUNT		=  0x80000000, -		RENDER_DEBUG_IMPOSTORS			= 0x100000000 +		RENDER_DEBUG_IMPOSTORS			= 0x100000000, +        RENDER_DEBUG_SH                  = 0x200000000,  	};  public: @@ -588,7 +589,6 @@ public:  	static bool				sRenderAttachedLights;  	static bool				sRenderAttachedParticles;  	static bool				sRenderDeferred; -    static bool				sRenderingWaterReflection;  	static bool             sMemAllocationThrottled;  	static S32				sVisibleLightCount;  	static F32				sMinRenderSize; @@ -620,43 +620,41 @@ public:  	//sun shadow map  	LLRenderTarget			mShadow[6];  	LLRenderTarget			mShadowOcclusion[6]; -	LLRenderTarget			mInscatter; -	std::vector<LLVector3>		mShadowFrustPoints[4]; -	LLVector4			mShadowError; -	LLVector4			mShadowFOV; -	LLVector3			mShadowFrustOrigin[4]; -	LLCamera			mShadowCamera[8]; -	LLVector3			mShadowExtents[4][2]; + +	std::vector<LLVector3>  mShadowFrustPoints[4]; +	LLVector4			    mShadowError; +	LLVector4			    mShadowFOV; +	LLVector3			    mShadowFrustOrigin[4]; +	LLCamera			    mShadowCamera[8]; +	LLVector3			    mShadowExtents[4][2];  	glh::matrix4f			mSunShadowMatrix[6];  	glh::matrix4f			mShadowModelview[6];  	glh::matrix4f			mShadowProjection[6]; -	glh::matrix4f			mGIMatrix; -	glh::matrix4f			mGIMatrixProj; -	glh::matrix4f			mGIModelview; -	glh::matrix4f			mGIProjection; -	glh::matrix4f			mGINormalMatrix; -	glh::matrix4f			mGIInvProj; -	LLVector2				mGIRange; -	F32						mGILightRadius; -	 -	LLPointer<LLDrawable>				mShadowSpotLight[2]; -	F32									mSpotLightFade[2]; -	LLPointer<LLDrawable>				mTargetShadowSpotLight[2]; +    glh::matrix4f           mReflectionModelView; + +	LLPointer<LLDrawable>	mShadowSpotLight[2]; +	F32						mSpotLightFade[2]; +	LLPointer<LLDrawable>	mTargetShadowSpotLight[2];  	LLVector4				mSunClipPlanes;  	LLVector4				mSunOrthoClipPlanes; -  	LLVector2				mScreenScale;  	//water reflection texture  	LLRenderTarget				mWaterRef; - +    LLRenderTarget				mWaterDeferredScreen; +    LLRenderTarget				mWaterDeferredDepth; +    LLRenderTarget				mWaterOcclusionDepth; +    LLRenderTarget			    mWaterDeferredLight;  	//water distortion texture (refraction)  	LLRenderTarget				mWaterDis;  	//texture for making the glow  	LLRenderTarget				mGlow[3]; +    // texture for SH indirect sky contribution +	LLRenderTarget				mSkySH; +  	//noise map  	U32					mNoiseMap;  	U32					mTrueNoiseMap;  | 
