summaryrefslogtreecommitdiff
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
commit61a47a0f626830cef6c430780f69b5c9ed2d321e (patch)
tree07cf4d3e3694037de2a2273056b8c4773cb69be6
parentfb830551d0fef66154ae6652ffaaab3fa3da2bd0 (diff)
screen-space reflections mk4. generally subtle. very cheap.
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl47
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl48
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl48
3 files changed, 119 insertions, 24 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);
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
index 589a292751..c5530c5f59 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
@@ -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,7 +256,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;
@@ -271,11 +277,37 @@ 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;
+ float refshad = texture2DRect(lightMap, ref2d).r;
+ 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 = min(max(dot(refn, vary_light.xyz), 0.0), refshad);
+ // 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);
diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
index 96a083b522..265fb437ec 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
@@ -56,9 +56,8 @@ vec3 vary_AdditiveColor;
vec3 vary_AtmosAttenuation;
uniform float gi_ambiance;
-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;
@@ -274,11 +280,37 @@ 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 refnorm = normalize(reflect(pos.xyz, norm.xyz));
+ float sa = dot(refnorm, vary_light.xyz);
+ vec3 dumbshiny = vary_SunlitColor*scol*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;
+ float refshad = texture2DRect(lightMap, ref2d).r;
+ 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 = min(max(dot(refn, vary_light.xyz), 0.0), refshad);
+ // 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);