diff options
author | Graham Linden <graham@lindenlab.com> | 2018-12-03 15:33:15 -0800 |
---|---|---|
committer | Graham Linden <graham@lindenlab.com> | 2018-12-03 15:33:15 -0800 |
commit | b6fa72d3c4d02527f6d118eadc9ba1ac48a297f5 (patch) | |
tree | 8b2025afc4049f0b8238ba994852082675ab25d1 /indra/newview | |
parent | 79049c49bd34d58c3a3140d4fc50f586e45f3047 (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.glsl | 13 | ||||
-rw-r--r-- | indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl | 332 | ||||
-rw-r--r-- | indra/newview/app_settings/shaders/class1/deferred/materialF.glsl | 8 | ||||
-rw-r--r-- | indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl | 12 | ||||
-rw-r--r-- | indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl | 192 | ||||
-rw-r--r-- | indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl | 14 | ||||
-rw-r--r-- | indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl | 12 | ||||
-rw-r--r-- | indra/newview/llvosky.cpp | 24 | ||||
-rw-r--r-- | indra/newview/llvosky.h | 3 | ||||
-rw-r--r-- | indra/newview/pipeline.cpp | 112 | ||||
-rw-r--r-- | indra/newview/pipeline.h | 1 |
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; |