summaryrefslogtreecommitdiff
path: root/indra/newview/app_settings/shaders/class1
diff options
context:
space:
mode:
authorTofu Linden <tofu.linden@lindenlab.com>2010-03-22 16:10:34 +0000
committerTofu Linden <tofu.linden@lindenlab.com>2010-03-22 16:10:34 +0000
commit28618d0d3bf93790cc70da247c2a723df0778b05 (patch)
tree4bfd0e7b32fa8f726f13ec4f608edff14b19a2db /indra/newview/app_settings/shaders/class1
parentb767f2a5d5c61e01b0eb270f951fb2e6c98dbdd4 (diff)
screen-space reflections mk4. generally subtle. very cheap.
Diffstat (limited to 'indra/newview/app_settings/shaders/class1')
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl47
1 files changed, 39 insertions, 8 deletions
diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
index 9cf60aad48..7d57eaa13d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
@@ -56,9 +56,8 @@ vec3 vary_AtmosAttenuation;
uniform mat4 inv_proj;
uniform vec2 screen_res;
-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);
@@ -69,6 +68,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;
@@ -252,7 +257,8 @@ vec3 scaleSoftClip(vec3 light)
void main()
{
vec2 tc = vary_fragcoord.xy;
- vec3 pos = getPosition(tc).xyz;
+ float depth = texture2DRect(depthMap, tc.xy).a;
+ vec3 pos = getPosition_d(tc, depth).xyz;
vec3 norm = texture2DRect(normalMap, tc).xyz*2.0-1.0;
//vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz;
@@ -272,11 +278,36 @@ 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_ambocc.r*spec.rgb*texture2D(lightFunc, vec2(sa, spec.a)).a;
+ // the old infinite-sky shiny reflection
+ //
+ vec3 refnorm = normalize(reflect(pos.xyz, norm.xyz));
+ float sa = dot(refnorm, vary_light.xyz);
+ vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*texture2D(lightFunc, vec2(sa, spec.a)).a;
+
+ // screen-space cheap fakey reflection map
+ //
+ // first figure out where we'll make our 2D guess from
+ vec2 ref2d = tc.xy + (0.5 * screen_res.y) * (refnorm.xy) * abs(refnorm.z) / depth;
+ // get attributes from the 2D guess point
+ float refdepth = texture2DRect(depthMap, ref2d).a;
+ vec3 refpos = getPosition_d(ref2d, refdepth).xyz;
+ vec3 refcol = texture2DRect(diffuseRect, ref2d).rgb;
+ vec3 refn = normalize(texture2DRect(normalMap, ref2d).rgb * 2.0 - 1.0);
+ // 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
+ float reflit = max(dot(refn, vary_light.xyz), 0.0);
+ // apply sun color to guess-point, dampen according to inappropriateness of guess
+ vec3 refprod = (vary_SunlitColor*reflit) * refcol.rgb * refapprop;
+ vec3 ssshiny = (refprod * spec.a);
+
+ // add the two types of shiny together
+ col += (ssshiny + dumbshiny) * spec.rgb;
}
col = atmosLighting(col);