summaryrefslogtreecommitdiff
path: root/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl')
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl337
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;
}