diff options
Diffstat (limited to 'indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl')
-rw-r--r-- | indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl | 337 |
1 files changed, 228 insertions, 109 deletions
diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index 7ed9e7b4fc..8b0ea23897 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -1,177 +1,296 @@ -/** +/** * @file class3/deferred/softenLightF.glsl * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2007, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ - -#extension GL_ARB_texture_rectangle : enable -/*[EXTRA_CODE_HERE]*/ +#define FLT_MAX 3.402823466e+38 -#ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; -#else -#define frag_color gl_FragColor + +uniform sampler2D diffuseRect; +uniform sampler2D specularRect; +uniform sampler2D normalMap; +uniform sampler2D emissiveRect; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl + +const float M_PI = 3.14159265; + +#if defined(HAS_SUN_SHADOW) || defined(HAS_SSAO) +uniform sampler2D lightMap; #endif -uniform sampler2DRect diffuseRect; -uniform sampler2DRect specularRect; -uniform sampler2DRect normalMap; -uniform sampler2DRect lightMap; -uniform sampler2DRect depthMap; +uniform sampler2D depthMap; uniform sampler2D lightFunc; -uniform samplerCube environmentMap; uniform float blur_size; uniform float blur_fidelity; +#if defined(HAS_SSAO) +uniform float ssao_irradiance_scale; +uniform float ssao_irradiance_max; +#endif + // Inputs -uniform vec4 morphFactor; -uniform vec3 camPosLocal; -uniform float cloud_shadow; -uniform float max_y; -uniform vec4 glow; uniform mat3 env_mat; -uniform vec4 shadow_clip; - +uniform mat3 ssao_effect_mat; uniform vec3 sun_dir; -VARYING vec2 vary_fragcoord; +uniform vec3 moon_dir; +uniform int sun_up_factor; +in vec2 vary_fragcoord; uniform mat4 inv_proj; -uniform mat4 inv_modelview; - uniform vec2 screen_res; -uniform sampler2D transmittance_texture; -uniform sampler3D scattering_texture; -uniform sampler3D single_mie_scattering_texture; -uniform sampler2D irradiance_texture; +vec3 getNorm(vec2 pos_screen); +vec4 getPositionWithDepth(vec2 pos_screen, float depth); -uniform sampler2D sh_input_r; -uniform sampler2D sh_input_g; -uniform sampler2D sh_input_b; +void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive); +vec3 atmosFragLightingLinear(vec3 l, vec3 additive, vec3 atten); +vec3 scaleSoftClipFragLinear(vec3 l); -vec3 GetSunAndSkyIrradiance(vec3 camPos, vec3 norm, vec3 dir, out vec3 sky_irradiance); -vec3 GetSkyLuminance(vec3 camPos, vec3 view_dir, float shadow_length, vec3 dir, out vec3 transmittance); -vec3 GetSkyLuminanceToPoint(vec3 camPos, vec3 pos, float shadow_length, vec3 dir, out vec3 transmittance); +// reflection probe interface +void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, + vec2 tc, vec3 pos, vec3 norm, float glossiness, bool transparent, vec3 amblit_linear); +void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv, + vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity, bool transparent, vec3 amblit_linear); +void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm); +void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity); +float getDepth(vec2 pos_screen); -vec3 ColorFromRadiance(vec3 radiance); -vec4 getPositionWithDepth(vec2 pos_screen, float depth); -vec4 getPosition(vec2 pos_screen); -vec3 getNorm(vec2 pos_screen); +vec3 linear_to_srgb(vec3 c); +vec3 srgb_to_linear(vec3 c); +vec3 legacy_adjust(vec3 c); + +uniform vec4 waterPlane; + +uniform int cube_snapshot; #ifdef WATER_FOG -vec4 applyWaterFogView(vec3 pos, vec4 color); +vec4 applyWaterFogViewLinear(vec3 pos, vec4 color); +#endif + +uniform float sky_hdr_scale; + +void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist); +void calcDiffuseSpecular(vec3 baseColor, float metallic, inout vec3 diffuseColor, inout vec3 specularColor); + +vec3 pbrBaseLight(vec3 diffuseColor, + vec3 specularColor, + float metallic, + vec3 pos, + vec3 norm, + float perceptualRoughness, + vec3 light_dir, + vec3 sunlit, + float scol, + vec3 radiance, + vec3 irradiance, + vec3 colorEmissive, + float ao, + vec3 additive, + vec3 atten); + +vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor, + float perceptualRoughness, + float metallic, + vec3 n, // normal + vec3 v, // surface point to camera + vec3 l); //surface point to light + + +void adjustIrradiance(inout vec3 irradiance, float ambocc) +{ + // use sky settings ambient or irradiance map sample, whichever is brighter + //irradiance = max(amblit_linear, irradiance); + +#if defined(HAS_SSAO) + irradiance = mix(ssao_effect_mat * min(irradiance.rgb*ssao_irradiance_scale, vec3(ssao_irradiance_max)), irradiance.rgb, ambocc); #endif +} -void main() +void main() { - vec2 tc = vary_fragcoord.xy; - float depth = texture2DRect(depthMap, tc.xy).r; - vec3 pos = getPositionWithDepth(tc, depth).xyz; - vec4 norm = texture2DRect(normalMap, tc); + vec2 tc = vary_fragcoord.xy; + float depth = getDepth(tc.xy); + vec4 pos = getPositionWithDepth(tc, depth); + vec4 norm = texture(normalMap, tc); float envIntensity = norm.z; - norm.xyz = getNorm(tc); + norm.xyz = getNorm(tc); + vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir; - float da = max(dot(norm.xyz, sun_dir.xyz), 0.0); + vec4 baseColor = texture(diffuseRect, tc); + vec4 spec = texture(specularRect, vary_fragcoord.xy); // NOTE: PBR linear Emissive - vec4 diffuse = texture2DRect(diffuseRect, tc); // sRGB - diffuse.rgb = srgb_to_linear(diffuse.rgb); +#if defined(HAS_SUN_SHADOW) || defined(HAS_SSAO) + vec2 scol_ambocc = texture(lightMap, vary_fragcoord.xy).rg; +#endif - vec3 col; +#if defined(HAS_SUN_SHADOW) + float scol = max(scol_ambocc.r, baseColor.a); +#else + float scol = 1.0; +#endif +#if defined(HAS_SSAO) + float ambocc = scol_ambocc.g; +#else + float ambocc = 1.0; +#endif + + vec3 color = vec3(0); float bloom = 0.0; - { - vec3 camPos = (camPosLocal / 1000.0f) + vec3(0, 0, 6360.0f); - vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); - - vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg; + vec3 sunlit; + vec3 amblit; + vec3 additive; + vec3 atten; - float scol = max(scol_ambocc.r, diffuse.a); + calcAtmosphericVarsLinear(pos.xyz, norm.xyz, light_dir, sunlit, amblit, additive, atten); - float ambocc = scol_ambocc.g; + vec3 sunlit_linear = srgb_to_linear(sunlit); + vec3 amblit_linear = amblit; - vec4 l1tap = vec4(1.0/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265)); - vec4 l1r = texture2D(sh_input_r, vec2(0,0)); - vec4 l1g = texture2D(sh_input_g, vec2(0,0)); - vec4 l1b = texture2D(sh_input_b, vec2(0,0)); + bool do_atmospherics = false; - vec3 indirect = vec3(dot(l1r, l1tap * vec4(1, norm.xyz)), - dot(l1g, l1tap * vec4(1, norm.xyz)), - dot(l1b, l1tap * vec4(1, norm.xyz))); +#ifndef WATER_FOG + // when above water, mask off atmospherics below water + if (dot(pos.xyz, waterPlane.xyz) + waterPlane.w > 0.0) + { + do_atmospherics = true; + } +#else + do_atmospherics = true; +#endif + + vec3 irradiance = vec3(0); + vec3 radiance = vec3(0); + + if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR)) + { + vec3 orm = texture(specularRect, tc).rgb; + float perceptualRoughness = orm.g; + float metallic = orm.b; + float ao = orm.r; + + vec3 colorEmissive = texture(emissiveRect, tc).rgb; + // PBR IBL + float gloss = 1.0 - perceptualRoughness; + + sampleReflectionProbes(irradiance, radiance, tc, pos.xyz, norm.xyz, gloss, false, amblit_linear); + + adjustIrradiance(irradiance, ambocc); + + vec3 diffuseColor; + vec3 specularColor; + calcDiffuseSpecular(baseColor.rgb, metallic, diffuseColor, specularColor); + + vec3 v = -normalize(pos.xyz); + color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit_linear, scol, radiance, irradiance, colorEmissive, ao, additive, atten); + + if (do_atmospherics) + { + color = atmosFragLightingLinear(color, additive, atten); + } + } + else if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS)) + { + //should only be true of WL sky, just port over base color value + color = texture(emissiveRect, tc).rgb; + color = srgb_to_linear(color); + color *= sky_hdr_scale; + } + else + { + // legacy shaders are still writng sRGB to gbuffer + baseColor.rgb = legacy_adjust(baseColor.rgb); + + baseColor.rgb = srgb_to_linear(baseColor.rgb); + + spec.rgb = srgb_to_linear(spec.rgb); - indirect = clamp(indirect, vec3(0), vec3(1.0)); + float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0); - vec3 transmittance; - vec3 sky_irradiance; - vec3 sun_irradiance = GetSunAndSkyIrradiance(camPos, norm.xyz, sun_dir, sky_irradiance); - vec3 inscatter = GetSkyLuminanceToPoint(camPos, (pos / 1000.f) + vec3(0, 0, 6360.0f), scol, sun_dir, transmittance); + vec3 irradiance = vec3(0); + vec3 glossenv = vec3(0); + vec3 legacyenv = vec3(0); - vec3 radiance = scol * (sun_irradiance + sky_irradiance) + inscatter; - vec3 atmo_color = ColorFromRadiance(radiance); + sampleReflectionProbesLegacy(irradiance, glossenv, legacyenv, tc, pos.xyz, norm.xyz, spec.a, envIntensity, false, amblit_linear); + + adjustIrradiance(irradiance, ambocc); - col = atmo_color + indirect; - col *= transmittance; - col *= diffuse.rgb; + // apply lambertian IBL only (see pbrIbl) + color.rgb = irradiance; - vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); + vec3 sun_contrib = min(da, scol) * sunlit_linear; + color.rgb += sun_contrib; + color.rgb *= baseColor.rgb; + + vec3 refnormpersp = reflect(pos.xyz, norm.xyz); - if (spec.a > 0.0) // specular reflection + if (spec.a > 0.0) { - // the old infinite-sky shiny reflection - // - float sa = dot(refnormpersp, sun_dir.xyz); - vec3 dumbshiny = scol * texture2D(lightFunc, vec2(sa, spec.a)).r * atmo_color; - - // add the two types of shiny together - vec3 spec_contrib = dumbshiny * spec.rgb * 0.25; - bloom = dot(spec_contrib, spec_contrib); - col += spec_contrib; + vec3 lv = light_dir.xyz; + vec3 h, l, v = -normalize(pos.xyz); + float nh, nl, nv, vh, lightDist; + vec3 n = norm.xyz; + calcHalfVectors(lv, n, v, h, l, nh, nl, nv, vh, lightDist); + + if (nl > 0.0 && nh > 0.0) + { + float lit = min(nl*6.0, 1.0); + + float sa = nh; + float fres = pow(1 - vh, 5) * 0.4+0.5; + float gtdenom = 2 * nh; + float gt = max(0,(min(gtdenom * nv / vh, gtdenom * nl / vh))); + + scol *= fres*texture(lightFunc, vec2(nh, spec.a)).r*gt/(nh*nl); + color.rgb += lit*scol*sunlit_linear.rgb*spec.rgb; + } + + // add radiance map + applyGlossEnv(color, glossenv, spec, pos.xyz, norm.xyz); } - col = mix(col, diffuse.rgb, diffuse.a); - + color.rgb = mix(color.rgb, baseColor.rgb, baseColor.a); + if (envIntensity > 0.0) - { //add environmentmap - vec3 env_vec = env_mat * refnormpersp; - vec3 sun_direction = (inv_modelview * vec4(sun_dir, 1.0)).xyz; - vec3 radiance_sun = GetSkyLuminance(camPos, env_vec, 0.0f, sun_direction, transmittance); - vec3 refcol = ColorFromRadiance(radiance_sun); - col = mix(col.rgb, refcol, envIntensity); + { // add environment map + applyLegacyEnv(color, legacyenv, spec, pos.xyz, norm.xyz, envIntensity); } - - /*if (norm.w < 0.5) + + + if (do_atmospherics) { - col = scaleSoftClipFrag(col); - }*/ - - #ifdef WATER_FOG - vec4 fogged = applyWaterFogView(pos,vec4(col, bloom)); - col = fogged.rgb; - bloom = fogged.a; - #endif - } + color = atmosFragLightingLinear(color, additive, atten); + } + } + + + + #ifdef WATER_FOG + vec4 fogged = applyWaterFogViewLinear(pos.xyz, vec4(color, bloom)); + color = fogged.rgb; + #endif - //output linear since gamma correction happens down stream - frag_color.rgb = col; - frag_color.a = bloom; + frag_color.rgb = max(color.rgb, vec3(0)); //output linear since local lights will be added to this shader's results + frag_color.a = 0.0; } |