summaryrefslogtreecommitdiff
path: root/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl')
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl86
1 files changed, 68 insertions, 18 deletions
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
index 531f7376a3..fd6ae2b960 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
@@ -11,6 +11,7 @@ uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
uniform sampler2DRect normalMap;
uniform sampler2DRect lightMap;
+uniform sampler2DRect depthMap;
uniform sampler2D noiseMap;
uniform samplerCube environmentMap;
uniform sampler2D lightFunc;
@@ -41,7 +42,6 @@ uniform vec3 env_mat[3];
uniform vec4 shadow_clip;
uniform mat3 ssao_effect_mat;
-uniform sampler2DRect depthMap;
uniform mat4 inv_proj;
uniform vec2 screen_res;
@@ -55,9 +55,8 @@ vec3 vary_AmblitColor;
vec3 vary_AdditiveColor;
vec3 vary_AtmosAttenuation;
-vec4 getPosition(vec2 pos_screen)
-{ //get position in screen space (world units) given window coordinate and depth map
- float depth = texture2DRect(depthMap, pos_screen.xy).a;
+vec4 getPosition_d(vec2 pos_screen, float depth)
+{
vec2 sc = pos_screen.xy*2.0;
sc /= screen_res;
sc -= vec2(1.0,1.0);
@@ -68,6 +67,12 @@ vec4 getPosition(vec2 pos_screen)
return pos;
}
+vec4 getPosition(vec2 pos_screen)
+{ //get position in screen space (world units) given window coordinate and depth map
+ float depth = texture2DRect(depthMap, pos_screen.xy).a;
+ return getPosition_d(pos_screen, depth);
+}
+
vec3 getPositionEye()
{
return vary_PositionEye;
@@ -251,8 +256,10 @@ vec3 scaleSoftClip(vec3 light)
void main()
{
vec2 tc = vary_fragcoord.xy;
- vec3 pos = getPosition(tc).xyz;
- vec3 norm = texture2DRect(normalMap, tc).xyz*2.0-1.0;
+ float depth = texture2DRect(depthMap, tc.xy).a;
+ vec3 pos = getPosition_d(tc, depth).xyz;
+ vec3 norm = texture2DRect(normalMap, tc).xyz;
+ norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
//vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz;
float da = max(dot(norm.xyz, vary_light.xyz), 0.0);
@@ -271,24 +278,67 @@ void main()
col *= diffuse.rgb;
- if (spec.a > 0.0)
+ if (spec.a > 0.0) // specular reflection
{
- vec3 ref = normalize(reflect(pos.xyz, norm.xyz));
- float sa = dot(ref, vary_light.xyz);
- col.rgb += vary_SunlitColor*scol*spec.rgb*texture2D(lightFunc, vec2(sa, spec.a)).a;
+ // the old infinite-sky shiny reflection
+ //
+ vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+ float sa = dot(refnormpersp, vary_light.xyz);
+ vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*texture2D(lightFunc, vec2(sa, spec.a)).a;
+
+ /*
+ // screen-space cheap fakey reflection map
+ //
+ vec3 refnorm = normalize(reflect(vec3(0,0,-1), norm.xyz));
+ depth -= 0.5; // unbias depth
+ // first figure out where we'll make our 2D guess from
+ vec2 ref2d = (0.25 * screen_res.y) * (refnorm.xy) * abs(refnorm.z) / depth;
+ // Offset the guess source a little according to a trivial
+ // checkerboard dither function and spec.a.
+ // This is meant to be similar to sampling a blurred version
+ // of the diffuse map. LOD would be better in that regard.
+ // The goal of the blur is to soften reflections in surfaces
+ // with low shinyness, and also to disguise our lameness.
+ float checkerboard = floor(mod(tc.x+tc.y, 2.0)); // 0.0, 1.0
+ float checkoffset = (3.0 + (7.0*(1.0-spec.a)))*(checkerboard-0.5);
+ ref2d += vec2(checkoffset, checkoffset);
+ ref2d += tc.xy; // use as offset from destination
+ // Get attributes from the 2D guess point.
+ // We average two samples of diffuse (not of anything else) per
+ // pixel to try to reduce aliasing some more.
+ vec3 refcol = 0.5 * (texture2DRect(diffuseRect, ref2d + vec2(0.0, -checkoffset)).rgb +
+ texture2DRect(diffuseRect, ref2d + vec2(-checkoffset, 0.0)).rgb);
+ float refdepth = texture2DRect(depthMap, ref2d).a;
+ vec3 refpos = getPosition_d(ref2d, refdepth).xyz;
+ float refshad = texture2DRect(lightMap, ref2d).r;
+ vec3 refn = texture2DRect(normalMap, ref2d).rgb;
+ refn = vec3((refn.xy-0.5)*2.0,refn.z); // unpack norm
+ refn = normalize(refn);
+ // figure out how appropriate our guess actually was
+ float refapprop = max(0.0, dot(-refnorm, normalize(pos - refpos)));
+ // darken reflections from points which face away from the reflected ray - our guess was a back-face
+ //refapprop *= step(dot(refnorm, refn), 0.0);
+ refapprop = min(refapprop, max(0.0, -dot(refnorm, refn))); // more conservative variant
+ // get appropriate light strength for guess-point
+ // reflect light direction to increase the illusion that
+ // these are reflections.
+ vec3 reflight = reflect(lightnorm.xyz, norm.xyz);
+ float reflit = min(max(dot(refn, reflight.xyz), 0.0), refshad);
+ // apply sun color to guess-point, dampen according to inappropriateness of guess
+ float refmod = min(refapprop, reflit);
+ vec3 refprod = vary_SunlitColor * refcol.rgb * refmod;
+ vec3 ssshiny = (refprod * spec.a);
+ ssshiny *= 0.3; // dampen it even more
+ */
+ vec3 ssshiny = vec3(0,0,0);
+
+ // add the two types of shiny together
+ col += (ssshiny + dumbshiny) * spec.rgb;
}
col = atmosLighting(col);
col = scaleSoftClip(col);
gl_FragColor.rgb = col;
-
- //gl_FragColor.rgb = gi_col.rgb;
gl_FragColor.a = 0.0;
-
- //gl_FragColor.rg = scol_ambocc.rg;
- //gl_FragColor.rgb = texture2DRect(lightMap, vary_fragcoord.xy).rgb;
- //gl_FragColor.rgb = norm.rgb*0.5+0.5;
- //gl_FragColor.rgb = vec3(ambocc);
- //gl_FragColor.rgb = vec3(scol);
}