diff options
Diffstat (limited to 'indra/newview/app_settings/shaders/class2/deferred')
9 files changed, 646 insertions, 1305 deletions
diff --git a/indra/newview/app_settings/shaders/class2/deferred/indirect.glsl b/indra/newview/app_settings/shaders/class2/deferred/indirect.glsl new file mode 100644 index 0000000000..67b98e0fb1 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/indirect.glsl @@ -0,0 +1,32 @@ +/** + * @file class2/deferred/indirect.glsl + * + * $LicenseInfo:firstyear=2018&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$ + */ + +float calcAmbientOcclusion(vec4 pos, vec3 norm, vec2 pos_screen); + +vec3 getIndirect(vec3 ambient, vec3 norm, vec4 pos, vec2 pos_screen) +{ + return ambient * calcAmbientOcclusion(pos, norm, pos_screen); +} + diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl index b9bb522842..1b7a1cc6ec 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl @@ -71,294 +71,229 @@ uniform vec2 screen_res; uniform mat4 inv_proj; -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)); - -#ifdef OLD_SELECT - vec3 result; - result.r = lte.r ? low_range.r : high_range.r; - result.g = lte.g ? low_range.g : high_range.g; - result.b = lte.b ? low_range.b : high_range.b; - return result; -#else - return mix(high_range, low_range, lte); -#endif - -} - -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)); - -#ifdef OLD_SELECT - vec3 result; - result.r = lt.r ? low_range.r : high_range.r; - result.g = lt.g ? low_range.g : high_range.g; - result.b = lt.b ? low_range.b : high_range.b; - return result; -#else - return mix(high_range, low_range, lt); -#endif - -} - -vec2 encode_normal(vec3 n) -{ - float f = sqrt(8 * n.z + 8); - return n.xy / f + 0.5; -} - -vec3 decode_normal (vec2 enc) -{ - vec2 fenc = enc*4-2; - float f = dot(fenc,fenc); - float g = sqrt(1-f/4); - vec3 n; - n.xy = fenc*g; - n.z = 1-f/2; - return n; -} - -vec4 correctWithGamma(vec4 col) -{ - return vec4(srgb_to_linear(col.rgb), col.a); -} +vec3 srgb_to_linear(vec3 cs); +vec3 getNorm(vec2 pos_screen); 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)); - - float det = min(lod/(proj_lod*0.5), 1.0); - - float d = min(dist.x, dist.y); + vec4 ret = texture2DLod(projectionMap, tc, lod); + ret.rgb = srgb_to_linear(ret.rgb); + vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); + + float det = min(lod/(proj_lod*0.5), 1.0); + + float d = min(dist.x, dist.y); d *= min(1, d * (proj_lod - lod)); - - float edge = 0.25*det; - ret *= clamp(d/edge, 0.0, 1.0); - - return ret; + float edge = 0.25*det; + + ret *= clamp(d/edge, 0.0, 1.0); + + return ret; } 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)); - - float det = min(lod/(proj_lod*0.5), 1.0); - - float d = min(dist.x, dist.y); - - float edge = 0.25*det; - - ret *= clamp(d/edge, 0.0, 1.0); - - return ret; + vec4 ret = texture2DLod(projectionMap, tc, lod); + ret.rgb = srgb_to_linear(ret.rgb); + + vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); + + float det = min(lod/(proj_lod*0.5), 1.0); + + float d = min(dist.x, dist.y); + + float edge = 0.25*det; + + ret *= clamp(d/edge, 0.0, 1.0); + + return ret; } vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod) { - vec4 ret = texture2DLod(projectionMap, tc, lod); - ret = correctWithGamma(ret); - - vec2 dist = tc-vec2(0.5); - - float d = dot(dist,dist); - - ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0); - - return ret; -} + vec4 ret = texture2DLod(projectionMap, tc, lod); + ret.rgb = srgb_to_linear(ret.rgb); - -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 dist = tc-vec2(0.5); + + float d = dot(dist,dist); + + ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0); + + return ret; } +vec4 getPosition(vec2 pos_screen); + void main() { - vec4 frag = vary_fragcoord; - frag.xyz /= frag.w; - frag.xyz = frag.xyz*0.5+0.5; - frag.xy *= screen_res; - - vec3 pos = getPosition(frag.xy).xyz; - vec3 lv = center.xyz-pos.xyz; - float dist = length(lv); - dist /= size; - if (dist > 1.0) - { - discard; - } - - float shadow = 1.0; - - if (proj_shadow_idx >= 0) - { - vec4 shd = texture2DRect(lightMap, frag.xy); - float sh[2]; - sh[0] = shd.b; - sh[1] = shd.a; - shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0); - } - - vec3 norm = texture2DRect(normalMap, frag.xy).xyz; - - float envIntensity = norm.z; - - norm = decode_normal(norm.xy); - - norm = normalize(norm); - float l_dist = -dot(lv, proj_n); - - vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); - if (proj_tc.z < 0.0) - { - discard; - } - - proj_tc.xyz /= proj_tc.w; - - float fa = falloff+1.0; - float dist_atten = min(1.0-(dist-1.0*(1.0-fa))/fa, 1.0); - dist_atten *= dist_atten; - dist_atten *= 2.0; - if (dist_atten <= 0.0) - { - discard; - } - - lv = proj_origin-pos.xyz; - lv = normalize(lv); - float da = dot(norm, lv); - - vec3 col = vec3(0,0,0); - - vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb; - - vec4 spec = texture2DRect(specularRect, frag.xy); - - vec3 dlit = vec3(0, 0, 0); - - float noise = texture2D(noiseMap, frag.xy/128.0).b; - if (proj_tc.z > 0.0 && - proj_tc.x < 1.0 && - proj_tc.y < 1.0 && - proj_tc.x > 0.0 && - proj_tc.y > 0.0) - { - float amb_da = proj_ambiance; - float lit = 0.0; - - if (da > 0.0) - { - lit = da * dist_atten * noise; - - float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0); - float lod = diff * proj_lod; - - vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod); - - dlit = color.rgb * plcol.rgb * plcol.a; - - col = dlit*lit*diff_tex*shadow; - amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance; - } - - //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); - vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod); - - amb_da += (da*da*0.5+0.5)*proj_ambiance; - - amb_da *= dist_atten * noise; - - amb_da = min(amb_da, 1.0-lit); - - col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; - } - - - if (spec.a > 0.0) - { - vec3 npos = -normalize(pos); - dlit *= min(da*6.0, 1.0) * dist_atten; - - //vec3 ref = dot(pos+lv, norm); - vec3 h = normalize(lv+npos); - float nh = dot(norm, h); - float nv = dot(norm, 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); - col += dlit*scol*spec.rgb*shadow; - //col += spec.rgb; - } - } - - - - - - if (envIntensity > 0.0) - { - vec3 ref = reflect(normalize(pos), norm); - - //project from point pos in direction ref to plane proj_p, proj_n - vec3 pdelta = proj_p-pos; - float ds = dot(ref, proj_n); - - if (ds < 0.0) - { - vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; - - vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0)); - - if (stc.z > 0.0) - { + + vec3 col = vec3(0,0,0); + +#if defined(LOCAL_LIGHT_KILL) + discard; +#else + vec4 frag = vary_fragcoord; + frag.xyz /= frag.w; + frag.xyz = frag.xyz*0.5+0.5; + frag.xy *= screen_res; + + vec3 pos = getPosition(frag.xy).xyz; + vec3 lv = center.xyz-pos.xyz; + float dist = length(lv); + + if (dist >= size) + { + discard; + } + dist /= size; + + float shadow = 1.0; + + if (proj_shadow_idx >= 0) + { + vec4 shd = texture2DRect(lightMap, frag.xy); + shadow = (proj_shadow_idx==0)?shd.b:shd.a; + shadow += shadow_fade; + shadow = clamp(shadow, 0.0, 1.0); + } + + vec3 norm = texture2DRect(normalMap, frag.xy).xyz; + + float envIntensity = norm.z; + + norm = getNorm(frag.xy); + + norm = normalize(norm); + float l_dist = -dot(lv, proj_n); + + vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); + if (proj_tc.z < 0.0) + { + discard; + } + + proj_tc.xyz /= proj_tc.w; + + float fa = falloff+1.0; + float dist_atten = min(1.0-(dist-1.0*(1.0-fa))/fa, 1.0); + dist_atten *= dist_atten; + dist_atten *= 2.0; + if (dist_atten <= 0.0) + { + discard; + } + + lv = proj_origin-pos.xyz; + lv = normalize(lv); + float da = dot(norm, lv); + + vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb; + + vec4 spec = texture2DRect(specularRect, frag.xy); + + vec3 dlit = vec3(0, 0, 0); + + float noise = texture2D(noiseMap, frag.xy/128.0).b; + if (proj_tc.z > 0.0 && + proj_tc.x < 1.0 && + proj_tc.y < 1.0 && + proj_tc.x > 0.0 && + proj_tc.y > 0.0) + { + float amb_da = proj_ambiance; + float lit = 0.0; + + if (da > 0.0) + { + lit = da * dist_atten * noise; + + float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0); + float lod = diff * proj_lod; + + vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod); + + dlit = color.rgb * plcol.rgb * plcol.a; + + col = dlit*lit*diff_tex*shadow; + + // unshadowed for consistency between forward and deferred? + amb_da += (da*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance; + } + + //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); + vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod); + + // use unshadowed for consistency between forward and deferred? + amb_da += (da*da*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance; + amb_da *= dist_atten * noise; + amb_da = min(amb_da, 1.0-lit); + + col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; + } + + + if (spec.a > 0.0) + { + vec3 npos = -normalize(pos); + dlit *= min(da*6.0, 1.0) * dist_atten; + + //vec3 ref = dot(pos+lv, norm); + vec3 h = normalize(lv+npos); + float nh = dot(norm, h); + float nv = dot(norm, 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 = dlit*scol*spec.rgb*shadow; + speccol = clamp(speccol, vec3(0), vec3(1)); + col += speccol; + } + } + + if (envIntensity > 0.0) + { + vec3 ref = reflect(normalize(pos), norm); + + //project from point pos in direction ref to plane proj_p, proj_n + vec3 pdelta = proj_p-pos; + float ds = dot(ref, proj_n); + + if (ds < 0.0) + { + vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; + + vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0)); + + if (stc.z > 0.0) + { stc /= stc.w; - - if (stc.x < 1.0 && - stc.y < 1.0 && - stc.x > 0.0 && - stc.y > 0.0) - { - col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * shadow * envIntensity; - } - } - } - } - - //not sure why, but this line prevents MATBUG-194 - col = max(col, vec3(0.0)); - - frag_color.rgb = col; - frag_color.a = 0.0; + + if (stc.x < 1.0 && + stc.y < 1.0 && + stc.x > 0.0 && + stc.y > 0.0) + { + col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * shadow * envIntensity; + } + } + } + } +#endif + + //not sure why, but this line prevents MATBUG-194 + col = max(col, vec3(0.0)); + + //output linear + frag_color.rgb = col; + frag_color.a = 0.0; } diff --git a/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl new file mode 100644 index 0000000000..6841a8194f --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl @@ -0,0 +1,199 @@ +/** + * @file class2/deferred/skyF.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$ + */ + +uniform mat4 modelview_projection_matrix; + +// SKY //////////////////////////////////////////////////////////////////////// +// The vertex shader for creating the atmospheric sky +/////////////////////////////////////////////////////////////////////////////// + +// Inputs +uniform vec3 camPosLocal; + +uniform vec4 lightnorm; +uniform vec4 sunlight_color; +uniform vec4 moonlight_color; +uniform int sun_up_factor; +uniform vec4 ambient_color; +uniform vec4 blue_horizon; +uniform vec4 blue_density; +uniform float haze_horizon; +uniform float haze_density; + +uniform float cloud_shadow; +uniform float density_multiplier; +uniform float distance_multiplier; +uniform float max_y; + +uniform vec4 glow; +uniform float sun_moon_glow_factor; + +uniform vec4 cloud_color; + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_data[3]; +#else +#define frag_data gl_FragData +#endif + +VARYING vec3 pos; + +///////////////////////////////////////////////////////////////////////// +// The fragment shader for the sky +///////////////////////////////////////////////////////////////////////// + +uniform sampler2D rainbow_map; +uniform sampler2D halo_map; + +uniform float moisture_level; +uniform float droplet_radius; +uniform float ice_level; + +vec3 rainbow(float d) +{ + // d is the dot product of view and sun directions, so ranging -1.0..1.0 + // 'interesting' values of d are the range -0.75..-0.825, when view is nearly opposite of sun vec + // Rainbox texture mode is GL_REPEAT, so tc of -.75 is equiv to 0.25, -0.825 equiv to 0.175. + + // SL-13629 Rainbow texture has colors within the correct .175...250 range, but order is inverted. + // Rather than replace the texture, we mirror and translate the y tc to keep the colors within the + // interesting range, but in reversed order: i.e. d = (1 - d) - 1.575 + d = clamp(-0.575 - d, 0.0, 1.0); + + // With the colors in the lower 1/4 of the texture, inverting the coords leaves most of it inaccessible. + // So, we can stretch the texcoord above the colors (ie > 0.25) to fill the entire remaining coordinate + // space. This improves gradation, reduces banding within the rainbow interior. (1-0.25) / (0.425/0.25) = 4.2857 + float interior_coord = max(0.0, d - 0.25) * 4.2857; + d = clamp(d, 0.0, 0.25) + interior_coord; + + float rad = (droplet_radius - 5.0f) / 1024.0f; + return pow(texture2D(rainbow_map, vec2(rad, d)).rgb, vec3(1.8)) * moisture_level; +} + +vec3 halo22(float d) +{ + d = clamp(d, 0.1, 1.0); + float v = sqrt(clamp(1 - (d * d), 0, 1)); + return texture2D(halo_map, vec2(0, v)).rgb * ice_level; +} + +/// Soft clips the light with a gamma correction +vec3 scaleSoftClip(vec3 light); + +void main() +{ + // World / view / projection + // Get relative position (offset why?) + vec3 rel_pos = pos.xyz - camPosLocal.xyz + vec3(0, 50, 0); + + // Adj position vector to clamp altitude + if (rel_pos.y > 0.) + { + rel_pos *= (max_y / rel_pos.y); + } + if (rel_pos.y < 0.) + { + rel_pos *= (-32000. / rel_pos.y); + } + + // Normalized + vec3 rel_pos_norm = normalize(rel_pos); + float rel_pos_len = length(rel_pos); + + // Initialize temp variables + vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color; + + // Sunlight attenuation effect (hue and brightness) due to atmosphere + // this is used later for sunlight modulation at various altitudes + vec4 light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y); + + // Calculate relative weights + vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density)); + vec4 blue_weight = blue_density / combined_haze; + vec4 haze_weight = haze_density / combined_haze; + + // Compute sunlight from rel_pos & lightnorm (for long rays like sky) + float off_axis = 1.0 / max(1e-6, max(0, rel_pos_norm.y) + lightnorm.y); + sunlight *= exp(-light_atten * off_axis); + + // Distance + float density_dist = rel_pos_len * density_multiplier; + + // Transparency (-> combined_haze) + // ATI Bugfix -- can't store combined_haze*density_dist in a variable because the ati + // compiler gets confused. + combined_haze = exp(-combined_haze * density_dist); + + // Compute haze glow + float haze_glow = dot(rel_pos_norm, lightnorm.xyz); + haze_glow = 1. - haze_glow; + // haze_glow is 0 at the sun and increases away from sun + haze_glow = max(haze_glow, .001); + // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) + haze_glow *= glow.x; + // Higher glow.x gives dimmer glow (because next step is 1 / "angle") + haze_glow = pow(haze_glow, glow.z); + // glow.z should be negative, so we're doing a sort of (1 / "angle") function + + // Add "minimum anti-solar illumination" + // For sun, add to glow. For moon, remove glow entirely. SL-13768 + haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (sun_moon_glow_factor * (haze_glow + 0.25)); + + // Haze color above cloud + vec4 color = blue_horizon * blue_weight * (sunlight + ambient_color) + + haze_horizon * haze_weight * (sunlight * haze_glow + ambient_color); + + // Final atmosphere additive + color *= (1. - combined_haze); + + // Increase ambient when there are more clouds + // TODO 9/20: DJH what does this do? max(0,(1-ambient)) will change the color + vec4 ambient = ambient_color + max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5; + + // Dim sunlight by cloud shadow percentage + sunlight *= max(0.0, (1. - cloud_shadow)); + + // Haze color below cloud + vec4 add_below_cloud = blue_horizon * blue_weight * (sunlight + ambient) + + haze_horizon * haze_weight * (sunlight * haze_glow + ambient); + + // Attenuate cloud color by atmosphere + combined_haze = sqrt(combined_haze); // less atmos opacity (more transparency) below clouds + + // At horizon, blend high altitude sky color towards the darker color below the clouds + color += (add_below_cloud - color) * (1. - sqrt(combined_haze)); + + float optic_d = dot(rel_pos_norm, lightnorm.xyz); + vec3 halo_22 = halo22(optic_d); + color.rgb += rainbow(optic_d); + color.rgb += halo_22; + color.rgb *= 2.; + color.rgb = scaleSoftClip(color.rgb); + + // Gamma correct for WL (soft clip effect). + frag_data[0] = vec4(color.rgb, 1.0); + frag_data[1] = vec4(0.0, 0.0, 0.0, 0.0); + frag_data[2] = vec4(0.0, 0.0, 0.0, 1.0); // 1.0 in norm.w masks off fog +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class2/deferred/skyV.glsl new file mode 100644 index 0000000000..bcf775577a --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/skyV.glsl @@ -0,0 +1,42 @@ +/** + * @file WLSkyV.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$ + */ + +uniform mat4 modelview_projection_matrix; + +ATTRIBUTE vec3 position; + +// SKY //////////////////////////////////////////////////////////////////////// +// The vertex shader for creating the atmospheric sky +/////////////////////////////////////////////////////////////////////////////// + +VARYING vec3 pos; + +void main() +{ + + // World / view / projection + pos = position.xyz; + gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl index f7832521fa..7700d16007 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -1,29 +1,30 @@ -/** - * @file softenLightF.glsl +/** + * @file class2/deferred/softenLightF.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$ */ - + #extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_shader_texture_lod : enable /*[EXTRA_CODE_HERE]*/ @@ -38,457 +39,120 @@ uniform sampler2DRect specularRect; uniform sampler2DRect normalMap; uniform sampler2DRect lightMap; uniform sampler2DRect depthMap; -uniform samplerCube environmentMap; -uniform sampler2D lightFunc; +uniform samplerCube environmentMap; +uniform sampler2D lightFunc; uniform float blur_size; uniform float blur_fidelity; // Inputs -uniform vec4 morphFactor; -uniform vec3 camPosLocal; -//uniform vec4 camPosWorld; -uniform vec4 gamma; -uniform vec4 lightnorm; -uniform vec4 sunlight_color; -uniform vec4 ambient; -uniform vec4 blue_horizon; -uniform vec4 blue_density; -uniform float haze_horizon; -uniform float haze_density; -uniform float cloud_shadow; -uniform float density_multiplier; -uniform float distance_multiplier; -uniform float max_y; -uniform vec4 glow; -uniform float global_gamma; -uniform float scene_light_strength; uniform mat3 env_mat; -uniform vec4 shadow_clip; -uniform mat3 ssao_effect_mat; uniform vec3 sun_dir; +uniform vec3 moon_dir; +uniform int sun_up_factor; VARYING vec2 vary_fragcoord; -vec3 vary_PositionEye; - -vec3 vary_SunlitColor; -vec3 vary_AmblitColor; -vec3 vary_AdditiveColor; -vec3 vary_AtmosAttenuation; - uniform mat4 inv_proj; uniform vec2 screen_res; -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)); - -#ifdef OLD_SELECT - vec3 result; - result.r = lte.r ? low_range.r : high_range.r; - result.g = lte.g ? low_range.g : high_range.g; - result.b = lte.b ? low_range.b : high_range.b; - return result; -#else - return mix(high_range, low_range, lte); -#endif +vec3 getNorm(vec2 pos_screen); +vec4 getPositionWithDepth(vec2 pos_screen, float depth); -} +void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao); +float getAmbientClamp(); +vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten); +vec3 scaleSoftClipFrag(vec3 l); +vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten); +vec3 fullbrightScaleSoftClip(vec3 light); -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)); +vec3 linear_to_srgb(vec3 c); +vec3 srgb_to_linear(vec3 c); -#ifdef OLD_SELECT - vec3 result; - result.r = lt.r ? low_range.r : high_range.r; - result.g = lt.g ? low_range.g : high_range.g; - result.b = lt.b ? low_range.b : high_range.b; - return result; -#else - return mix(high_range, low_range, lt); +#ifdef WATER_FOG +vec4 applyWaterFogView(vec3 pos, vec4 color); #endif -} - -vec2 encode_normal(vec3 n) -{ - float f = sqrt(8 * n.z + 8); - return n.xy / f + 0.5; -} - -vec3 decode_normal (vec2 enc) -{ - vec2 fenc = enc*4-2; - float f = dot(fenc,fenc); - float g = sqrt(1-f/4); - vec3 n; - n.xy = fenc*g; - n.z = 1-f/2; - return n; -} - -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); -} - -vec3 getPositionEye() -{ - return vary_PositionEye; -} -vec3 getSunlitColor() -{ - return vary_SunlitColor; -} -vec3 getAmblitColor() -{ - return vary_AmblitColor; -} -vec3 getAdditiveColor() -{ - return vary_AdditiveColor; -} -vec3 getAtmosAttenuation() -{ - return vary_AtmosAttenuation; -} - -void setPositionEye(vec3 v) -{ - vary_PositionEye = v; -} - -void setSunlitColor(vec3 v) -{ - vary_SunlitColor = v; -} - -void setAmblitColor(vec3 v) -{ - vary_AmblitColor = v; -} - -void setAdditiveColor(vec3 v) -{ - vary_AdditiveColor = v; -} - -void setAtmosAttenuation(vec3 v) -{ - vary_AtmosAttenuation = v; -} - -void calcAtmospherics(vec3 inPositionEye, float ambFactor) { - - vec3 P = inPositionEye; - setPositionEye(P); - - vec3 tmpLightnorm = lightnorm.xyz; - - vec3 Pn = normalize(P); - float Plen = length(P); - - vec4 temp1 = vec4(0); - vec3 temp2 = vec3(0); - vec4 blue_weight; - vec4 haze_weight; - vec4 sunlight = sunlight_color; - vec4 light_atten; - - //sunlight attenuation effect (hue and brightness) due to atmosphere - //this is used later for sunlight modulation at various altitudes - light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y); - //I had thought blue_density and haze_density should have equal weighting, - //but attenuation due to haze_density tends to seem too strong - - temp1 = blue_density + vec4(haze_density); - blue_weight = blue_density / temp1; - haze_weight = vec4(haze_density) / temp1; - - //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain) - temp2.y = max(0.0, tmpLightnorm.y); - temp2.y = 1. / temp2.y; - sunlight *= exp( - light_atten * temp2.y); - - // main atmospheric scattering line integral - temp2.z = Plen * density_multiplier; - - // Transparency (-> temp1) - // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati - // compiler gets confused. - temp1 = exp(-temp1 * temp2.z * distance_multiplier); - - //final atmosphere attenuation factor - setAtmosAttenuation(temp1.rgb); - - //compute haze glow - //(can use temp2.x as temp because we haven't used it yet) - temp2.x = dot(Pn, tmpLightnorm.xyz); - temp2.x = 1. - temp2.x; - //temp2.x is 0 at the sun and increases away from sun - temp2.x = max(temp2.x, .03); //was glow.y - //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) - temp2.x *= glow.x; - //higher glow.x gives dimmer glow (because next step is 1 / "angle") - temp2.x = pow(temp2.x, glow.z); - //glow.z should be negative, so we're doing a sort of (1 / "angle") function - - //add "minimum anti-solar illumination" - temp2.x += .25; - - //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 - * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html - * // The following line of code performs the equivalent of: - * float ambAlpha = tmpAmbient.a; - * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis - * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue); - * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha); - */ - tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a); - - //haze color - setAdditiveColor( - 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(pow(vec3(sunlight * .5), vec3(global_gamma)) * global_gamma); - setAmblitColor(pow(vec3(tmpAmbient * .25), vec3(global_gamma)) * global_gamma); - setAdditiveColor(pow(getAdditiveColor() * vec3(1.0 - temp1), vec3(global_gamma)) * global_gamma);*/ - - setSunlitColor(vec3(sunlight * .5)); - setAmblitColor(vec3(tmpAmbient * .25)); - setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1)); -} +void main() +{ + 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 = getNorm(tc); + + vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir; + float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0); + float light_gamma = 1.0 / 1.3; + da = pow(da, light_gamma); + + vec4 diffuse = texture2DRect(diffuseRect, tc); + diffuse.rgb = linear_to_srgb(diffuse.rgb); // SL-14025 + 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; + + vec3 color = vec3(0); + float bloom = 0.0; + + vec3 sunlit; + vec3 amblit; + vec3 additive; + vec3 atten; + calcAtmosphericVars(pos.xyz, light_dir, ambocc, sunlit, amblit, additive, atten, true); + + color.rgb = amblit; + + float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0); + ambient *= 0.5; + ambient *= ambient; + ambient = (1.0 - ambient); + color.rgb *= ambient; + + vec3 sun_contrib = min(da, scol) * sunlit; + color.rgb += sun_contrib; + color.rgb *= diffuse.rgb; + + vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); + + if (spec.a > 0.0) // specular reflection + { + float sa = dot(refnormpersp, light_dir.xyz); + vec3 dumbshiny = sunlit * scol * (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; + color.rgb += spec_contrib; + } + + color.rgb = mix(color.rgb, diffuse.rgb, diffuse.a); + + if (envIntensity > 0.0) + { // add environmentmap + vec3 env_vec = env_mat * refnormpersp; + vec3 reflected_color = textureCube(environmentMap, env_vec).rgb; + color = mix(color.rgb, reflected_color, envIntensity); + } + + if (norm.w < 0.5) + { + color = mix(atmosFragLighting(color, additive, atten), fullbrightAtmosTransportFrag(color, additive, atten), diffuse.a); + color = mix(scaleSoftClipFrag(color), fullbrightScaleSoftClip(color), diffuse.a); + } #ifdef WATER_FOG -uniform vec4 waterPlane; -uniform vec4 waterFogColor; -uniform float waterFogDensity; -uniform float waterFogKS; - -vec4 applyWaterFogDeferred(vec3 pos, vec4 color) -{ - //normalize view vector - vec3 view = normalize(pos); - float es = -(dot(view, waterPlane.xyz)); - - //find intersection point with water plane and eye vector - - //get eye depth - float e0 = max(-waterPlane.w, 0.0); - - vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0); - - //get object depth - float depth = length(pos - int_v); - - //get "thickness" of water - float l = max(depth, 0.1); - - float kd = waterFogDensity; - float ks = waterFogKS; - vec4 kc = waterFogColor; - - float F = 0.98; - - float t1 = -kd * pow(F, ks * e0); - float t2 = kd + ks * es; - float t3 = pow(F, t2*l) - 1.0; - - float L = min(t1/t2*t3, 1.0); - - float D = pow(0.98, l*kd); - - color.rgb = color.rgb * D + kc.rgb * L; - color.a = kc.a + color.a; - - return color; -} + vec4 fogged = applyWaterFogView(pos.xyz, vec4(color, bloom)); + color = fogged.rgb; + bloom = fogged.a; #endif -vec3 atmosLighting(vec3 light) -{ - light *= getAtmosAttenuation().r; - light += getAdditiveColor(); - return (2.0 * light); -} - -vec3 atmosTransport(vec3 light) { - light *= getAtmosAttenuation().r; - light += getAdditiveColor() * 2.0; - return light; -} - -vec3 fullbrightAtmosTransport(vec3 light) { - float brightness = dot(light.rgb, vec3(0.33333)); - - return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness); -} - - - -vec3 atmosGetDiffuseSunlightColor() -{ - return getSunlitColor(); -} - -vec3 scaleDownLight(vec3 light) -{ - return (light / scene_light_strength ); -} - -vec3 scaleUpLight(vec3 light) -{ - return (light * scene_light_strength); -} - -vec3 atmosAmbient(vec3 light) -{ - return getAmblitColor() + light / 2.0; -} - -vec3 atmosAffectDirectionalLight(float lightIntensity) -{ - return getSunlitColor() * lightIntensity; -} - -vec3 scaleSoftClip(vec3 light) -{ - //soft clip effect: - light = 1. - clamp(light, vec3(0.), vec3(1.)); - light = 1. - pow(light, gamma.xxx); - - return light; -} - - -vec3 fullbrightScaleSoftClip(vec3 light) -{ - //soft clip effect: - return light; -} - -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; - - calcAtmospherics(pos.xyz, ambocc); - - col = atmosAmbient(vec3(0)); - float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0); - ambient *= 0.5; - ambient *= ambient; - ambient = (1.0-ambient); - - col.rgb *= ambient; - - col += atmosAffectDirectionalLight(max(min(da, scol), 0.0)); - - 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 = vary_SunlitColor*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(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a); - col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a); - } - - #ifdef WATER_FOG - vec4 fogged = applyWaterFogDeferred(pos,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; + // convert to linear as fullscreen lights need to sum in linear colorspace + // and will be gamma (re)corrected downstream... + frag_color.rgb = srgb_to_linear(color.rgb); + 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..bd11aa3f05 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl @@ -31,12 +31,19 @@ uniform vec2 screen_res; VARYING vec2 vary_fragcoord; +// forwards +void setAtmosAttenuation(vec3 c); +void setAdditiveColor(vec3 c); + void main() { //transform vertex vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0); gl_Position = pos; - - + + // appease OSX GLSL compiler/linker by touching all the varyings we said we would + setAtmosAttenuation(vec3(1)); + setAdditiveColor(vec3(0)); + 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 81af1fdc8a..774f537821 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl @@ -71,70 +71,14 @@ uniform vec2 screen_res; uniform mat4 inv_proj; -vec2 encode_normal(vec3 n) -{ - float f = sqrt(8 * n.z + 8); - return n.xy / f + 0.5; -} - -vec3 decode_normal (vec2 enc) -{ - vec2 fenc = enc*4-2; - float f = dot(fenc,fenc); - float g = sqrt(1-f/4); - vec3 n; - n.xy = fenc*g; - n.z = 1-f/2; - return n; -} - -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)); - -#ifdef OLD_SELECT - vec3 result; - result.r = lte.r ? low_range.r : high_range.r; - result.g = lte.g ? low_range.g : high_range.g; - result.b = lte.b ? low_range.b : high_range.b; - return result; -#else - return mix(high_range, low_range, lte); -#endif - -} - -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)); - -#ifdef OLD_SELECT - vec3 result; - result.r = lt.r ? low_range.r : high_range.r; - result.g = lt.g ? low_range.g : high_range.g; - result.b = lt.b ? low_range.b : high_range.b; - return result; -#else - return mix(high_range, low_range, lt); -#endif - -} - -vec4 correctWithGamma(vec4 col) -{ - return vec4(srgb_to_linear(col.rgb), col.a); -} +vec3 getNorm(vec2 pos_screen); +vec3 srgb_to_linear(vec3 c); 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)); float det = min(lod/(proj_lod*0.5), 1.0); @@ -153,7 +97,7 @@ 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); + ret.rgb = srgb_to_linear(ret.rgb); vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); @@ -171,7 +115,7 @@ 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); + ret.rgb = srgb_to_linear(ret.rgb); vec2 dist = tc-vec2(0.5); @@ -182,22 +126,15 @@ 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() { + vec3 col = vec3(0,0,0); + +#if defined(LOCAL_LIGHT_KILL) + discard; +#else vec4 frag = vary_fragcoord; frag.xyz /= frag.w; frag.xyz = frag.xyz*0.5+0.5; @@ -206,26 +143,26 @@ void main() vec3 pos = getPosition(frag.xy).xyz; vec3 lv = trans_center.xyz-pos.xyz; float dist = length(lv); + + if (dist >= size) + { + discard; + } dist /= size; - if (dist > 1.0) - { - discard; - } - + float shadow = 1.0; if (proj_shadow_idx >= 0) { vec4 shd = texture2DRect(lightMap, frag.xy); - float sh[2]; - sh[0] = shd.b; - sh[1] = shd.a; - shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0); + shadow = (proj_shadow_idx == 0) ? shd.b : shd.a; + shadow += shadow_fade; + shadow = clamp(shadow, 0.0, 1.0); } vec3 norm = texture2DRect(normalMap, frag.xy).xyz; float envIntensity = norm.z; - norm = decode_normal(norm.xy); + norm = getNorm(frag.xy); norm = normalize(norm); float l_dist = -dot(lv, proj_n); @@ -252,12 +189,8 @@ void main() lv = normalize(lv); float da = dot(norm, lv); - vec3 col = vec3(0,0,0); - vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb; - vec4 spec = texture2DRect(specularRect, frag.xy); - vec3 dlit = vec3(0, 0, 0); float noise = texture2D(noiseMap, frag.xy/128.0).b; @@ -280,23 +213,21 @@ void main() vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod); dlit = color.rgb * plcol.rgb * plcol.a; - + col = dlit*lit*diff_tex*shadow; - amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance; + + amb_da += (da*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance; } //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod); - amb_da += (da*da*0.5+0.5)*proj_ambiance; - + amb_da += (da*da*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance; amb_da *= dist_atten * noise; - amb_da = min(amb_da, 1.0-lit); - - col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; - } + col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; + } if (spec.a > 0.0) { @@ -317,14 +248,11 @@ void main() if (nh > 0.0) { float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da); - col += dlit*scol*spec.rgb*shadow; - //col += spec.rgb; + vec3 speccol = dlit*scol*spec.rgb*shadow; + speccol = clamp(speccol, vec3(0), vec3(1)); + col += speccol; } } - - - - if (envIntensity > 0.0) { @@ -354,10 +282,12 @@ void main() } } } +#endif //not sure why, but this line prevents MATBUG-194 col = max(col, vec3(0.0)); + //output linear colors as gamma correction happens down stream frag_color.rgb = col; frag_color.a = 0.0; } diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl index 265da8df99..8abdeae5ae 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl @@ -35,228 +35,26 @@ out vec4 frag_color; //class 2, shadows, no SSAO -uniform sampler2DRect depthMap; -uniform sampler2DRect normalMap; -uniform sampler2DShadow shadowMap0; -uniform sampler2DShadow shadowMap1; -uniform sampler2DShadow shadowMap2; -uniform sampler2DShadow shadowMap3; -uniform sampler2DShadow shadowMap4; -uniform sampler2DShadow shadowMap5; - - // 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 vec2 shadow_res; uniform float shadow_bias; -uniform float shadow_offset; - -uniform float spot_shadow_bias; -uniform float spot_shadow_offset; - -vec2 encode_normal(vec3 n) -{ - float f = sqrt(8 * n.z + 8); - return n.xy / f + 0.5; -} - -vec3 decode_normal (vec2 enc) -{ - vec2 fenc = enc*4-2; - float f = dot(fenc,fenc); - float g = sqrt(1-f/4); - vec3 n; - n.xy = fenc*g; - n.z = 1-f/2; - return n; -} - -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) -{ - 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; // add some 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; +vec3 getNorm(vec2 pos_screen); +vec4 getPosition(vec2 pos_screen); - 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(-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; - - - return shadow*0.2; -} - -float pcfSpotShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen) -{ - stc.xyz /= stc.w; - stc.z += spot_shadow_bias*scl; - 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 sampleSpotShadow(vec3 pos, vec3 norm, int index, vec2 pos_screen); void main() { - vec2 pos_screen = vary_fragcoord.xy; - - //try doing an unproject here - - vec4 pos = getPosition(pos_screen); - - vec3 norm = texture2DRect(normalMap, pos_screen).xyz; - norm = decode_normal(norm.xy); // unpack norm - - /*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL - { - frag_color = vec4(0.0); // doesn't matter - return; - }*/ - - float shadow = 0.0; - float dp_directional_light = max(0.0, dot(norm, sun_dir.xyz)); - - vec3 shadow_pos = pos.xyz; - vec3 offset = sun_dir.xyz * (1.0-dp_directional_light); - - vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0); - - if (spos.z > -shadow_clip.w) - { - if (dp_directional_light == 0.0) - { - // if we know this point is facing away from the sun then we know it's in shadow without having to do a squirrelly shadow-map lookup - shadow = 0.0; - } - else - { - vec4 lpos; - - 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.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); - } - - 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.5, 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.75, 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; - - // take the most-shadowed value out of these two: - // * the blurred sun shadow in the light (shadow) map - // * an unblurred dot product between the sun and this norm - // the goal is to err on the side of most-shadow to fill-in shadow holes and reduce artifacting - shadow = min(shadow, dp_directional_light); - - //lpos.xy /= lpos.w*32.0; - //if (fract(lpos.x) < 0.1 || fract(lpos.y) < 0.1) - //{ - // shadow = 0.0; - //} - - } - } - else - { - // more distant than the shadow map covers - shadow = 1.0; - } - - frag_color[0] = shadow; - frag_color[1] = 1.0; - - spos = vec4(shadow_pos+norm*spot_shadow_offset, 1.0); - - //spotlight shadow 1 - vec4 lpos = shadow_matrix[4]*spos; - frag_color[2] = pcfSpotShadow(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.rgb = pos.xyz; - //frag_color.b = shadow; + vec2 pos_screen = vary_fragcoord.xy; + vec4 pos = getPosition(pos_screen); + vec3 norm = getNorm(pos_screen); + + frag_color.r = sampleDirectionalShadow(pos.xyz, norm, pos_screen); + frag_color.g = 1.0f; + frag_color.b = sampleSpotShadow(pos.xyz, norm, 0, pos_screen); + frag_color.a = sampleSpotShadow(pos.xyz, norm, 1, pos_screen); } diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl index 5c6fe30daa..64d99bae2c 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. @@ -34,290 +34,24 @@ out vec4 frag_color; //class 2 -- shadows and SSAO -uniform sampler2DRect depthMap; -uniform sampler2DRect normalMap; -uniform sampler2DShadow shadowMap0; -uniform sampler2DShadow shadowMap1; -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 vec2 shadow_res; - -uniform float shadow_bias; -uniform float shadow_offset; - -uniform float spot_shadow_bias; -uniform float spot_shadow_offset; - -vec2 encode_normal(vec3 n) -{ - float f = sqrt(8 * n.z + 8); - return n.xy / f + 0.5; -} - -vec3 decode_normal (vec2 enc) -{ - vec2 fenc = enc*4-2; - float f = dot(fenc,fenc); - float g = sqrt(1-f/4); - vec3 n; - n.xy = fenc*g; - n.z = 1-f/2; - return n; -} - -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]; -} - -//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; - - 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 pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen) -{ - 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; - 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 scl, vec2 pos_screen) -{ - stc.xyz /= stc.w; - stc.z += spot_shadow_bias*scl; - 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; +vec4 getPosition(vec2 pos_screen); +vec3 getNorm(vec2 pos_screen); - 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 shadow_pos, vec3 norm, vec2 pos_screen); +float sampleSpotShadow(vec3 shadow_pos, vec3 norm, int index, vec2 pos_screen); +float calcAmbientOcclusion(vec4 pos, vec3 norm, vec2 pos_screen); void main() { - vec2 pos_screen = vary_fragcoord.xy; - - //try doing an unproject here - - vec4 pos = getPosition(pos_screen); - - vec3 norm = texture2DRect(normalMap, pos_screen).xyz; - norm = decode_normal(norm.xy); // unpack norm - - /*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL - { - frag_color = vec4(0.0); // doesn't matter - return; - }*/ - - float shadow = 0.0; - float dp_directional_light = max(0.0, dot(norm, sun_dir.xyz)); - - vec3 shadow_pos = pos.xyz; - vec3 offset = sun_dir.xyz * (1.0-dp_directional_light); - - vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0); - - if (spos.z > -shadow_clip.w) - { - if (dp_directional_light == 0.0) - { - // if we know this point is facing away from the sun then we know it's in shadow without having to do a squirrelly shadow-map lookup - shadow = 0.0; - } - else - { - vec4 lpos; - - 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.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); - } - - 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.5, 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.75, 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; - - // take the most-shadowed value out of these two: - // * the blurred sun shadow in the light (shadow) map - // * an unblurred dot product between the sun and this norm - // the goal is to err on the side of most-shadow to fill-in shadow holes and reduce artifacting - shadow = min(shadow, dp_directional_light); - - //lpos.xy /= lpos.w*32.0; - //if (fract(lpos.x) < 0.1 || fract(lpos.y) < 0.1) - //{ - // shadow = 0.0; - //} - - } - } - else - { - // more distant than the shadow map covers - shadow = 1.0; - } - - frag_color[0] = shadow; - frag_color[1] = calcAmbientOcclusion(pos, norm); - - spos = vec4(shadow_pos+norm*spot_shadow_offset, 1.0); - - //spotlight shadow 1 - vec4 lpos = shadow_matrix[4]*spos; - frag_color[2] = pcfSpotShadow(shadowMap4, lpos, 0.8, pos_screen); - - //spotlight shadow 2 - lpos = shadow_matrix[5]*spos; - frag_color[3] = pcfSpotShadow(shadowMap5, lpos, 0.8, pos_screen); + vec2 pos_screen = vary_fragcoord.xy; + vec4 pos = getPosition(pos_screen); + vec3 norm = getNorm(pos_screen); - //frag_color.rgb = pos.xyz; - //frag_color.b = shadow; + frag_color.r = sampleDirectionalShadow(pos.xyz, norm, pos_screen); + frag_color.g = calcAmbientOcclusion(pos, norm, pos_screen); + frag_color.b = sampleSpotShadow(pos.xyz, norm, 0, pos_screen); + frag_color.a = sampleSpotShadow(pos.xyz, norm, 1, pos_screen); } |