/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
Unknown | 328 lines | 272 code | 56 blank | 0 comment | 0 complexity | 844bf1541d19d4f2f0891890a6800574 MD5 | raw file
Possible License(s): LGPL-2.1
1/** 2 * @file softenLightF.glsl 3 * 4 * $LicenseInfo:firstyear=2007&license=viewerlgpl$ 5 * Second Life Viewer Source Code 6 * Copyright (C) 2007, Linden Research, Inc. 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; 11 * version 2.1 of the License only. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 * 22 * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA 23 * $/LicenseInfo$ 24 */ 25 26#extension GL_ARB_texture_rectangle : enable 27 28#ifdef DEFINE_GL_FRAGCOLOR 29out vec4 gl_FragColor; 30#endif 31 32uniform sampler2DRect diffuseRect; 33uniform sampler2DRect specularRect; 34uniform sampler2DRect positionMap; 35uniform sampler2DRect normalMap; 36uniform sampler2DRect lightMap; 37uniform sampler2DRect depthMap; 38uniform samplerCube environmentMap; 39uniform sampler2D lightFunc; 40 41uniform float blur_size; 42uniform float blur_fidelity; 43 44// Inputs 45uniform vec4 morphFactor; 46uniform vec3 camPosLocal; 47//uniform vec4 camPosWorld; 48uniform vec4 gamma; 49uniform vec4 lightnorm; 50uniform vec4 sunlight_color; 51uniform vec4 ambient; 52uniform vec4 blue_horizon; 53uniform vec4 blue_density; 54uniform vec4 haze_horizon; 55uniform vec4 haze_density; 56uniform vec4 cloud_shadow; 57uniform vec4 density_multiplier; 58uniform vec4 distance_multiplier; 59uniform vec4 max_y; 60uniform vec4 glow; 61uniform float scene_light_strength; 62uniform mat3 env_mat; 63uniform mat3 ssao_effect_mat; 64 65uniform vec3 sun_dir; 66VARYING vec2 vary_fragcoord; 67 68vec3 vary_PositionEye; 69 70vec3 vary_SunlitColor; 71vec3 vary_AmblitColor; 72vec3 vary_AdditiveColor; 73vec3 vary_AtmosAttenuation; 74 75uniform mat4 inv_proj; 76uniform vec2 screen_res; 77 78vec4 getPosition_d(vec2 pos_screen, float depth) 79{ 80 vec2 sc = pos_screen.xy*2.0; 81 sc /= screen_res; 82 sc -= vec2(1.0,1.0); 83 vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); 84 vec4 pos = inv_proj * ndc; 85 pos /= pos.w; 86 pos.w = 1.0; 87 return pos; 88} 89 90vec4 getPosition(vec2 pos_screen) 91{ //get position in screen space (world units) given window coordinate and depth map 92 float depth = texture2DRect(depthMap, pos_screen.xy).a; 93 return getPosition_d(pos_screen, depth); 94} 95 96vec3 getPositionEye() 97{ 98 return vary_PositionEye; 99} 100vec3 getSunlitColor() 101{ 102 return vary_SunlitColor; 103} 104vec3 getAmblitColor() 105{ 106 return vary_AmblitColor; 107} 108vec3 getAdditiveColor() 109{ 110 return vary_AdditiveColor; 111} 112vec3 getAtmosAttenuation() 113{ 114 return vary_AtmosAttenuation; 115} 116 117 118void setPositionEye(vec3 v) 119{ 120 vary_PositionEye = v; 121} 122 123void setSunlitColor(vec3 v) 124{ 125 vary_SunlitColor = v; 126} 127 128void setAmblitColor(vec3 v) 129{ 130 vary_AmblitColor = v; 131} 132 133void setAdditiveColor(vec3 v) 134{ 135 vary_AdditiveColor = v; 136} 137 138void setAtmosAttenuation(vec3 v) 139{ 140 vary_AtmosAttenuation = v; 141} 142 143void calcAtmospherics(vec3 inPositionEye, float ambFactor) { 144 145 vec3 P = inPositionEye; 146 setPositionEye(P); 147 148 vec3 tmpLightnorm = lightnorm.xyz; 149 150 vec3 Pn = normalize(P); 151 float Plen = length(P); 152 153 vec4 temp1 = vec4(0); 154 vec3 temp2 = vec3(0); 155 vec4 blue_weight; 156 vec4 haze_weight; 157 vec4 sunlight = sunlight_color; 158 vec4 light_atten; 159 160 //sunlight attenuation effect (hue and brightness) due to atmosphere 161 //this is used later for sunlight modulation at various altitudes 162 light_atten = (blue_density * 1.0 + vec4(haze_density.r) * 0.25) * (density_multiplier.x * max_y.x); 163 //I had thought blue_density and haze_density should have equal weighting, 164 //but attenuation due to haze_density tends to seem too strong 165 166 temp1 = blue_density + vec4(haze_density.r); 167 blue_weight = blue_density / temp1; 168 haze_weight = vec4(haze_density.r) / temp1; 169 170 //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain) 171 temp2.y = max(0.0, tmpLightnorm.y); 172 temp2.y = 1. / temp2.y; 173 sunlight *= exp( - light_atten * temp2.y); 174 175 // main atmospheric scattering line integral 176 temp2.z = Plen * density_multiplier.x; 177 178 // Transparency (-> temp1) 179 // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier.x in a variable because the ati 180 // compiler gets confused. 181 temp1 = exp(-temp1 * temp2.z * distance_multiplier.x); 182 183 //final atmosphere attenuation factor 184 setAtmosAttenuation(temp1.rgb); 185 186 //compute haze glow 187 //(can use temp2.x as temp because we haven't used it yet) 188 temp2.x = dot(Pn, tmpLightnorm.xyz); 189 temp2.x = 1. - temp2.x; 190 //temp2.x is 0 at the sun and increases away from sun 191 temp2.x = max(temp2.x, .03); //was glow.y 192 //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) 193 temp2.x *= glow.x; 194 //higher glow.x gives dimmer glow (because next step is 1 / "angle") 195 temp2.x = pow(temp2.x, glow.z); 196 //glow.z should be negative, so we're doing a sort of (1 / "angle") function 197 198 //add "minimum anti-solar illumination" 199 temp2.x += .25; 200 201 //increase ambient when there are more clouds 202 vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow.x * 0.5; 203 204 /* decrease value and saturation (that in HSV, not HSL) for occluded areas 205 * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html 206 * // The following line of code performs the equivalent of: 207 * float ambAlpha = tmpAmbient.a; 208 * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis 209 * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue); 210 * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha); 211 */ 212 tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a); 213 214 //haze color 215 setAdditiveColor( 216 vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow.x) + tmpAmbient) 217 + (haze_horizon.r * haze_weight) * (sunlight*(1.-cloud_shadow.x) * temp2.x 218 + tmpAmbient))); 219 220 //brightness of surface both sunlight and ambient 221 setSunlitColor(vec3(sunlight * .5)); 222 setAmblitColor(vec3(tmpAmbient * .25)); 223 setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1)); 224} 225 226vec3 atmosLighting(vec3 light) 227{ 228 light *= getAtmosAttenuation().r; 229 light += getAdditiveColor(); 230 return (2.0 * light); 231} 232 233vec3 atmosTransport(vec3 light) { 234 light *= getAtmosAttenuation().r; 235 light += getAdditiveColor() * 2.0; 236 return light; 237} 238vec3 atmosGetDiffuseSunlightColor() 239{ 240 return getSunlitColor(); 241} 242 243vec3 scaleDownLight(vec3 light) 244{ 245 return (light / scene_light_strength ); 246} 247 248vec3 scaleUpLight(vec3 light) 249{ 250 return (light * scene_light_strength); 251} 252 253vec3 atmosAmbient(vec3 light) 254{ 255 return getAmblitColor() + light / 2.0; 256} 257 258vec3 atmosAffectDirectionalLight(float lightIntensity) 259{ 260 return getSunlitColor() * lightIntensity; 261} 262 263vec3 scaleSoftClip(vec3 light) 264{ 265 //soft clip effect: 266 light = 1. - clamp(light, vec3(0.), vec3(1.)); 267 light = 1. - pow(light, gamma.xxx); 268 269 return light; 270} 271 272void main() 273{ 274 vec2 tc = vary_fragcoord.xy; 275 float depth = texture2DRect(depthMap, tc.xy).r; 276 vec3 pos = getPosition_d(tc, depth).xyz; 277 vec3 norm = texture2DRect(normalMap, tc).xyz; 278 norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm 279 280 float da = max(dot(norm.xyz, sun_dir.xyz), 0.0); 281 282 vec4 diffuse = texture2DRect(diffuseRect, tc); 283 vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); 284 285 vec3 col; 286 float bloom = 0.0; 287 if (diffuse.a < 0.9) 288 { 289 calcAtmospherics(pos.xyz, 1.0); 290 291 col = atmosAmbient(vec3(0)); 292 col += atmosAffectDirectionalLight(max(min(da, 1.0), diffuse.a)); 293 294 col *= diffuse.rgb; 295 296 if (spec.a > 0.0) // specular reflection 297 { 298 // the old infinite-sky shiny reflection 299 // 300 vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); 301 float sa = dot(refnormpersp, sun_dir.xyz); 302 vec3 dumbshiny = vary_SunlitColor*texture2D(lightFunc, vec2(sa, spec.a)).r; 303 304 // add the two types of shiny together 305 vec3 spec_contrib = dumbshiny * spec.rgb; 306 bloom = dot(spec_contrib, spec_contrib); 307 col += spec_contrib; 308 309 //add environmentmap 310 vec3 env_vec = env_mat * refnormpersp; 311 col = mix(col.rgb, textureCube(environmentMap, env_vec).rgb, 312 max(spec.a-diffuse.a*2.0, 0.0)); 313 } 314 315 col = atmosLighting(col); 316 col = scaleSoftClip(col); 317 318 col = mix(col.rgb, diffuse.rgb, diffuse.a); 319 } 320 else 321 { 322 col = diffuse.rgb; 323 } 324 325 gl_FragColor.rgb = col; 326 327 gl_FragColor.a = bloom; 328}