diff options
Diffstat (limited to 'indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl')
-rwxr-xr-x | indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl | 108 |
1 files changed, 93 insertions, 15 deletions
diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl index 6d6ad6d565..fc0e6b2388 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl @@ -39,6 +39,7 @@ uniform samplerCube environmentMap; uniform sampler2DRect lightMap; uniform sampler2D noiseMap; uniform sampler2D projectionMap; +uniform sampler2D lightFunc; uniform mat4 proj_mat; //screen space to light space uniform float proj_near; //near clip for projection @@ -67,9 +68,49 @@ uniform vec2 screen_res; uniform mat4 inv_proj; +#ifdef SINGLE_FP_ONLY +vec2 encode_normal(vec3 n) +{ + vec2 sn; + sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); + return sn; +} + +vec3 decode_normal (vec2 enc) +{ + vec3 n; + n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); + n.z = sqrt(1.0f - dot(n.xy,n.xy)); + return n; +} +#else +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; +} +#endif + +vec4 correctWithGamma(vec4 col) +{ + return vec4(pow(col.rgb, vec3(2.2)), col.a); +} + vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod) { vec4 ret = texture2DLod(projectionMap, tc, lod); + ret = correctWithGamma(ret); vec2 dist = tc-vec2(0.5); @@ -85,6 +126,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); vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); @@ -102,6 +144,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); vec2 dist = tc-vec2(0.5); @@ -135,9 +178,9 @@ void main() vec3 pos = getPosition(frag.xy).xyz; vec3 lv = trans_center.xyz-pos.xyz; - float dist2 = dot(lv,lv); - dist2 /= size; - if (dist2 > 1.0) + float dist = length(lv); + dist /= size; + if (dist > 1.0) { discard; } @@ -154,7 +197,8 @@ void main() } vec3 norm = texture2DRect(normalMap, frag.xy).xyz; - norm = (norm.xyz-0.5)*2.0; // unpack norm + float envIntensity = norm.z; + norm = decode_normal(norm.xy); norm = normalize(norm); float l_dist = -dot(lv, proj_n); @@ -168,7 +212,10 @@ void main() proj_tc.xyz /= proj_tc.w; float fa = falloff+1.0; - float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 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; @@ -182,6 +229,10 @@ void main() 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 && @@ -189,21 +240,21 @@ void main() proj_tc.x > 0.0 && proj_tc.y > 0.0) { - float lit = 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); - vec3 lcol = color.rgb * plcol.rgb * plcol.a; - - lit = da * dist_atten * noise; + dlit = color.rgb * plcol.rgb * plcol.a; - col = lcol*lit*diff_tex*shadow; + col = dlit*lit*diff_tex*shadow; amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance; } @@ -219,10 +270,37 @@ void main() col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; } - - vec4 spec = texture2DRect(specularRect, frag.xy); + if (spec.a > 0.0) { + dlit *= min(da*6.0, 1.0) * dist_atten; + vec3 npos = -normalize(pos); + + //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 @@ -239,8 +317,9 @@ void main() { stc.xy /= stc.w; - float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0); + float fatten = clamp(envIntensity*envIntensity+envIntensity*0.5, 0.25, 1.0); + //stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); if (stc.x < 1.0 && @@ -248,8 +327,7 @@ void main() stc.x > 0.0 && stc.y > 0.0) { - vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); - col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb*shadow; + col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod-envIntensity*proj_lod).rgb*shadow*spec.rgb; } } } |