From 569f9cf88a7bc9b9cb9ee6e33fb7c3bc06d08b30 Mon Sep 17 00:00:00 2001 From: Cinders Date: Sun, 20 Jan 2013 07:18:35 -0700 Subject: [PATCH] Pull in STORM-1921, STORM-1927, STORM-1928: improved Dof, SSAO, and Fog fixes by Tofu Buzzard --- doc/contributions.txt | 3 + indra/newview/app_settings/settings.xml | 4 +- .../shaders/class1/deferred/blurLightF.glsl | 15 +++-- .../class1/deferred/postDeferredF.glsl | 15 ++--- .../shaders/class1/deferred/softenLightF.glsl | 13 ++-- .../class1/deferred/sunLightSSAOF.glsl | 53 +++++++++------- .../shaders/class1/deferred/waterF.glsl | 4 +- .../shaders/class1/deferred/waterV.glsl | 2 +- .../shaders/class1/environment/waterV.glsl | 3 +- .../shaders/class2/deferred/softenLightF.glsl | 14 ++--- .../class2/deferred/sunLightSSAOF.glsl | 61 ++++++++++--------- 11 files changed, 101 insertions(+), 86 deletions(-) diff --git a/doc/contributions.txt b/doc/contributions.txt index 2e526f7d8d..3132469862 100644 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -1200,6 +1200,9 @@ Tofu Buzzard SH-2477 STORM-1684 STORM-1819 + STORM-1921 + STORM-1927 + STORM-1928 Tony Kembia Torben Trautman TouchaHoney Perhaps diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 03edfc7788..f597bc1a6d 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -3078,7 +3078,7 @@ Type F32 Value - 10.0 + 20.0 CameraFNumber @@ -10550,7 +10550,7 @@ Change of this parameter will affect the layout of buttons in notification toast Type F32 Value - 0.7 + 0.5 RenderSpotLightsInNondeferred diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl index f400eb7a5b..83c06476f1 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl @@ -72,24 +72,23 @@ void main() vec3 pos = getPosition(tc).xyz; vec4 ccol = texture2DRect(lightMap, tc).rgba; - vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy); + vec2 dlt = kern_scale * delta / (vec2(1.0)+norm.xy*norm.xy); dlt /= max(-pos.z*dist_factor, 1.0); vec2 defined_weight = getKern(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; + float pointplanedist_tolerance_pow2 = pos.z*-0.001; // 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; + vec2 tc_v = fract(0.5 * tc.xy); // we now have floor(mod(tc,2.0))*0.5 + float tc_mod = 2.0 * abs(tc_v.x - tc_v.y); // diff of x,y makes checkerboard tc += ( (tc_mod - 0.5) * getKern(1).z * dlt * 0.5 ); for (int i = 1; i < 4; i++) { - vec2 samptc = tc + getKern(i).z*dlt; + vec2 samptc = (tc + getKern(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) @@ -100,7 +99,7 @@ void main() } for (int i = 1; i < 4; i++) { - vec2 samptc = tc - getKern(i).z*dlt; + vec2 samptc = (tc - getKern(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) @@ -111,7 +110,7 @@ void main() } col /= defined_weight.xyxx; - col.y *= col.y; + col.y *= col.y; // delinearize SSAO effect post-blur frag_color = col; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl index bf362e21a4..1db8ba3012 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl @@ -75,23 +75,20 @@ void dofSampleNear(inout vec4 diff, inout float w, float min_sc, vec2 tc) void main() { - vec2 tc = vary_fragcoord.xy; - vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy); { - float w = 1.0; - float sc = (diff.a*2.0-1.0)*max_cof; + float w = 1.0; - float PI = 3.14159265358979323846264; + const float PI = 3.14159265358979323846264; // sample quite uniformly spaced points within a circle, for a circular 'bokeh' if (sc > 0.5) { while (sc > 0.5) { - int its = int(max(1.0,(sc*3.7))); + int its = int(max(1.0,(sc*PI))); for (int i=0; i 0.5) { - int its = int(max(1.0,(sc*3.7))); + int its = int(max(1.0,(sc*PI))); for (int i=0; i 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) + vec3 samppos_world = getPosition(samppos_screen).xyz; - angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv); + vec3 diff = samppos_world - pos.xyz; - // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion" - points = points + int(diff.z > -1.0); + if (diff.z < ssao_factor && diff.z != 0.0) + { + float dist = length(diff); + float angrel = max(0.0, dot(norm.xyz, diff/dist)); + float distrel = 1.0/(1.0+dist*dist); + float samplehidden = min(angrel, distrel); + + angle_hidden += (samplehidden); + points += 1.0; + } } - angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0); + angle_hidden /= points; - ret = (1.0 - (float(points != 0) * angle_hidden)); + float rtn = (1.0 - angle_hidden); - return min(ret, 1.0); + return (rtn * rtn); } void main() diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl index 3427d6db57..1ae006bc8a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl @@ -151,8 +151,8 @@ void main() //spec *= shadow; //color.rgb += spec * specular; - //color.rgb = atmosTransport(color.rgb); - //color.rgb = scaleSoftClip(color.rgb); + color.rgb = atmosTransport(color.rgb); + color.rgb = scaleSoftClip(color.rgb); //color.a = spec * sunAngle2; //wavef.z *= 0.1f; diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl index 9734acf005..ece34dcc4e 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl @@ -85,7 +85,7 @@ void main() pos.w = 1.0; pos = modelview_matrix*pos; - calcAtmospherics(pos.xyz); + calcAtmospherics(view.xyz); //pass wave parameters to pixel shader vec2 bigWave = (v.xy) * vec2(0.04,0.04) + d1 * time * 0.055; diff --git a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl index f66ba1d2d9..fec8906fd0 100644 --- a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl @@ -81,8 +81,7 @@ void main() pos.w = 1.0; pos = modelview_matrix*pos; - calcAtmospherics(pos.xyz); - + calcAtmospherics(view.xyz); //pass wave parameters to pixel shader vec2 bigWave = (v.xy) * vec2(0.04,0.04) + d1 * time * 0.055; diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl index 9df9d75905..4f5281c6be 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -205,7 +205,13 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) { //increase ambient when there are more clouds vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5; - /* decrease value and saturation (that in HSV, not HSL) for occluded areas + //haze color + setAdditiveColor( + vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient) + + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x + + tmpAmbient))); + + /* decrease value and saturation (that in HSV, not HSL) for occluded areas * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html * // The following line of code performs the equivalent of: * float ambAlpha = tmpAmbient.a; @@ -215,12 +221,6 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) { */ tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a); - //haze color - setAdditiveColor( - vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient) - + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x - + tmpAmbient))); - //brightness of surface both sunlight and ambient setSunlitColor(vec3(sunlight * .5)); setAmblitColor(vec3(tmpAmbient * .25)); diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl index 2dcd3d656f..d6104b1065 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl @@ -98,62 +98,68 @@ vec2 getKern(int i) //calculate decreases in ambient lighting when crowded out (SSAO) float calcAmbientOcclusion(vec4 pos, vec3 norm) { - float ret = 1.0; - vec2 pos_screen = vary_fragcoord.xy; - vec3 pos_world = pos.xyz; vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy; + // We treat the first sample as the origin, which definitely doesn't obscure itself thanks to being visible for sampling in the first place. + float points = 1.0; float angle_hidden = 0.0; - float points = 0; - float scale = min(ssao_radius / -pos_world.z, ssao_max_radius); + // use a kernel scale that diminishes with distance. + // a scale of less than 32 is just wasting good samples, though. + float scale = max(32.0, min(ssao_radius / -pos.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); + + // if sample is out-of-screen then give it no weight by continuing + if (any(lessThan(samppos_screen.xy, vec2(0.0, 0.0))) || + any(greaterThan(samppos_screen.xy, vec2(screen_res.xy)))) continue; + vec3 samppos_world = getPosition(samppos_screen).xyz; - vec3 diff = pos_world - samppos_world; - float dist2 = dot(diff, diff); + vec3 diff = samppos_world - pos.xyz; - // assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area - // --> solid angle shrinking by the square of distance - //radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2 - //(k should vary inversely with # of samples, but this is taken care of later) + if (diff.z < ssao_factor // only use sample if it's near enough + && diff.z != 0.0 // Z is very quantized at distance, this lessens noise and eliminates dist==0 + ) + { + float dist = length(diff); + float angrel = max(0.0, dot(norm.xyz, diff/dist)); // how much the origin faces the sample + float distrel = 1.0/(1.0+dist*dist); // 'closeness' of origin to sample - 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); + // origin is obscured by this sample according to how directly the origin is facing the sample and how close the sample is. It has to score high on both to be a good occluder. (a*d) seems the most intuitive way to score, but min(a,d) gives a less localized effect... + float samplehidden = min(angrel, distrel); - // '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 += (samplehidden); + points += 1.0; + } } - angle_hidden = min(ssao_factor*angle_hidden/points, 1.0); + angle_hidden = angle_hidden / points; - float points_val = (points > 0.0) ? 1.0 : 0.0; - ret = (1.0 - (points_val * angle_hidden)); + float rtn = (1.0 - angle_hidden); - ret = max(ret, 0.0); - return min(ret, 1.0); + return (rtn * rtn); } float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen) { + vec2 recip_shadow_res = 1.0 / shadow_res.xy; stc.xyz /= stc.w; stc.z += shadow_bias; - stc.x = floor(stc.x*shadow_res.x + fract(pos_screen.y*0.666666666))/shadow_res.x; + stc.x = floor(stc.x*shadow_res.x + fract(pos_screen.y*0.666666666)) * recip_shadow_res.x; 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; + shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0*recip_shadow_res.x, 1.5*recip_shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0*recip_shadow_res.x, -1.5*recip_shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0*recip_shadow_res.x, 1.5*recip_shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0*recip_shadow_res.x, -1.5*recip_shadow_res.y, 0.0)).x; return shadow*0.2; } @@ -167,8 +173,7 @@ float pcfSpotShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_scr float cs = shadow2D(shadowMap, stc.xyz).x; float shadow = cs; - vec2 off = 1.0/proj_shadow_res; - off.y *= 1.5; + vec2 off = vec2(1.0, 1.5) / proj_shadow_res.xy; 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;