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