summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorGraham Linden <graham@lindenlab.com>2018-12-03 15:33:15 -0800
committerGraham Linden <graham@lindenlab.com>2018-12-03 15:33:15 -0800
commitb6fa72d3c4d02527f6d118eadc9ba1ac48a297f5 (patch)
tree8b2025afc4049f0b8238ba994852082675ab25d1 /indra/newview
parent79049c49bd34d58c3a3140d4fc50f586e45f3047 (diff)
SL-10055
Modify handling of directional light to prefer sun when it is up but use moon dir/color when it is alone in the sky. Modify handling of shader in shaders to get some shadowing of ambient and nighttime shadowing.
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl13
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl332
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/materialF.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl192
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl14
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl12
-rw-r--r--indra/newview/llvosky.cpp24
-rw-r--r--indra/newview/llvosky.h3
-rw-r--r--indra/newview/pipeline.cpp112
-rw-r--r--indra/newview/pipeline.h1
11 files changed, 399 insertions, 324 deletions
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
index f79fc012d1..07b0f2a98a 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
@@ -43,6 +43,7 @@ uniform mat3 env_mat;
uniform mat3 ssao_effect_mat;
uniform vec3 sun_dir;
+uniform vec3 moon_dir;
#if HAS_SHADOW
uniform sampler2DShadow shadowMap0;
@@ -280,20 +281,20 @@ void main()
vec2 abnormal = encode_normal(norm.xyz);
norm.xyz = decode_normal(abnormal.xy);
- float da = dot(norm.xyz, sun_dir.xyz);
+ float sun_da = dot(norm.xyz, sun_dir.xyz);
+ float moon_da = dot(norm.xyz, moon_dir.xyz);
- float final_da = da;
+ float final_da = max(sun_da, moon_da);
final_da = min(final_da, shadow);
- 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 = clamp(final_da, 0.0f, 1.0f);
+ final_da = pow(final_da, 1.0/1.3);
vec4 color = vec4(0,0,0,0);
color.rgb = atmosFragAmbient(color.rgb, amblit);
color.a = final_alpha;
- float ambient = abs(da);
+ float ambient = abs(final_da);
ambient *= 0.5;
ambient *= ambient;
ambient = (1.0-ambient);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
index 43f0034874..ec05dab57f 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
@@ -1,5 +1,5 @@
/**
- * @file shadowUtil.glsl
+ * @file class1/deferred/deferredUtil.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -39,6 +39,7 @@ 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];
@@ -55,7 +56,7 @@ vec3 decode_normal(vec2 enc);
vec2 getScreenCoordinate(vec2 screenpos)
{
- vec2 sc = screenpos.xy * 2.0;
+ vec2 sc = screenpos.xy * 2.0;
if (screen_res.x > 0 && screen_res.y > 0)
{
sc /= screen_res;
@@ -72,41 +73,41 @@ vec3 getNorm(vec2 screenpos)
float getDepth(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen).r;
- return depth;
+ 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;
+ 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;
}
#if USE_DEFERRED_SHADER_API
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;
+ 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;
}
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;
+ 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;
@@ -116,85 +117,90 @@ float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float bias_scale, vec2 pos_
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;
+ 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_directional_light = max(0.0, dot(sun_dir.xyz, norm));
- vec3 offset = sun_dir.xyz * (1.0-dp_directional_light);
- vec3 shadow_pos = pos.xyz + (offset * shadow_bias);
+ 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;
- }
+ 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;
}
@@ -203,88 +209,88 @@ 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;
+ 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;
- }
+ 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;
+ 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];
+ 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);
+ 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/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
index c1c17532b8..7d5ae7c2e7 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
@@ -98,6 +98,7 @@ uniform mat3 env_mat;
uniform mat3 ssao_effect_mat;
uniform vec3 sun_dir;
+uniform vec3 moon_dir;
VARYING vec2 vary_fragcoord;
VARYING vec3 vary_position;
@@ -381,9 +382,10 @@ void main()
vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
- float da =dot(norm.xyz, sun_dir.xyz);
+ float sun_da = dot(norm.xyz, sun_dir.xyz);
+ float moon_da = dot(norm.xyz, moon_dir.xyz);
- float final_da = da;
+ 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);
@@ -392,7 +394,7 @@ void main()
col.rgb = atmosFragAmbient(col, amblit);
- float ambient = min(abs(da), 1.0);
+ float ambient = min(abs(final_da), 1.0);
ambient *= 0.5;
ambient *= ambient;
ambient = (1.0-ambient);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
index 5813dd84ee..41eb06126b 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
@@ -56,6 +56,7 @@ uniform mat3 env_mat;
uniform mat3 ssao_effect_mat;
uniform vec3 sun_dir;
+uniform vec3 moon_dir;
VARYING vec2 vary_fragcoord;
uniform mat4 inv_proj;
@@ -104,15 +105,17 @@ void main()
float envIntensity = norm.z;
norm.xyz = decode_normal(norm.xy); // unpack norm
- float da = dot(norm.xyz, sun_dir.xyz);
+ 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);
float final_da = clamp(da, 0.0, 1.0);
- final_da = pow(final_da, 1.0/1.3);
+ final_da = pow(final_da, global_gamma);
vec4 diffuse = texture2DRect(diffuseRect, tc);
//convert to gamma space
- diffuse.rgb = linear_to_srgb(diffuse.rgb);
+ //diffuse.rgb = linear_to_srgb(diffuse.rgb);
vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
vec3 col;
@@ -171,8 +174,7 @@ void main()
bloom = fogged.a;
#endif
- col = srgb_to_linear(col);
-
+ //col = srgb_to_linear(col);
//col = vec3(1,0,1);
//col.g = envIntensity;
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
index 541122fb18..184ac13b27 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
@@ -39,7 +39,7 @@ uniform sampler2DRect normalMap;
uniform sampler2DRect lightMap;
uniform sampler2DRect depthMap;
uniform samplerCube environmentMap;
-uniform sampler2D lightFunc;
+uniform sampler2D lightFunc;
uniform float blur_size;
uniform float blur_fidelity;
@@ -68,13 +68,12 @@ uniform vec4 shadow_clip;
uniform mat3 ssao_effect_mat;
uniform vec3 sun_dir;
+uniform vec3 moon_dir;
VARYING vec2 vary_fragcoord;
uniform mat4 inv_proj;
uniform vec2 screen_res;
-uniform int no_atmo;
-
vec3 srgb_to_linear(vec3 cs);
vec3 linear_to_srgb(vec3 cl);
vec3 decode_normal (vec2 enc);
@@ -90,20 +89,20 @@ 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;
+ 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);
+ float depth = texture2DRect(depthMap, pos_screen.xy).r;
+ return getPosition_d(pos_screen, depth);
}
@@ -113,92 +112,93 @@ 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 = max(dot(norm.xyz, sun_dir.xyz), 0.0);
-
- float light_gamma = 1.0/1.3;
- da = pow(da, light_gamma);
-
- vec4 diffuse = texture2DRect(diffuseRect, tc);
-
- //convert to gamma space
- diffuse.rgb = linear_to_srgb(diffuse.rgb);
-
- 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(light_gamma));
-
- float scol = max(scol_ambocc.r, diffuse.a);
- float ambocc = scol_ambocc.g;
+ 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));
+ 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);
+
+ 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));
+
+ float scol = max(scol_ambocc.r, diffuse.a);
+ float ambocc = scol_ambocc.g;
vec3 sunlit;
vec3 amblit;
vec3 additive;
vec3 atten;
-
- calcFragAtmospherics(pos.xyz, ambocc, sunlit, amblit, additive, atten);
-
- float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
- ambient *= 0.5;
- ambient *= ambient;
- ambient = (1.0-ambient);
-
- col.rgb = amblit;
- col.rgb *= ambient;
- col += sunlit * min(da, scol);
- col *= diffuse.rgb;
-
- vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
-
- if (spec.a > 0.0) // specular reflection
- {
- // the old infinite-sky shiny reflection
- float sa = dot(refnormpersp, sun_dir.xyz);
- vec3 dumbshiny = sunlit*scol_ambocc.r*(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;
- }
-
- col = mix(col, diffuse.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);
- }
-
- if (norm.w < 0.5)
- {
- col = mix(atmosFragLighting(col, additive, atten), fullbrightAtmosTransportFrag(col, additive, atten), diffuse.a);
- col = mix(scaleSoftClipFrag(col), fullbrightScaleSoftClipFrag(col), diffuse.a);
- }
-
- #ifdef WATER_FOG
- vec4 fogged = applyWaterFogView(pos.xyz,vec4(col, bloom));
- col = fogged.rgb;
- bloom = fogged.a;
- #endif
-
- col = srgb_to_linear(col);
-
- //col = vec3(1,0,1);
- //col.g = envIntensity;
- }
-
- frag_color.rgb = col;
- frag_color.a = bloom;
+
+ calcFragAtmospherics(pos.xyz, ambocc, sunlit, amblit, additive, atten);
+
+ float ambient = dot(norm.xyz, sun_dir.xyz);
+ ambient *= 0.5;
+ ambient *= ambient;
+ ambient = (1.0-ambient);
+
+ col.rgb = amblit;
+ col.rgb *= min(ambient, max(scol, 0.5));
+
+ col += (sunlit * da) * scol;
+
+ col *= diffuse.rgb;
+
+ vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+
+ if (spec.a > 0.0) // specular reflection
+ {
+ // the old infinite-sky shiny reflection
+ float sa = dot(refnormpersp, sun_dir.xyz);
+ vec3 dumbshiny = sunlit*scol_ambocc.r*(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;
+ }
+
+ col = mix(col, diffuse.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);
+ }
+
+ if (norm.w < 0.5)
+ {
+ col = mix(atmosFragLighting(col, additive, atten), fullbrightAtmosTransportFrag(col, additive, atten), diffuse.a);
+ col = mix(scaleSoftClipFrag(col), fullbrightScaleSoftClipFrag(col), diffuse.a);
+ }
+
+ #ifdef WATER_FOG
+ vec4 fogged = applyWaterFogView(pos.xyz,vec4(col, bloom));
+ 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/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
index aa5e99a2f7..f2d04c95fe 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
@@ -59,6 +59,7 @@ uniform mat4 inv_proj;
uniform vec2 screen_res;
uniform vec2 proj_shadow_res;
uniform vec3 sun_dir;
+uniform vec3 moon_dir;
uniform vec2 shadow_res;
uniform float shadow_bias;
@@ -138,11 +139,16 @@ void main()
return;
}*/
- float shadow = 0.0;
- float dp_directional_light = max(0.0, dot(norm, sun_dir.xyz));
-
+ float shadow = 0.0;
+ float dp_sun = dot(norm, normalize(sun_dir.xyz));
+ float dp_moon = dot(norm, normalize(moon_dir.xyz));
+ float dp_directional_light = max(dp_sun, dp_moon);
+ dp_directional_light = clamp(dp_directional_light, 0.0, 1.0);
+
+ vec3 light_direction = (dp_moon > dp_sun) ? moon_dir : sun_dir;
+
vec3 shadow_pos = pos.xyz;
- vec3 offset = sun_dir.xyz * (1.0-dp_directional_light);
+ vec3 offset = light_direction.xyz * (1.0-dp_directional_light);
vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0);
diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
index 58f3f2f91e..fd3256e9c8 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
@@ -59,6 +59,7 @@ uniform mat4 inv_proj;
uniform vec2 screen_res;
uniform vec2 proj_shadow_res;
uniform vec3 sun_dir;
+uniform vec3 moon_dir;
uniform vec2 shadow_res;
@@ -200,10 +201,15 @@ void main()
}*/
float shadow = 0.0;
- float dp_directional_light = max(0.0, dot(norm, sun_dir.xyz));
-
+ float dp_sun = dot(norm, normalize(sun_dir.xyz));
+ float dp_moon = dot(norm, normalize(moon_dir.xyz));
+ float dp_directional_light = max(dp_sun, dp_moon);
+ dp_directional_light = max(0.0, dp_directional_light);
+
+ vec3 light_direction = (dp_moon > dp_sun) ? moon_dir : sun_dir;
+
vec3 shadow_pos = pos.xyz;
- vec3 offset = sun_dir.xyz * (1.0-dp_directional_light);
+ vec3 offset = light_direction.xyz * (1.0-dp_directional_light);
vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0);
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index f5aa003417..d30bb260e1 100644
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -732,8 +732,14 @@ void LLVOSky::updateDirections(void)
{
LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+ mLastSunLightingDirection = mSun.getDirection();
+ mLastMoonLightingDirection = mMoon.getDirection();
+
+ mSun.setDirection(psky->getSunDirection());
+ mMoon.setDirection(psky->getMoonDirection());
+
mSun.setColor(psky->getSunlightColor());
- mMoon.setColor(LLColor3(1.0f, 1.0f, 1.0f));
+ mMoon.setColor(psky->getMoonDiffuse());
mSun.renewDirection();
mSun.renewColor();
@@ -788,17 +794,20 @@ bool LLVOSky::updateSky()
LLVector3 direction = mSun.getDirection();
direction.normalize();
- const F32 dot_lighting = direction * mLastLightingDirection;
+ const F32 dot_sun = direction * mLastSunLightingDirection;
+ const F32 dot_moon = direction * mLastMoonLightingDirection;
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 light_direction_changed = (dot_lighting < LIGHT_DIRECTION_THRESHOLD);
- bool color_changed = (delta_color.length() >= COLOR_CHANGE_THRESHOLD);
+ 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 || light_direction_changed;
+ mForceUpdate = mForceUpdate || sun_direction_changed;
+ mForceUpdate = mForceUpdate || moon_direction_changed;
mForceUpdate = mForceUpdate || color_changed;
mForceUpdate = mForceUpdate || !mInitialized;
@@ -816,7 +825,6 @@ bool LLVOSky::updateSky()
if (!direction.isExactlyZero())
{
- mLastLightingDirection = direction;
mLastTotalAmbient = total_ambient;
mInitialized = TRUE;
@@ -1623,8 +1631,6 @@ void LLVOSky::setSunAndMoonDirectionsCFR(const LLVector3 &sun_dir_cfr, const LLV
mSun.setDirection(sun_dir_cfr);
mMoon.setDirection(moon_dir_cfr);
- mLastLightingDirection = mSun.getDirection();
-
// Push the sun "South" as it approaches directly overhead so that we can always see bump mapping
// on the upward facing faces of cubes.
{
@@ -1650,8 +1656,6 @@ void LLVOSky::setSunDirectionCFR(const LLVector3 &sun_dir_cfr)
{
mSun.setDirection(sun_dir_cfr);
- mLastLightingDirection = mSun.getDirection();
-
// Push the sun "South" as it approaches directly overhead so that we can always see bump mapping
// on the upward facing faces of cubes.
{
diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h
index 20d0135c21..0713661295 100644
--- a/indra/newview/llvosky.h
+++ b/indra/newview/llvosky.h
@@ -334,7 +334,8 @@ protected:
bool mInitialized;
bool mForceUpdate; //flag to force instantaneous update of cubemap
- LLVector3 mLastLightingDirection;
+ LLVector3 mLastSunLightingDirection;
+ LLVector3 mLastMoonLightingDirection;
LLColor3 mLastTotalAmbient;
F32 mAmbientScale;
LLColor3 mNightColorShift;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 21b70e9c60..cd2146ab4e 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -6008,6 +6008,13 @@ void LLPipeline::setupAvatarLights(bool for_edit)
{
assertInitialized();
+ LLEnvironment& environment = LLEnvironment::instance();
+ LLSettingsSky::ptr_t psky = environment.getCurrentSky();
+
+ bool sun_up = environment.getIsSunUp();
+ bool moon_up = environment.getIsMoonUp();
+ bool sun_is_primary = sun_up || !moon_up;
+
if (for_edit)
{
LLColor4 diffuse(1.f, 1.f, 1.f, 0.f);
@@ -6042,13 +6049,14 @@ void LLPipeline::setupAvatarLights(bool for_edit)
}
else if (gAvatarBacklight) // Always true (unless overridden in a devs .ini)
{
- LLVector3 sun_dir = LLVector3(mSunDir);
- LLVector3 opposite_pos = -sun_dir;
- LLVector3 orthog_light_pos = sun_dir % LLVector3::z_axis;
+ LLVector3 light_dir = sun_is_primary ? LLVector3(mSunDir) : LLVector3(mMoonDir);
+ LLVector3 opposite_pos = -light_dir;
+ LLVector3 orthog_light_pos = light_dir % LLVector3::z_axis;
LLVector4 backlight_pos = LLVector4(lerp(opposite_pos, orthog_light_pos, 0.3f), 0.0f);
backlight_pos.normalize();
-
- LLColor4 light_diffuse = mSunDiffuse;
+
+ LLColor4 light_diffuse = sun_is_primary ? mSunDiffuse : mMoonDiffuse;
+
LLColor4 backlight_diffuse(1.f - light_diffuse.mV[VRED], 1.f - light_diffuse.mV[VGREEN], 1.f - light_diffuse.mV[VBLUE], 1.f);
F32 max_component = 0.001f;
for (S32 i = 0; i < 3; i++)
@@ -6279,6 +6287,10 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
gGL.setAmbientLightColor(ambient);
}
+ bool sun_up = environment.getIsSunUp();
+ bool moon_up = environment.getIsMoonUp();
+ bool sun_is_primary = sun_up || !moon_up;
+
// Light 0 = Sun or Moon (All objects)
{
LLVector4 sun_dir(environment.getSunDirection(), 0.0f);
@@ -6286,15 +6298,8 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
mSunDir.setVec(sun_dir);
mMoonDir.setVec(moon_dir);
-
- if (environment.getIsSunUp())
- {
- mSunDiffuse.setVec(psky->getSunDiffuse());
- }
- else
- {
- mSunDiffuse.setVec(psky->getMoonDiffuse());
- }
+ mSunDiffuse.setVec(psky->getSunDiffuse());
+ mMoonDiffuse.setVec(psky->getMoonDiffuse());
F32 max_color = llmax(mSunDiffuse.mV[0], mSunDiffuse.mV[1], mSunDiffuse.mV[2]);
if (max_color > 1.f)
@@ -6303,19 +6308,21 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
}
mSunDiffuse.clamp();
- LLColor4 light_diffuse = mSunDiffuse;
+ max_color = llmax(mMoonDiffuse.mV[0], mMoonDiffuse.mV[1], mMoonDiffuse.mV[2]);
+ if (max_color > 1.f)
+ {
+ mMoonDiffuse *= 1.f/max_color;
+ }
+ mMoonDiffuse.clamp();
+
+ LLColor4 light_diffuse = sun_is_primary ? mSunDiffuse : mMoonDiffuse;
+ LLVector4 light_dir = sun_is_primary ? mSunDir : mMoonDir;
mHWLightColors[0] = light_diffuse;
LLLightState* light = gGL.getLight(0);
- if (environment.getIsSunUp())
- {
- light->setPosition(mSunDir);
- }
- else
- {
- light->setPosition(mMoonDir);
- }
+ light->setPosition(light_dir);
+
light->setDiffuse(light_diffuse);
light->setAmbient(LLColor4::black);
light->setSpecular(LLColor4::black);
@@ -8491,17 +8498,32 @@ void LLPipeline::renderDeferredLighting()
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);
- mTransformedSunDir.set(tc.v);
- mTransformedSunDir.normalize();
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();
@@ -9110,16 +9132,31 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target)
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);
- mTransformedSunDir.set(tc.v);
- mTransformedSunDir.normalize();
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();
@@ -10697,17 +10734,20 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
//LLVector3 n = RenderShadowNearDist;
//F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] };
- LLVector3 sun_dir(mSunDir);
+ LLEnvironment& environment = LLEnvironment::instance();
+ LLSettingsSky::ptr_t psky = environment.getCurrentSky();
+
+ LLVector3 caster_dir(environment.getIsSunUp() ? mSunDir : mMoonDir);
//put together a universal "near clip" plane for shadow frusta
LLPlane shadow_near_clip;
{
LLVector3 p = gAgent.getPositionAgent();
- p += sun_dir * RenderFarClip*2.f;
- shadow_near_clip.setVec(p, sun_dir);
+ p += caster_dir * RenderFarClip*2.f;
+ shadow_near_clip.setVec(p, caster_dir);
}
- LLVector3 lightDir = -sun_dir;
+ LLVector3 lightDir = -caster_dir;
lightDir.normVec();
glh::vec3f light_dir(lightDir.mV);
@@ -10810,9 +10850,15 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
// convenience array of 4 near clip plane distances
F32 dist[] = { near_clip, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] };
-
- if (mSunDiffuse == LLColor4::black)
+ bool sun_up = environment.getIsSunUp();
+ bool moon_up = environment.getIsMoonUp();
+ bool sun_is_primary = sun_up || !moon_up;
+ bool ignore_shadows = (sun_is_primary && (mSunDiffuse == LLColor4::black))
+ || (moon_up && (mMoonDiffuse == LLColor4::black))
+ || !(sun_up || moon_up);
+
+ if (ignore_shadows)
{ //sun diffuse is totally black, shadows don't matter
LLGLDepthTest depth(GL_TRUE);
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 57d2331222..9977781065 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -663,6 +663,7 @@ public:
U32 mLightFunc;
LLColor4 mSunDiffuse;
+ LLColor4 mMoonDiffuse;
LLVector4 mSunDir;
LLVector4 mMoonDir;