From 4ee4d52b2f49f856c08c6e80ed214a32eab5590a Mon Sep 17 00:00:00 2001 From: Shyotl Date: Tue, 24 May 2011 20:31:17 -0500 Subject: [PATCH] Added bokeh DoF. Fixed some several SSAO and shadow combinations. Fixed GI crash bug. Enabled several fasttimers. Updated shaders. --- indra/llcommon/llfasttimer.h | 18 +- indra/newview/app_settings/settings.xml | 59 +++ .../shaders/class1/deferred/avatarAlphaF.glsl | 68 ---- .../shaders/class1/deferred/avatarAlphaV.glsl | 64 ++- .../shaders/class1/deferred/blurLightF.glsl | 36 +- .../class1/deferred/postDeferredF.glsl | 146 +++++-- .../shaders/class1/deferred/softenLightF.glsl | 5 - .../deferred/softenLightNoSSAOF.glsl} | 35 +- .../class1/deferred/sunLightSSAOF.glsl | 76 ++-- .../shaders/class2/deferred/avatarAlphaF.glsl | 98 ----- .../shaders/class2/deferred/avatarAlphaV.glsl | 53 ++- .../shaders/class2/deferred/blurLightF.glsl | 81 ---- .../shaders/class2/deferred/blurLightV.glsl | 17 - .../class2/deferred/postDeferredF.glsl | 59 --- .../class2/deferred/postDeferredV.glsl | 17 - .../class2/deferred/sunLightSSAOF.glsl | 63 ++- .../shaders/class3/deferred/softenLightF.glsl | 4 +- indra/newview/llfasttimerview.cpp | 13 + indra/newview/llviewershadermgr.cpp | 38 +- indra/newview/llviewershadermgr.h | 1 + indra/newview/pipeline.cpp | 372 +++++++++++++----- 21 files changed, 692 insertions(+), 631 deletions(-) delete mode 100644 indra/newview/app_settings/shaders/class1/deferred/avatarAlphaF.glsl rename indra/newview/app_settings/shaders/{class2/deferred/softenLightF.glsl => class1/deferred/softenLightNoSSAOF.glsl} (92%) delete mode 100644 indra/newview/app_settings/shaders/class2/deferred/avatarAlphaF.glsl delete mode 100644 indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl delete mode 100644 indra/newview/app_settings/shaders/class2/deferred/blurLightV.glsl delete mode 100644 indra/newview/app_settings/shaders/class2/deferred/postDeferredF.glsl delete mode 100644 indra/newview/app_settings/shaders/class2/deferred/postDeferredV.glsl diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index 5cb654a46..d46250b1b 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -107,7 +107,23 @@ public: FTM_RENDER_BLOOM, FTM_RENDER_BLOOM_FBO, FTM_RENDER_FONTS, - + + // deferred rendering + FTM_RENDER_DEFERRED, + FTM_BIND_DEFERRED, + FTM_SUN_SHADOW, + FTM_SOFTEN_SHADOW, + FTM_EDGE_DETECTION, + FTM_GI_TRACE, + FTM_GI_GATHER, + FTM_ATMOSPHERICS, + FTM_LOCAL_LIGHTS, + FTM_FULLSCREEN_LIGHTS, + FTM_PROJECTORS, + FTM_POST, + + FTM_VISIBLE_CLOUD, + // newview specific FTM_MESSAGES, FTM_MOUSEHANDLER, diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 44f05bd68..145247144 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -2654,6 +2654,65 @@ Value 1.0 + CameraFocusTransitionTime + + Comment + How many seconds it takes the camera to transition between focal distances + Persist + 1 + Type + F32 + Value + 0.5 + + + CameraFNumber + + Comment + Camera f-number value for DoF effect + Persist + 1 + Type + F32 + Value + 9.0 + + + CameraFocalLength + + Comment + Camera focal length for DoF effect (in millimeters) + Persist + 1 + Type + F32 + Value + 50 + + + CameraFieldOfView + + Comment + Vertical camera field of view for DoF effect (in degrees) + Persist + 1 + Type + F32 + Value + 60.0 + + + CameraAspectRatio + + Comment + Camera aspect ratio for DoF effect + Persist + 1 + Type + F32 + Value + 1.5 + ChatBarStealsFocus Comment diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaF.glsl deleted file mode 100644 index ff64a6b0c..000000000 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaF.glsl +++ /dev/null @@ -1,68 +0,0 @@ -/** - * @file avatarAlphaF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -uniform sampler2D diffuseMap; -uniform sampler2DShadow shadowMap0; -uniform sampler2DShadow shadowMap1; -uniform sampler2DShadow shadowMap2; -uniform sampler2DShadow shadowMap3; -uniform sampler2D noiseMap; - -uniform mat4 shadow_matrix[6]; -uniform vec4 shadow_clip; - -vec3 atmosLighting(vec3 light); -vec3 scaleSoftClip(vec3 light); - -varying vec3 vary_ambient; -varying vec3 vary_directional; -varying vec4 vary_position; -varying vec3 vary_normal; - -void main() -{ - float shadow = 1.0; - vec4 pos = vary_position; - vec3 norm = normalize(vary_normal); - - vec3 nz = texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz; - - if (pos.z > -shadow_clip.w) - { - - if (pos.z < -shadow_clip.z) - { - vec4 lpos = shadow_matrix[3]*pos; - shadow = shadow2DProj(shadowMap3, lpos).x; - } - else if (pos.z < -shadow_clip.y) - { - vec4 lpos = shadow_matrix[2]*pos; - shadow = shadow2DProj(shadowMap2, lpos).x; - } - else if (pos.z < -shadow_clip.x) - { - vec4 lpos = shadow_matrix[1]*pos; - shadow = shadow2DProj(shadowMap1, lpos).x; - } - else - { - vec4 lpos = shadow_matrix[0]*pos; - shadow = shadow2DProj(shadowMap0, lpos).x; - } - } - - - vec4 col = vec4(vary_ambient + vary_directional*shadow, gl_Color.a); - vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * col; - - color.rgb = atmosLighting(color.rgb); - - color.rgb = scaleSoftClip(color.rgb); - - gl_FragColor = color; -} diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl index 7fc763fa0..616990560 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl @@ -19,10 +19,38 @@ vec3 atmosAffectDirectionalLight(float lightIntensity); vec3 scaleDownLight(vec3 light); vec3 scaleUpLight(vec3 light); -varying vec4 vary_position; +varying vec3 vary_position; varying vec3 vary_ambient; varying vec3 vary_directional; -varying vec3 vary_normal; +varying vec3 vary_fragcoord; +varying vec3 vary_pointlight_col; + +uniform float near_clip; + +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) +{ + //get light vector + vec3 lv = lp.xyz-v; + + //get distance + float d = length(lv); + + //normalize light vector + lv *= 1.0/d; + + //distance attenuation + float dist2 = d*d/(la*la); + float da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); + + // spotlight coefficient. + float spot = max(dot(-ln, lv), is_pointlight); + da *= spot*spot; // GL_SPOT_EXPONENT=2 + + //angular attenuation + da *= calcDirectionalLight(n, lv); + + return da; +} void main() { @@ -42,9 +70,10 @@ void main() norm.z = dot(trans[2].xyz, gl_Normal); norm = normalize(norm); - gl_Position = gl_ProjectionMatrix * pos; - vary_position = pos; - vary_normal = norm; + vec4 frag_pos = gl_ProjectionMatrix * pos; + gl_Position = frag_pos; + + vary_position = pos.xyz; calcAtmospherics(pos.xyz); @@ -52,18 +81,20 @@ void main() vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a); - // Collect normal lights (need to be divided by two, as we later multiply by 2) - col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a); - col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a); - col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a); - col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].specular.a); - col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].specular.a); - col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].specular.a); - col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz); - col.rgb = scaleDownLight(col.rgb); + // Collect normal lights + col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].quadraticAttenuation, gl_LightSource[2].specular.a); + col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].quadraticAttenuation ,gl_LightSource[3].specular.a); + col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].quadraticAttenuation, gl_LightSource[4].specular.a); + col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].quadraticAttenuation, gl_LightSource[5].specular.a); + col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].quadraticAttenuation, gl_LightSource[6].specular.a); + col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].quadraticAttenuation, gl_LightSource[7].specular.a); + vary_pointlight_col = col.rgb*gl_Color.rgb; + + col.rgb = vec3(0,0,0); + // Add windlight lights - col.rgb += atmosAmbient(vec3(0.)); + col.rgb = atmosAmbient(vec3(0.)); vary_ambient = col.rgb*gl_Color.rgb; vary_directional = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a))); @@ -73,7 +104,8 @@ void main() gl_FrontColor = col; gl_FogFragCoord = pos.z; - + + vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl index 6e732fa54..d04bfb3ad 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl @@ -39,44 +39,50 @@ vec4 getPosition(vec2 pos_screen) void main() { - vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz; + vec2 tc = vary_fragcoord.xy; + vec3 norm = texture2DRect(normalMap, tc).xyz; norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm - vec3 pos = getPosition(vary_fragcoord.xy).xyz; - vec4 ccol = texture2DRect(lightMap, vary_fragcoord.xy).rgba; + vec3 pos = getPosition(tc).xyz; + vec4 ccol = texture2DRect(lightMap, tc).rgba; vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy); - dlt /= max(-pos.z*dist_factor, 1.0); vec2 defined_weight = kern[0].xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free' vec4 col = defined_weight.xyxx * ccol; - + + // relax tolerance according to distance to avoid speckling artifacts, as angles and distances are a lot more abrupt within a small screen area at larger distances + float pointplanedist_tolerance_pow2 = pos.z*pos.z*0.00005; + + // perturb sampling origin slightly in screen-space to hide edge-ghosting artifacts where smoothing radius is quite large + //This causes some pretty nasty artifacting, so disabling for now. + //tc += ( (mod(tc.x+tc.y,2) - 0.5) * kern[1].z * dlt * 0.5 ); + for (int i = 1; i < 4; i++) { - vec2 tc = vary_fragcoord.xy + kern[i].z*dlt; - vec3 samppos = getPosition(tc).xyz; + vec2 samptc = tc + kern[i].z*dlt; + vec3 samppos = getPosition(samptc).xyz; float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane - if (d*d <= 0.003) + if (d*d <= pointplanedist_tolerance_pow2) { - col += texture2DRect(lightMap, tc)*kern[i].xyxx; + col += texture2DRect(lightMap, samptc)*kern[i].xyxx; defined_weight += kern[i].xy; } } for (int i = 1; i < 4; i++) { - vec2 tc = vary_fragcoord.xy - kern[i].z*dlt; - vec3 samppos = getPosition(tc).xyz; + vec2 samptc = tc - kern[i].z*dlt; + vec3 samppos = getPosition(samptc).xyz; float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane - if (d*d <= 0.003) + if (d*d <= pointplanedist_tolerance_pow2) { - col += texture2DRect(lightMap, tc)*kern[i].xyxx; + col += texture2DRect(lightMap, samptc)*kern[i].xyxx; defined_weight += kern[i].xy; } } - - col /= defined_weight.xyxx; + col.y *= col.y; gl_FragColor = col; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl index 7e41b07f8..77f1b2224 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl @@ -10,50 +10,128 @@ #extension GL_ARB_texture_rectangle : enable uniform sampler2DRect diffuseRect; -uniform sampler2DRect localLightMap; -uniform sampler2DRect sunLightMap; -uniform sampler2DRect giLightMap; -uniform sampler2D luminanceMap; -uniform sampler2DRect lightMap; +uniform sampler2DRect edgeMap; +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform sampler2D bloomMap; -uniform vec3 lum_quad; -uniform float lum_lod; -uniform vec4 ambient; - -uniform vec3 gi_quad; +uniform float depth_cutoff; +uniform float norm_cutoff; +uniform float focal_distance; +uniform float blur_constant; +uniform float tan_pixel_angle; +uniform float magnification; +uniform mat4 inv_proj; uniform vec2 screen_res; + varying vec2 vary_fragcoord; +float getDepth(vec2 pos_screen) +{ + float z = texture2DRect(depthMap, pos_screen.xy).a; + z = z*2.0-1.0; + vec4 ndc = vec4(0.0, 0.0, z, 1.0); + vec4 p = inv_proj*ndc; + return p.z/p.w; +} + +float calc_cof(float depth) +{ + float sc = abs(depth-focal_distance)/-depth*blur_constant; + + sc /= magnification; + + // tan_pixel_angle = pixel_length/-depth; + float pixel_length = tan_pixel_angle*-focal_distance; + + sc = sc/pixel_length; + sc *= 1.414; + + return sc; +} + +void dofSampleNear(inout vec4 diff, inout float w, float cur_sc, vec2 tc) +{ + float d = getDepth(tc); + + float sc = calc_cof(d); + + float wg = 0.25; + + vec4 s = texture2DRect(diffuseRect, tc); + // de-weight dull areas to make highlights 'pop' + wg += s.r+s.g+s.b; + + diff += wg*s; + + w += wg; +} + +void dofSample(inout vec4 diff, inout float w, float min_sc, float cur_depth, vec2 tc) +{ + float d = getDepth(tc); + + float sc = calc_cof(d); + + if (sc > min_sc //sampled pixel is more "out of focus" than current sample radius + || d < cur_depth) //sampled pixel is further away than current pixel + { + float wg = 0.25; + + vec4 s = texture2DRect(diffuseRect, tc); + // de-weight dull areas to make highlights 'pop' + wg += s.r+s.g+s.b; + + diff += wg*s; + + w += wg; + } +} + + void main() { + vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz; + norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + vec2 tc = vary_fragcoord.xy; - vec3 lum = texture2DLod(luminanceMap, tc/screen_res, lum_lod).rgb; - float luminance = lum.r; - luminance = luminance*lum_quad.y+lum_quad.z; - + + float depth = getDepth(tc); + vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy); + + { + float w = 1.0; + + float sc = calc_cof(depth); + sc = min(abs(sc), 10.0); + + float fd = depth*0.5f; + + float PI = 3.14159265358979323846264; - float ambocc = texture2DRect(lightMap, vary_fragcoord.xy).g; - - vec3 gi_col = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; - gi_col = gi_col*gi_col*gi_quad.x + gi_col*gi_quad.y+gi_quad.z*ambocc*ambient.rgb; - gi_col *= diff; - - vec4 sun_col = texture2DRect(sunLightMap, vary_fragcoord.xy); - - vec3 local_col = texture2DRect(localLightMap, vary_fragcoord.xy).rgb; + // sample quite uniformly spaced points within a circle, for a circular 'bokeh' + //if (depth < focal_distance) + { + while (sc > 0.5) + { + int its = int(max(1.0,(sc*3.7))); + for (int i=0; i 0.0) // specular reflection @@ -288,7 +284,6 @@ void main() 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 // diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightNoSSAOF.glsl similarity index 92% rename from indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl rename to indra/newview/app_settings/shaders/class1/deferred/softenLightNoSSAOF.glsl index 0160e8427..bca692cab 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightNoSSAOF.glsl @@ -1,8 +1,8 @@ /** * @file softenLightF.glsl * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * $/LicenseInfo$ + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ */ #version 120 @@ -12,12 +12,8 @@ uniform sampler2DRect diffuseRect; uniform sampler2DRect specularRect; uniform sampler2DRect normalMap; -uniform sampler2DRect lightMap; uniform sampler2DRect depthMap; -uniform sampler2D noiseMap; -uniform samplerCube environmentMap; uniform sampler2D lightFunc; -uniform vec3 gi_quad; uniform float blur_size; uniform float blur_fidelity; @@ -41,12 +37,10 @@ uniform vec4 max_y; uniform vec4 glow; uniform float scene_light_strength; uniform vec3 env_mat[3]; -uniform vec4 shadow_clip; +//uniform mat4 shadow_matrix[3]; +//uniform vec4 shadow_clip; uniform mat3 ssao_effect_mat; -uniform mat4 inv_proj; -uniform vec2 screen_res; - varying vec4 vary_light; varying vec2 vary_fragcoord; @@ -57,6 +51,9 @@ vec3 vary_AmblitColor; vec3 vary_AdditiveColor; vec3 vary_AtmosAttenuation; +uniform mat4 inv_proj; +uniform vec2 screen_res; + vec4 getPosition_d(vec2 pos_screen, float depth) { vec2 sc = pos_screen.xy*2.0; @@ -269,14 +266,10 @@ void main() vec4 diffuse = texture2DRect(diffuseRect, tc); vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); - vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg; - float scol = max(scol_ambocc.r, diffuse.a); - float ambocc = scol_ambocc.g; - - calcAtmospherics(pos.xyz, ambocc); + calcAtmospherics(pos.xyz, 1.0); vec3 col = atmosAmbient(vec3(0)); - col += atmosAffectDirectionalLight(max(min(da, scol), diffuse.a)); + col += atmosAffectDirectionalLight(max(min(da, 1.0), diffuse.a)); col *= diffuse.rgb; @@ -286,7 +279,7 @@ void main() // 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; + vec3 dumbshiny = vary_SunlitColor*texture2D(lightFunc, vec2(sa, spec.a)).a; /* // screen-space cheap fakey reflection map @@ -312,20 +305,18 @@ void main() 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); + refn = normalize(vec3((refn.xy-0.5)*2.0,refn.z)); // unpack norm // 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 + // 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); + float reflit = max(dot(refn, reflight.xyz), 0.0); // apply sun color to guess-point, dampen according to inappropriateness of guess float refmod = min(refapprop, reflit); vec3 refprod = vary_SunlitColor * refcol.rgb * refmod; diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl index 3c936251f..cd91351ad 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl @@ -51,57 +51,49 @@ float calcAmbientOcclusion(vec4 pos, vec3 norm) { float ret = 1.0; - float dist = dot(pos.xyz,pos.xyz); - - if (dist < 64.0*64.0) - { - 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; + 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; - vec2 pos_screen = vary_fragcoord.xy; - vec3 pos_world = pos.xyz; - vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy; + 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; - int points = 0; + float angle_hidden = 0.0; + int points = 0; - float scale = min(ssao_radius / -pos_world.z, ssao_max_radius); + 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(kern[i], noise_reflect); - vec3 samppos_world = getPosition(samppos_screen).xyz; + // 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(kern[i], noise_reflect); + vec3 samppos_world = getPosition(samppos_screen).xyz; - vec3 diff = pos_world - samppos_world; - float dist2 = dot(diff, diff); + 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) + // 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) - //if (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) // -0.05*norm to shift sample point back slightly for flat surfaces - // angle_hidden += min(1.0/dist2, ssao_factor_inv); // dist != 0 follows from conditional. max of 1.0 (= ssao_factor_inv * ssao_factor) - angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv); + angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv); - // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion" - points = points + int(diff.z > -1.0); - } - - angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0); - - ret = (1.0 - (float(points != 0) * angle_hidden)); - ret += max((dist-32.0*32.0)/(32.0*32.0), 0.0); + // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion" + points = points + int(diff.z > -1.0); } + + angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0); + + ret = (1.0 - (float(points != 0) * angle_hidden)); return min(ret, 1.0); } diff --git a/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaF.glsl deleted file mode 100644 index 5ecbbd2c4..000000000 --- a/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaF.glsl +++ /dev/null @@ -1,98 +0,0 @@ -/** - * @file avatarAlphaF.glsl - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * $/LicenseInfo$ - */ - -#extension GL_ARB_texture_rectangle : enable - -uniform sampler2D diffuseMap; -uniform sampler2DRectShadow shadowMap0; -uniform sampler2DRectShadow shadowMap1; -uniform sampler2DRectShadow shadowMap2; -uniform sampler2DRectShadow shadowMap3; -uniform sampler2D noiseMap; - -uniform mat4 shadow_matrix[6]; -uniform vec4 shadow_clip; -uniform vec2 screen_res; -uniform vec2 shadow_res; - -vec3 atmosLighting(vec3 light); -vec3 scaleSoftClip(vec3 light); - -varying vec3 vary_ambient; -varying vec3 vary_directional; -varying vec3 vary_position; -varying vec3 vary_normal; - -uniform float shadow_bias; - -float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl) -{ - stc.xyz /= stc.w; - stc.z += shadow_bias; - - float cs = shadow2DRect(shadowMap, stc.xyz).x; - float shadow = cs; - - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(scl, scl, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(scl, -scl, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-scl, scl, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-scl, -scl, 0.0)).x, cs); - - return shadow/5.0; -} - -void main() -{ - float shadow = 1.0; - vec4 pos = vec4(vary_position, 1.0); - vec3 norm = normalize(vary_normal); - - //vec3 nz = texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz; - - vec4 spos = pos; - - if (spos.z > -shadow_clip.w) - { - vec4 lpos; - - if (spos.z < -shadow_clip.z) - { - lpos = shadow_matrix[3]*spos; - lpos.xy *= shadow_res; - shadow = pcfShadow(shadowMap3, lpos, 1.5); - shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); - } - else if (spos.z < -shadow_clip.y) - { - lpos = shadow_matrix[2]*spos; - lpos.xy *= shadow_res; - shadow = pcfShadow(shadowMap2, lpos, 1.5); - } - else if (spos.z < -shadow_clip.x) - { - lpos = shadow_matrix[1]*spos; - lpos.xy *= shadow_res; - shadow = pcfShadow(shadowMap1, lpos, 1.5); - } - else - { - lpos = shadow_matrix[0]*spos; - lpos.xy *= shadow_res; - shadow = pcfShadow(shadowMap0, lpos, 1.5); - } - } - - - vec4 col = vec4(vary_ambient + vary_directional*shadow, gl_Color.a); - vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * col; - - color.rgb = atmosLighting(color.rgb); - - color.rgb = scaleSoftClip(color.rgb); - - gl_FragColor = color; -} diff --git a/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl index 43a554b47..495e86c8d 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl @@ -22,12 +22,38 @@ vec3 scaleUpLight(vec3 light); varying vec3 vary_position; varying vec3 vary_ambient; varying vec3 vary_directional; -varying vec3 vary_normal; +varying vec3 vary_fragcoord; +varying vec3 vary_pointlight_col; uniform float near_clip; uniform float shadow_offset; uniform float shadow_bias; +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) +{ + //get light vector + vec3 lv = lp.xyz-v; + + //get distance + float d = length(lv); + + //normalize light vector + lv *= 1.0/d; + + //distance attenuation + float dist2 = d*d/(la*la); + float da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); + + // spotlight coefficient. + float spot = max(dot(-ln, lv), is_pointlight); + da *= spot*spot; // GL_SPOT_EXPONENT=2 + + //angular attenuation + da *= calcDirectionalLight(n, lv); + + return da; +} + void main() { gl_TexCoord[0] = gl_MultiTexCoord0; @@ -50,7 +76,6 @@ void main() float dp_directional_light = max(0.0, dot(norm, gl_LightSource[0].position.xyz)); vary_position = pos.xyz + gl_LightSource[0].position.xyz * (1.0-dp_directional_light)*shadow_offset; - vary_normal = norm; calcAtmospherics(pos.xyz); @@ -58,18 +83,20 @@ void main() vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a); - // Collect normal lights (need to be divided by two, as we later multiply by 2) - col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a); - col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a); - col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a); - col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].specular.a); - col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].specular.a); - col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].specular.a); - col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz); - col.rgb = scaleDownLight(col.rgb); + // Collect normal lights + col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].quadraticAttenuation, gl_LightSource[2].specular.a); + col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].quadraticAttenuation ,gl_LightSource[3].specular.a); + col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].quadraticAttenuation, gl_LightSource[4].specular.a); + col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].quadraticAttenuation, gl_LightSource[5].specular.a); + col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].quadraticAttenuation, gl_LightSource[6].specular.a); + col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].quadraticAttenuation, gl_LightSource[7].specular.a); + vary_pointlight_col = col.rgb*gl_Color.rgb; + + col.rgb = vec3(0,0,0); + // Add windlight lights - col.rgb += atmosAmbient(vec3(0.)); + col.rgb = atmosAmbient(vec3(0.)); vary_ambient = col.rgb*gl_Color.rgb; vary_directional = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a))); @@ -79,7 +106,7 @@ void main() gl_FrontColor = col; gl_FogFragCoord = pos.z; - + vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip); } diff --git a/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl deleted file mode 100644 index 258a9b7c4..000000000 --- a/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl +++ /dev/null @@ -1,81 +0,0 @@ -/** - * @file blurLightF.glsl - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * $/LicenseInfo$ - */ - -#extension GL_ARB_texture_rectangle : enable - -uniform sampler2DRect depthMap; -uniform sampler2DRect normalMap; -uniform sampler2DRect lightMap; - -uniform float dist_factor; -uniform float blur_size; -uniform vec2 delta; -uniform vec3 kern[4]; -uniform float kern_scale; - -varying vec2 vary_fragcoord; - -uniform mat4 inv_proj; -uniform vec2 screen_res; - -vec4 getPosition(vec2 pos_screen) -{ - float depth = texture2DRect(depthMap, pos_screen.xy).a; - 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; -} - -void main() -{ - vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm - vec3 pos = getPosition(vary_fragcoord.xy).xyz; - vec4 ccol = texture2DRect(lightMap, vary_fragcoord.xy).rgba; - - vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy); - - dlt /= max(-pos.z*dist_factor, 1.0); - - vec2 defined_weight = kern[0].xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free' - vec4 col = defined_weight.xyxx * ccol; - - for (int i = 1; i < 4; i++) - { - vec2 tc = vary_fragcoord.xy + kern[i].z*dlt; - vec3 samppos = getPosition(tc).xyz; - float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane - if (d*d <= 0.003) - { - col += texture2DRect(lightMap, tc)*kern[i].xyxx; - defined_weight += kern[i].xy; - } - } - for (int i = 1; i < 4; i++) - { - vec2 tc = vary_fragcoord.xy - kern[i].z*dlt; - vec3 samppos = getPosition(tc).xyz; - float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane - if (d*d <= 0.003) - { - col += texture2DRect(lightMap, tc)*kern[i].xyxx; - defined_weight += kern[i].xy; - } - } - - - - col /= defined_weight.xyxx; - - gl_FragColor = col; -} - diff --git a/indra/newview/app_settings/shaders/class2/deferred/blurLightV.glsl b/indra/newview/app_settings/shaders/class2/deferred/blurLightV.glsl deleted file mode 100644 index b1b3f55f0..000000000 --- a/indra/newview/app_settings/shaders/class2/deferred/blurLightV.glsl +++ /dev/null @@ -1,17 +0,0 @@ -/** - * @file blurLightF.glsl - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * $/LicenseInfo$ - */ - -varying vec2 vary_fragcoord; -uniform vec2 screen_res; - -void main() -{ - //transform vertex - gl_Position = ftransform(); - vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; - vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; -} diff --git a/indra/newview/app_settings/shaders/class2/deferred/postDeferredF.glsl b/indra/newview/app_settings/shaders/class2/deferred/postDeferredF.glsl deleted file mode 100644 index 757e3e7aa..000000000 --- a/indra/newview/app_settings/shaders/class2/deferred/postDeferredF.glsl +++ /dev/null @@ -1,59 +0,0 @@ -/** - * @file postDeferredF.glsl - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * $/LicenseInfo$ - */ - -uniform sampler2DRect diffuseRect; -uniform sampler2DRect localLightMap; -uniform sampler2DRect sunLightMap; -uniform sampler2DRect giLightMap; -uniform sampler2D luminanceMap; -uniform sampler2DRect lightMap; - -uniform vec3 gi_lum_quad; -uniform vec3 sun_lum_quad; -uniform vec3 lum_quad; -uniform float lum_lod; -uniform vec4 ambient; - -uniform vec3 gi_quad; - -uniform vec2 screen_res; -varying vec2 vary_fragcoord; - -void main() -{ - vec2 tc = vary_fragcoord.xy; - vec3 lcol = texture2DLod(luminanceMap, tc/screen_res, lum_lod).rgb; - - float lum = sqrt(lcol.r)*lum_quad.x+lcol.r*lcol.r*lum_quad.y+lcol.r*lum_quad.z; - - vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy); - - float ambocc = texture2DRect(lightMap, vary_fragcoord.xy).g; - - vec3 gi_col = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; - gi_col = gi_col*gi_col*gi_quad.x + gi_col*gi_quad.y+gi_quad.z*ambocc*ambient.rgb; - gi_col *= diff; - - vec4 sun_col = texture2DRect(sunLightMap, vary_fragcoord.xy); - - vec3 local_col = texture2DRect(localLightMap, vary_fragcoord.xy).rgb; - - - float sun_lum = 1.0-lum; - sun_lum = sun_lum*sun_lum*sun_lum_quad.x + sun_lum*sun_lum_quad.y+sun_lum_quad.z; - - float gi_lum = lum; - gi_lum = gi_lum*gi_lum*gi_lum_quad.x+gi_lum*gi_lum_quad.y+gi_lum_quad.z; - gi_col *= 1.0/gi_lum; - - vec3 col = sun_col.rgb*(1.0+max(sun_lum,0.0))+gi_col+local_col; - - gl_FragColor.rgb = col.rgb; - gl_FragColor.a = max(sun_lum*min(sun_col.r+sun_col.g+sun_col.b, 1.0), sun_col.a); - - //gl_FragColor.rgb = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; -} diff --git a/indra/newview/app_settings/shaders/class2/deferred/postDeferredV.glsl b/indra/newview/app_settings/shaders/class2/deferred/postDeferredV.glsl deleted file mode 100644 index 0ec81dcb0..000000000 --- a/indra/newview/app_settings/shaders/class2/deferred/postDeferredV.glsl +++ /dev/null @@ -1,17 +0,0 @@ -/** - * @file postDeferredV.glsl - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * $/LicenseInfo$ - */ - -varying vec2 vary_fragcoord; -uniform vec2 screen_res; - -void main() -{ - //transform vertex - gl_Position = ftransform(); - vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; - vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; -} diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl index c457d0a3e..fcea7aaf1 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl @@ -63,15 +63,13 @@ float calcAmbientOcclusion(vec4 pos, vec3 norm) float dist = dot(pos.xyz,pos.xyz); - if (dist < 64.0*64.0) - { - 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; + 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; @@ -80,38 +78,35 @@ float calcAmbientOcclusion(vec4 pos, vec3 norm) vec3 pos_world = pos.xyz; vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy; - float angle_hidden = 0.0; - int points = 0; + float angle_hidden = 0.0; + int points = 0; - float scale = min(ssao_radius / -pos_world.z, ssao_max_radius); + 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(kern[i], noise_reflect); - vec3 samppos_world = getPosition(samppos_screen).xyz; + // 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(kern[i], noise_reflect); + vec3 samppos_world = getPosition(samppos_screen).xyz; - vec3 diff = pos_world - samppos_world; - float dist2 = dot(diff, diff); + 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) + // 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) - //if (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) // -0.05*norm to shift sample point back slightly for flat surfaces - // angle_hidden += min(1.0/dist2, ssao_factor_inv); // dist != 0 follows from conditional. max of 1.0 (= ssao_factor_inv * ssao_factor) - angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv); + angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv); - // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion" - points = points + int(diff.z > -1.0); - } - - angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0); - - ret = (1.0 - (float(points != 0) * angle_hidden)); - ret += max((dist-32.0*32.0)/(32.0*32.0), 0.0); + // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion" + points = points + int(diff.z > -1.0); } + + angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0); + + ret = (1.0 - (float(points != 0) * angle_hidden)); + ret += max((dist-32.0*32.0)/(32.0*32.0), 0.0); return min(ret, 1.0); } diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index ce32f6600..56f3f9697 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -13,8 +13,7 @@ uniform sampler2DRect diffuseRect; uniform sampler2DRect specularRect; uniform sampler2DRect normalMap; uniform sampler2DRect lightMap; -uniform sampler2D noiseMap; -uniform samplerCube environmentMap; +uniform sampler2DRect depthMap; uniform sampler2D lightFunc; uniform vec3 gi_quad; @@ -43,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; diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index 5a6a3339d..ab0868237 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -195,6 +195,19 @@ static struct ft_display_info ft_display_table[] = { LLFastTimer::FTM_RENDER_FAKE_VBO_UPDATE," Fake VBO update", &LLColor4::red2, 0 }, { LLFastTimer::FTM_RENDER_BLOOM, " Bloom", &LLColor4::blue4, 0 }, { LLFastTimer::FTM_RENDER_BLOOM_FBO, " First FBO", &LLColor4::blue, 0 }, + { LLFastTimer::FTM_RENDER_DEFERRED, " Deferred", &LLColor4::cyan4, 1 }, + { LLFastTimer::FTM_BIND_DEFERRED, " Bind", &LLColor4::pink2, 0 }, + { LLFastTimer::FTM_SUN_SHADOW, " Sun Shadow", &LLColor4::cyan5, 0 }, + { LLFastTimer::FTM_SOFTEN_SHADOW, " Soften Shadow", &LLColor4::yellow1, 0 }, + { LLFastTimer::FTM_EDGE_DETECTION, " Edge Detect", &LLColor4::cyan2, 0 }, + { LLFastTimer::FTM_GI_TRACE, " GI Trace", &LLColor4::green6, 0 }, + { LLFastTimer::FTM_GI_GATHER, " GI Gather", &LLColor4::cyan1, 0 }, + { LLFastTimer::FTM_ATMOSPHERICS, " Atmos", &LLColor4::pink1, 0 }, + { LLFastTimer::FTM_LOCAL_LIGHTS, " Local Lights", &LLColor4::blue2, 0 }, + { LLFastTimer::FTM_FULLSCREEN_LIGHTS, " FS Lights", &LLColor4::purple4, 0 }, + { LLFastTimer::FTM_PROJECTORS, " Project", &LLColor4::orange2, 0 }, + { LLFastTimer::FTM_POST, " Postprocess", &LLColor4::red4, 0 }, + { LLFastTimer::FTM_VISIBLE_CLOUD, " Visible Cloud", &LLColor4::blue5, 0 }, { LLFastTimer::FTM_RENDER_UI, " UI", &LLColor4::cyan4, 1 }, { LLFastTimer::FTM_RENDER_TIMER, " Timers", &LLColor4::cyan5, 1, 0 }, { LLFastTimer::FTM_RENDER_FONTS, " Fonts", &LLColor4::pink1, 0 }, diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 50a57d827..0ab17f6d7 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -130,6 +130,7 @@ LLGLSLShader gDeferredGIProgram(LLViewerShaderMgr::SHADER_DEFERRED); LLGLSLShader gDeferredGIFinalProgram(LLViewerShaderMgr::SHADER_DEFERRED); LLGLSLShader gDeferredPostGIProgram(LLViewerShaderMgr::SHADER_DEFERRED); LLGLSLShader gDeferredPostProgram(LLViewerShaderMgr::SHADER_DEFERRED); +LLGLSLShader gDeferredPostNoDoFProgram(LLViewerShaderMgr::SHADER_DEFERRED); LLGLSLShader gLuminanceGatherProgram(LLViewerShaderMgr::SHADER_DEFERRED); //current avatar shader parameter pointer @@ -878,7 +879,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() { gDeferredMultiLightProgram.mName = "Deferred MultiLight Shader"; gDeferredMultiLightProgram.mShaderFiles.clear(); - gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredMultiLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; success = gDeferredMultiLightProgram.createShader(NULL, NULL); @@ -980,10 +981,21 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { + std::string fragment; + + if (mVertexShaderLevel[SHADER_DEFERRED] < 2 && !gSavedSettings.getBOOL("RenderDeferredSSAO")) + { + fragment = "deferred/softenLightNoSSAOF.glsl"; + } + else + { + fragment = "deferred/softenLightF.glsl"; + } + gDeferredSoftenProgram.mName = "Deferred Soften Shader"; gDeferredSoftenProgram.mShaderFiles.clear(); gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredSoftenProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB)); gDeferredSoftenProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; success = gDeferredSoftenProgram.createShader(NULL, NULL); } @@ -1041,11 +1053,31 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAvatarAlphaProgram.mFeatures.hasLighting = true; gDeferredAvatarAlphaProgram.mShaderFiles.clear(); gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredAvatarAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; success = gDeferredAvatarAlphaProgram.createShader(&mAvatarAttribs, &mAvatarUniforms); } + if (success) + { + gDeferredPostProgram.mName = "Deferred Post Shader"; + gDeferredPostProgram.mShaderFiles.clear(); + gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredPostProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredPostProgram.createShader(NULL, NULL); + } + + if (success) + { + gDeferredPostNoDoFProgram.mName = "Deferred Post Shader"; + gDeferredPostNoDoFProgram.mShaderFiles.clear(); + gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoDoFF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredPostNoDoFProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredPostNoDoFProgram.createShader(NULL, NULL); + } + if (mVertexShaderLevel[SHADER_DEFERRED] > 1) { if (success) diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 1c4e912a4..f952b1a6f 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -366,6 +366,7 @@ extern LLGLSLShader gDeferredSoftenProgram; extern LLGLSLShader gDeferredShadowProgram; extern LLGLSLShader gDeferredPostGIProgram; extern LLGLSLShader gDeferredPostProgram; +extern LLGLSLShader gDeferredPostNoDoFProgram; extern LLGLSLShader gDeferredAvatarShadowProgram; extern LLGLSLShader gDeferredAlphaProgram; extern LLGLSLShader gDeferredFullbrightProgram; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 827afec95..26212e34a 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -548,8 +548,8 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) mDeferredLight[0].release(); } - if (ssao) - { //only need mDeferredLight[1] for ssao + if (ssao || gi) + { //only need mDeferredLight[1] for ssao... and GI mDeferredLight[1].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); } else @@ -689,7 +689,6 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) void LLPipeline::updateRenderDeferred() { sRenderDeferred = (gSavedSettings.getBOOL("RenderDeferred") && - LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && LLRenderTarget::sUseFBO && LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && gSavedSettings.getBOOL("VertexShaderEnable") && @@ -2842,9 +2841,9 @@ void LLPipeline::postSort(LLCamera& camera) else if (sourcep->isMuted()) color = LLColor4(0.f, 1.f, 1.f, 0.5f); gObjectList.addDebugBeacon(pos, "", color, LLColor4(1.f, 1.f, 1.f, 0.5f), width); + // + //gObjectList.addDebugBeacon(pos, "", LLColor4(1.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), debug_beacon_line_width); } - // - //gObjectList.addDebugBeacon(pos, "", LLColor4(1.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), debug_beacon_line_width); } // now deal with highlights for all those seeable sound sources forAllVisibleDrawables(renderSoundHighlights); @@ -3604,6 +3603,8 @@ void LLPipeline::renderDebug() if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) { + LLVertexBuffer::unbind(); + LLGLEnable blend(GL_BLEND); LLGLDepthTest depth(TRUE, FALSE); LLGLDisable cull(GL_CULL_FACE); @@ -5866,16 +5867,152 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b LLVertexBuffer::unbind(); - if (LLPipeline::sRenderDeferred && LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2) + if (LLPipeline::sRenderDeferred && !LLViewerCamera::getInstance()->cameraUnderWater()) { - LLGLDisable blend(GL_BLEND); - bindDeferredShader(gDeferredGIFinalProgram); + bool dof_enabled = true; - S32 channel = gDeferredGIFinalProgram.enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE); + LLGLSLShader* shader = &gDeferredPostProgram; + static const LLCachedControl render_dof("RenderDepthOfField",false); + if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2) + { + shader = &gDeferredGIFinalProgram; + dof_enabled = false; + } + else if (LLToolMgr::getInstance()->inBuildMode() || !render_dof) + { //squish focal length when in build mode (or if DoF is disabled) so DoF doesn't make editing objects difficult + shader = &gDeferredPostNoDoFProgram; + dof_enabled = false; + } + + + LLGLDisable blend(GL_BLEND); + bindDeferredShader(*shader); + + if (dof_enabled) + { + //depth of field focal plane calculations + + static F32 current_distance = 16.f; + static F32 start_distance = 16.f; + static F32 transition_time = 1.f; + + LLVector3 focus_point; + + /*LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject(); + if (obj && obj->mDrawable && obj->isSelected()) + { //focus on selected media object + S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace(); + if (obj && obj->mDrawable) + { + LLFace* face = obj->mDrawable->getFace(face_idx); + if (face) + { + focus_point = face->getPositionAgent(); + } + } + }*/ + + if (focus_point.isExactlyZero()) + { + if (LLViewerJoystick::getInstance()->getOverrideCamera()) + { //focus on point under cursor + focus_point = gDebugRaycastIntersection; + } + else if (gAgent.cameraMouselook()) + { //focus on point under mouselook crosshairs + gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, + NULL, + &focus_point); + } + else + { + LLViewerObject* obj = gAgent.getFocusObject(); + if (obj) + { //focus on alt-zoom target + focus_point = LLVector3(gAgent.getFocusGlobal()-gAgent.getRegion()->getOriginGlobal()); + } + else + { //focus on your avatar + focus_point = gAgent.getPositionAgent(); + } + } + } + + LLVector3 eye = LLViewerCamera::getInstance()->getOrigin(); + F32 target_distance = 16.f; + if (!focus_point.isExactlyZero()) + { + target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point-eye); + } + + if (transition_time >= 1.f && + fabsf(current_distance-target_distance)/current_distance > 0.01f) + { //large shift happened, interpolate smoothly to new target distance + transition_time = 0.f; + start_distance = current_distance; + } + else if (transition_time < 1.f) + { //currently in a transition, continue interpolating + static const LLCachedControl cam_focus_transition_time("CameraFocusTransitionTime",.5f); + transition_time += 1.f/cam_focus_transition_time*gFrameIntervalSeconds; + transition_time = llmin(transition_time, 1.f); + + F32 t = cosf(transition_time*F_PI+F_PI)*0.5f+0.5f; + current_distance = start_distance + (target_distance-start_distance)*t; + } + else + { //small or no change, just snap to target distance + current_distance = target_distance; + } + + //convert to mm + F32 subject_distance = current_distance*1000.f; + static const LLCachedControl fnumber("CameraFNumber",9.f); + static const LLCachedControl default_focal_length("CameraFocalLength",50.f); + static const LLCachedControl cam_field_of_view("CameraFieldOfView",60.f); + + F32 fov = LLViewerCamera::getInstance()->getView(); + + const F32 default_fov = cam_field_of_view * F_PI/180.f; + //const F32 default_aspect_ratio = gSavedSettings.getF32("CameraAspectRatio"); + + //F32 aspect_ratio = (F32) mScreen.getWidth()/(F32)mScreen.getHeight(); + + F32 dv = 2.f*default_focal_length * tanf(default_fov/2.f); + //F32 dh = 2.f*default_focal_length * tanf(default_fov*default_aspect_ratio/2.f); + + F32 focal_length = dv/(2*tanf(fov/2.f)); + + //F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle); + + // from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f)) + // where N = fnumber + // s2 = dot distance + // s1 = subject distance + // f = focal length + // + + F32 blur_constant = focal_length*focal_length/(fnumber*(subject_distance-focal_length)); + blur_constant /= 1000.f; //convert to meters for shader + F32 magnification = focal_length/(subject_distance-focal_length); + + shader->uniform1f("focal_distance", -subject_distance/1000.f); + shader->uniform1f("blur_constant", blur_constant); + shader->uniform1f("tan_pixel_angle", tanf(1.f/LLDrawable::sCurPixelAngle)); + shader->uniform1f("magnification", magnification); + } + + S32 channel = shader->enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE); if (channel > -1) { mScreen.bindTexture(0, channel); + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); } + //channel = shader->enableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE); + //if (channel > -1) + //{ + //gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + //} gGL.begin(LLRender::TRIANGLE_STRIP); gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); @@ -5889,7 +6026,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b gGL.end(); - unbindDeferredShader(gDeferredGIFinalProgram); + unbindDeferredShader(*shader); } else { @@ -5952,12 +6089,12 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b gGL.getTexUnit(0)->activate(); gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); + } - if (LLRenderTarget::sUseFBO) - { //copy depth buffer from mScreen to framebuffer - LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(), - 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); - } + if (LLRenderTarget::sUseFBO) + { //copy depth buffer from mScreen to framebuffer + LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(), + 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); } @@ -5976,7 +6113,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRenderTarget* gi_source, LLRenderTarget* last_gi_post, U32 noise_map) { - //LLFastTimer t(FTM_BIND_DEFERRED); + LLFastTimer t(LLFastTimer::FTM_BIND_DEFERRED); if (noise_map == 0xFFFFFFFF) { @@ -6083,6 +6220,14 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); } + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LIGHT, LLTexUnit::TT_RECT_TEXTURE); + if (channel > -1) + { + has_gi = TRUE; + gi_source->bindTexture(0, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + } + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_DEPTH); if (channel > -1) { @@ -6188,13 +6333,6 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen mGlow[1].bindTexture(0, channel); } - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LIGHT, LLTexUnit::TT_RECT_TEXTURE); - if (channel > -1) - { - gi_source->bindTexture(0, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - } - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_EDGE, LLTexUnit::TT_RECT_TEXTURE); if (channel > -1) { @@ -6389,6 +6527,7 @@ void LLPipeline::renderDeferredLighting() } { + LLFastTimer ftm(LLFastTimer::FTM_RENDER_DEFERRED); LLViewerCamera* camera = LLViewerCamera::getInstance(); { @@ -6449,7 +6588,7 @@ void LLPipeline::renderDeferredLighting() { mDeferredLight[0].bindTarget(); { //paint shadow/SSAO light map (direct lighting lightmap) - //LLFastTimer ftm(FTM_SUN_SHADOW); + LLFastTimer ftm(LLFastTimer::FTM_SUN_SHADOW); bindDeferredShader(gDeferredSunProgram, 0); glClearColor(1,1,1,1); @@ -6497,7 +6636,7 @@ void LLPipeline::renderDeferredLighting() if (render_deferred_blur_light && render_shadow_gi) { - //LLFastTimer ftm(FTM_EDGE_DETECTION); + LLFastTimer ftm(LLFastTimer::FTM_EDGE_DETECTION); //generate edge map LLGLDisable blend(GL_BLEND); LLGLDisable test(GL_ALPHA_TEST); @@ -6540,7 +6679,7 @@ void LLPipeline::renderDeferredLighting() } { //paint noisy GI map (bounce lighting lightmap) - //LLFastTimer ftm(FTM_GI_TRACE); + LLFastTimer ftm(LLFastTimer::FTM_GI_TRACE); LLGLDisable blend(GL_BLEND); LLGLDepthTest depth(GL_FALSE); LLGLDisable test(GL_ALPHA_TEST); @@ -6565,7 +6704,7 @@ void LLPipeline::renderDeferredLighting() static const LLCachedControl render_gui_blur_brightness("RenderGIBlurBrightness",1.025f); for (U32 i = 0; i < pass_count; ++i) { //gather/soften indirect lighting map - //LLFastTimer ftm(FTM_GI_GATHER); + LLFastTimer ftm(LLFastTimer::FTM_GI_GATHER); bindDeferredShader(gDeferredPostGIProgram, 0, &mGIMapPost[0], NULL, mTrueNoiseMap); F32 blur_size = render_gui_blur_size/((F32) i * render_gui_blur_increment+1.f); gDeferredPostGIProgram.uniform2f("delta", 1.f, 0.f); @@ -6601,66 +6740,81 @@ void LLPipeline::renderDeferredLighting() } } - if(render_deferred_ssao) - { //soften direct lighting lightmap - //LLFastTimer ftm(FTM_SOFTEN_SHADOW); - //blur lightmap + //if (gSavedSettings.getBOOL("RenderDeferredSSAO")) + //Make sure to blur normal shadows, even if ssao isn't enabled... + if(mDeferredLight[0].getTexture(0)) + { + LLFastTimer ftm(LLFastTimer::FTM_SOFTEN_SHADOW); + //blur lightmap + if(mDeferredLight[1].getTexture(0)) + { mDeferredLight[1].bindTarget(); glClearColor(1,1,1,1); mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT); - glClearColor(0,0,0,0); + glClearColor(0,0,0,0); + } + else + mDeferredLight[0].bindTarget(); - bindDeferredShader(gDeferredBlurLightProgram); + bindDeferredShader(gDeferredBlurLightProgram); - static const LLCachedControl go("RenderShadowGaussian",LLVector3(3.f,2.f,0.f)); - const U32 kern_length = 4; - static const LLCachedControl blur_size("RenderShadowBlurSize",1.4f); - static const LLCachedControl shadow_blur_dist_factor("RenderShadowBlurDistFactor",.1f); + static const LLCachedControl go("RenderShadowGaussian",LLVector3(3.f,2.f,0.f)); + const U32 kern_length = 4; + static const LLCachedControl blur_size("RenderShadowBlurSize",1.4f); + static const LLCachedControl shadow_blur_dist_factor("RenderShadowBlurDistFactor",.1f); - // sample symmetrically with the middle sample falling exactly on 0.0 - F32 x = 0.f; + // sample symmetrically with the middle sample falling exactly on 0.0 + F32 x = 0.f; - LLVector3 gauss[32]; // xweight, yweight, offset + LLVector3 gauss[32]; // xweight, yweight, offset - for (U32 i = 0; i < kern_length; i++) - { - gauss[i].mV[0] = llgaussian(x, go.get().mV[0]); - gauss[i].mV[1] = llgaussian(x, go.get().mV[1]); - gauss[i].mV[2] = x; - x += 1.f; - } + for (U32 i = 0; i < kern_length; i++) + { + gauss[i].mV[0] = llgaussian(x, go.get().mV[0]); + gauss[i].mV[1] = llgaussian(x, go.get().mV[1]); + gauss[i].mV[2] = x; + x += 1.f; + } - gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f); - gDeferredBlurLightProgram.uniform1f("dist_factor", shadow_blur_dist_factor); - gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); - gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); + gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f); + gDeferredBlurLightProgram.uniform1f("dist_factor", shadow_blur_dist_factor); + gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); + gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); + + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); + stop_glerror(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + stop_glerror(); + } + + if(mDeferredLight[1].getTexture(0)) + { + mDeferredLight[1].flush(); + unbindDeferredShader(gDeferredBlurLightProgram); - { - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); - stop_glerror(); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); - stop_glerror(); - } - - mDeferredLight[1].flush(); - unbindDeferredShader(gDeferredBlurLightProgram); + bindDeferredShader(gDeferredBlurLightProgram, 1); + } + else + { + mDeferredLight[0].flush(); + } + + mDeferredLight[0].bindTarget(); - bindDeferredShader(gDeferredBlurLightProgram, 1); - mDeferredLight[0].bindTarget(); + gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f); - gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f); - - { - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); - stop_glerror(); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); - stop_glerror(); - } - mDeferredLight[0].flush(); - unbindDeferredShader(gDeferredBlurLightProgram); + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); + stop_glerror(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + stop_glerror(); + } + mDeferredLight[0].flush(); + unbindDeferredShader(gDeferredBlurLightProgram); } stop_glerror(); @@ -6693,30 +6847,30 @@ void LLPipeline::renderDeferredLighting() static const LLCachedControl render_deferred_atmospheric("RenderDeferredAtmospheric",false); if (render_deferred_atmospheric) { //apply sunlight contribution - //LLFastTimer ftm(FTM_ATMOSPHERICS); + LLFastTimer ftm(LLFastTimer::FTM_ATMOSPHERICS); bindDeferredShader(gDeferredSoftenProgram, 0, &mGIMapPost[0]); - { - LLGLDepthTest depth(GL_FALSE); - LLGLDisable blend(GL_BLEND); - LLGLDisable test(GL_ALPHA_TEST); + { + LLGLDepthTest depth(GL_FALSE); + LLGLDisable blend(GL_BLEND); + LLGLDisable test(GL_ALPHA_TEST); - //full screen blit - glPushMatrix(); - glLoadIdentity(); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); + //full screen blit + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); - glVertexPointer(2, GL_FLOAT, 0, vert); + glVertexPointer(2, GL_FLOAT, 0, vert); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - } + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + } - unbindDeferredShader(gDeferredSoftenProgram); + unbindDeferredShader(gDeferredSoftenProgram); } { //render sky @@ -6843,6 +6997,7 @@ void LLPipeline::renderDeferredLighting() continue; } + LLFastTimer ftm(LLFastTimer::FTM_LOCAL_LIGHTS); glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s); glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f); glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, @@ -6874,7 +7029,7 @@ void LLPipeline::renderDeferredLighting() for (LLDrawable::drawable_list_t::iterator iter = spot_lights.begin(); iter != spot_lights.end(); ++iter) { - //LLFastTimer ftm(FTM_PROJECTORS); + LLFastTimer ftm(LLFastTimer::FTM_PROJECTORS); LLDrawable* drawablep = *iter; LLVOVolume* volume = drawablep->getVOVolume(); @@ -6940,6 +7095,7 @@ void LLPipeline::renderDeferredLighting() while (!fullscreen_lights.empty()) { + LLFastTimer ftm(LLFastTimer::FTM_FULLSCREEN_LIGHTS); light[count] = fullscreen_lights.front(); fullscreen_lights.pop_front(); col[count] = light_colors.front(); @@ -6959,6 +7115,7 @@ void LLPipeline::renderDeferredLighting() glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); } } + unbindDeferredShader(gDeferredMultiLightProgram); bindDeferredShader(gDeferredMultiSpotLightProgram); @@ -6967,7 +7124,7 @@ void LLPipeline::renderDeferredLighting() for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter) { - //LLFastTimer ftm(FTM_PROJECTORS); + LLFastTimer ftm(LLFastTimer::FTM_PROJECTORS); LLDrawable* drawablep = *iter; LLVOVolume* volume = drawablep->getVOVolume(); @@ -7012,7 +7169,7 @@ void LLPipeline::renderDeferredLighting() gGL.setSceneBlendType(LLRender::BT_ALPHA); { //mix various light maps (local, sun, gi) - //LLFastTimer ftm(FTM_POST); + LLFastTimer ftm(LLFastTimer::FTM_POST); LLGLDisable blend(GL_BLEND); LLGLDisable test(GL_ALPHA_TEST); LLGLDepthTest depth(GL_FALSE); @@ -7635,14 +7792,14 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera glLoadMatrixf(proj.m); glMatrixMode(GL_MODELVIEW); glPushMatrix(); - glLoadMatrixf(view.m); + glLoadMatrixd(gGLModelView); stop_glerror(); gGLLastMatrix = NULL; { - LLGLDepthTest depth(GL_TRUE); - glClear(GL_DEPTH_BUFFER_BIT); + //LLGLDepthTest depth(GL_TRUE); + //glClear(GL_DEPTH_BUFFER_BIT); } gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); @@ -7658,7 +7815,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera LLVertexBuffer::unbind(); { - //LLFastTimer ftm(FTM_SHADOW_SIMPLE); + LLFastTimer ftm(LLFastTimer::FTM_SHADOW_SIMPLE); LLGLDisable test(GL_ALPHA_TEST); gGL.getTexUnit(0)->disable(); for (U32 i = 0; i < sizeof(types)/sizeof(U32); ++i) @@ -7680,7 +7837,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera } { - //LLFastTimer ftm(FTM_SHADOW_ALPHA); + LLFastTimer ftm(LLFastTimer::FTM_SHADOW_ALPHA); LLGLEnable test(GL_ALPHA_TEST); gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.6f); renderObjects(LLRenderPass::PASS_ALPHA_SHADOW, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR, TRUE); @@ -7714,7 +7871,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector3& max, std::vector& fp, LLVector3 light_dir) { - //LLFastTimer t(FTM_VISIBLE_CLOUD); + LLFastTimer t(LLFastTimer::FTM_VISIBLE_CLOUD); //get point cloud of intersection of frust and min, max if (getVisibleExtents(camera, min, max)) @@ -7800,7 +7957,7 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector 0,1, 1,2, 2,3, - 3,1, + 3,0, 4,5, 5,6, @@ -8128,6 +8285,14 @@ void LLPipeline::generateSunShadow(LLCamera& camera) //LLVector3 &n = shadow_near_dist.get(); //F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] }; + //put together a universal "near clip" plane for shadow frusta + /*LLPlane shadow_near_clip; + { + LLVector3 p = gAgent.getCameraPositionAgent();//gAgent.getPositionAgent(); + p += mSunDir * gSavedSettings.getF32("RenderFarClip")*2.f; + shadow_near_clip.setVec(p, mSunDir); + }*/ + LLVector3 lightDir = -mSunDir; lightDir.normVec(); @@ -8555,7 +8720,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) } } - shadow_cam.setFar(128.f); + //shadow_cam.setFar(128.f); shadow_cam.setOriginAndLookAt(eye, up, center); shadow_cam.setOrigin(0,0,0); @@ -8566,6 +8731,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); shadow_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR); + //shadow_cam.getAgentPlane(LLCamera::AGENT_PLANE_NEAR).set(shadow_near_clip); //translate and scale to from [-1, 1] to [0, 1] glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f,