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 | 484 |
1 files changed, 373 insertions, 111 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..bd6ba4bf15 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -1,31 +1,72 @@ -/** +/** * @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$ */ - + +#define DEBUG_PBR_PACKORM0 0 // Rough=0, Metal=0 +#define DEBUG_PBR_PACKORM1 0 // Rough=1, Metal=1 +#define DEBUG_PBR_TANGENT1 1 // Tangent = 1,0,0 +#define DEBUG_PBR_VERT2CAM1 0 // vertex2camera = 0,0,1 + +#define DEBUG_PBR_DIFFUSE 0 // Output: Radiance Lambertian +#define DEBUG_PBR_EMISSIVE 0 // Output: Emissive +#define DEBUG_PBR_METAL 0 // Output: grayscale Metal map +#define DEBUG_PBR_OCCLUSION 0 // Output: grayscale Occlusion map +#define DEBUG_PBR_ORM 0 // Output: Packed Occlusion Roughness Metal +#define DEBUG_PBR_ROUGH_PERCEPTUAL 0 // Output: grayscale Perceptual Roughenss map +#define DEBUG_PBR_ROUGH_ALPHA 0 // Output: grayscale Alpha Roughness + +#define DEBUG_PBR_NORMAL 0 // Output: passed in normal. To see raw normal map: set DEBUG_PBR_DIFFUSE_MAP 1, and in pbropaqueF set DEBUG_NORMAL_RAW +#define DEBUG_PBR_TANGENT 0 // Output: Tangent +#define DEBUG_PBR_BITANGENT 0 // Output: Bitangent +#define DEBUG_PBR_DOT_BV 0 // Output: graysacle dot(Bitangent,Vertex2Camera) +#define DEBUG_PBR_DOT_NV 0 // Output: grayscale dot(Normal ,Vertex2Camera) +#define DEBUG_PBR_DOT_TV 0 // Output: grayscale dot(Tangent ,Vertex2Camera) + +#define DEBUG_PBR_BRDF_SCALE_BIAS 0 // Output: red green BRDF Scale Bias (GGX output) +#define DEBUG_PBR_BRDF_UV 0 // Output: red green BRDF UV (GGX input) +#define DEBUG_PBR_DIFFUSE_K 0 // Output: diffuse FssEssLambert + FmsEms +#define DEBUG_PBR_DIFFUSE_MAP 0 // Output: use diffuse in G-Buffer +#define DEBUG_PBR_FE_GGX 0 // Output: FssEssGGX +#define DEBUG_PBR_FE_LAMBERT 0 // Output: FssEssLambert +#define DEBUG_PBR_FRESNEL 0 // Output: roughness dependent fresnel +#define DEBUG_PBR_IOR 0 // Output: grayscale IOR +#define DEBUG_PBR_IRRADIANCE 0 // Output: Diffuse Irradiance +#define DEBUG_PBR_KSPEC 0 // Output: K spec +#define DEBUG_PBR_REFLECT0_BASE 0 // Output: black reflect0 default from ior +#define DEBUG_PBR_REFLECT0_MIX 0 // Output: diffuse reflect0 calculated from ior +#define DEBUG_PBR_REFLECTANCE 0 // Output: diffuse reflectance -- NOT USED +#define DEBUG_PBR_SPEC 0 // Output: Final spec +#define DEBUG_PBR_SPEC_REFLECTION 0 // Output: environment reflection +#define DEBUG_PBR_V2C_RAW 0 // Output: vertex2camera +#define DEBUG_PBR_V2C_REMAP 0 // Output: vertex2camera (remap [-1,1] -> [0,1]) #extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_shader_texture_lod : enable + +#define FLT_MAX 3.402823466e+38 -/*[EXTRA_CODE_HERE]*/ +#define REFMAP_COUNT 256 +#define REF_SAMPLE_COUNT 64 //maximum number of samples to consider #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; @@ -36,142 +77,363 @@ out vec4 frag_color; uniform sampler2DRect diffuseRect; uniform sampler2DRect specularRect; uniform sampler2DRect normalMap; +uniform sampler2DRect emissiveRect; + +#if defined(HAS_SUN_SHADOW) || defined(HAS_SSAO) uniform sampler2DRect lightMap; +#endif + uniform sampler2DRect depthMap; uniform sampler2D lightFunc; -uniform samplerCube environmentMap; uniform float blur_size; uniform float blur_fidelity; // 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 vec3 sun_dir; +uniform vec3 moon_dir; +uniform int sun_up_factor; VARYING 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 calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao); +float getAmbientClamp(); +vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten); +vec3 scaleSoftClipFrag(vec3 l); +vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten); +vec3 fullbrightScaleSoftClip(vec3 light); -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, inout vec3 legacyEnv, + vec3 pos, vec3 norm, float glossiness, float envIntensity); +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); -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); #ifdef WATER_FOG vec4 applyWaterFogView(vec3 pos, vec4 color); #endif -void main() +uniform vec3 view_dir; // PBR + +// Approximate Environment BRDF +vec2 getGGXApprox( vec2 uv ) { - vec2 tc = vary_fragcoord.xy; - float depth = texture2DRect(depthMap, tc.xy).r; - vec3 pos = getPositionWithDepth(tc, depth).xyz; - vec4 norm = texture2DRect(normalMap, tc); + vec2 st = vec2(1.) - uv; + float d = (st.x * st.x * 0.5) * (st.y * st.y); + float scale = 1.0 - d; + float bias = d; + return vec2( scale, bias ); +} + +vec2 getGGX( vec2 brdfPoint ) +{ + // TODO: use GGXLUT + // texture2D(GGXLUT, brdfPoint).rg; + return getGGXApprox( brdfPoint); +} + +vec3 calcBaseReflect0(float ior) +{ + vec3 reflect0 = vec3(pow((ior - 1.0) / (ior + 1.0), 2.0)); + return reflect0; +} + +void main() +{ + vec2 tc = vary_fragcoord.xy; + float depth = texture2DRect(depthMap, tc.xy).r; + vec4 pos = getPositionWithDepth(tc, depth); + vec4 norm = texture2DRect(normalMap, tc); float envIntensity = norm.z; - norm.xyz = getNorm(tc); + norm.xyz = getNorm(tc); - float da = max(dot(norm.xyz, sun_dir.xyz), 0.0); + vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir; + float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0); + float light_gamma = 1.0 / 1.3; + da = pow(da, light_gamma); - vec4 diffuse = texture2DRect(diffuseRect, tc); // sRGB - diffuse.rgb = srgb_to_linear(diffuse.rgb); + vec4 diffuse = texture2DRect(diffuseRect, tc); + diffuse.rgb = linear_to_srgb(diffuse.rgb); // SL-14035 + vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); - vec3 col; + +#if defined(HAS_SUN_SHADOW) || defined(HAS_SSAO) + vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg; + scol_ambocc = pow(scol_ambocc, vec2(light_gamma)); + float scol = max(scol_ambocc.r, diffuse.a); + float ambocc = scol_ambocc.g; +#else + float scol = 1.0; + float ambocc = 1.0; +#endif + + vec3 color = vec3(0); float bloom = 0.0; + + vec3 sunlit; + vec3 amblit; + vec3 additive; + vec3 atten; + + calcAtmosphericVars(pos.xyz, light_dir, ambocc, sunlit, amblit, additive, atten, true); + + //vec3 amb_vec = env_mat * norm.xyz; + + vec3 ambenv; + vec3 glossenv; + vec3 legacyenv; + + bool hasPBR = GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR); + if (hasPBR) { - 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; - - float scol = max(scol_ambocc.r, diffuse.a); - - float ambocc = scol_ambocc.g; - - 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)); - - vec3 indirect = vec3(dot(l1r, l1tap * vec4(1, norm.xyz)), - dot(l1g, l1tap * vec4(1, norm.xyz)), - dot(l1b, l1tap * vec4(1, norm.xyz))); - - indirect = clamp(indirect, vec3(0), vec3(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 radiance = scol * (sun_irradiance + sky_irradiance) + inscatter; - vec3 atmo_color = ColorFromRadiance(radiance); - - col = atmo_color + indirect; - col *= transmittance; - col *= diffuse.rgb; - - vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); - - if (spec.a > 0.0) // specular reflection - { - // 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; - } - - col = mix(col, diffuse.rgb, diffuse.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); - } - - /*if (norm.w < 0.5) - { - col = scaleSoftClipFrag(col); - }*/ - - #ifdef WATER_FOG - vec4 fogged = applyWaterFogView(pos,vec4(col, bloom)); - col = fogged.rgb; - bloom = fogged.a; - #endif + vec3 colorDiffuse = vec3(0); + vec3 colorEmissive = texture2DRect(emissiveRect, tc).rgb; + vec3 colorSpec = vec3(0); +// vec3 colorClearCoat = vec3(0); +// vec3 colorSheen = vec3(0); +// vec3 colorTransmission = vec3(0); + + vec3 packedORM = spec.rgb; // Packed: Occlusion Roughness Metal +#if DEBUG_PBR_PACK_ORM0 + packedORM = vec3(0,0,0); +#endif +#if DEBUG_PBR_PACK_ORM1 + packedORM = vec3(1,1,1); +#endif + float IOR = 1.5; // default Index Of Refraction 1.5 (dielectrics) + vec3 reflect0 = vec3(0.04); // -> incidence reflectance 0.04 +#if HAS_IOR + reflect0 = calcBaseReflect0(IOR); +#endif +#if DEBUG_PBR_REFLECT0_BASE + vec3 debug_reflect0 = reflect0; +#endif + + float metal = packedORM.b; + vec3 reflect90 = vec3(0); + vec3 v = -normalize(pos.xyz); +#if DEBUG_PBR_VERT2CAM1 + v = vec3(0,0,1); +#endif + vec3 n = norm.xyz; +// vec3 t = texture2DRect(tangentMap, tc).rgb; +#if DEBUG_PBR_TANGENT1 + vec3 t = vec3(1,0,0); +#endif + vec3 b = cross( n,t); + vec3 reflectVN = normalize(reflect(-v,n)); + + float dotNV = clamp(dot(n,v),0,1); + float dotTV = clamp(dot(t,v),0,1); + float dotBV = clamp(dot(b,v),0,1); + + // Reference: getMetallicRoughnessInfo + float perceptualRough = packedORM.g; + float alphaRough = perceptualRough * perceptualRough; + vec3 colorDiff = mix( diffuse.rgb, vec3(0) , metal); + reflect0 = mix( reflect0 , diffuse.rgb, metal); // reflect at 0 degrees + reflect90 = vec3(1); // reflect at 90 degrees +#if DEBUG_PBR_REFLECTANCE + float reflectance = max( max( reflect0.r, reflect0.g ), reflect0.b ); +#endif + + // Common to RadianceGGX and RadianceLambertian + float specWeight = 1.0; + vec2 brdfPoint = clamp(vec2(dotNV, perceptualRough), vec2(0,0), vec2(1,1)); + vec2 vScaleBias = getGGX( brdfPoint); // Environment BRDF: scale and bias applied to reflect0 + vec3 fresnelR = max(vec3(1.0 - perceptualRough), reflect0) - reflect0; // roughness dependent fresnel + vec3 kSpec = reflect0 + fresnelR*pow(1.0 - dotNV, 5.0); + + // Reference: getIBLRadianceGGX + // https://forum.substance3d.com/index.php?topic=3243.0 + // Glossiness + // This map is the inverse of the roughness map. + vec3 irradiance = vec3(0); + vec3 specLight = vec3(0); + float gloss = 1.0 - perceptualRough; + sampleReflectionProbes(irradiance, specLight, legacyenv, pos.xyz, norm.xyz, gloss, 0.0); +#if HAS_IBL + kSpec = mix( kSpec, iridescenceFresnel, iridescenceFactor); +#endif + vec3 FssEssGGX = kSpec*vScaleBias.x + vScaleBias.y; + colorSpec += specWeight * specLight * FssEssGGX; + + // Reference: getIBLRadianceLambertian + vec3 FssEssLambert = specWeight * kSpec * vScaleBias.x + vScaleBias.y; // NOTE: Very similar to FssEssRadiance but with extra specWeight term + float Ems = (1.0 - vScaleBias.x + vScaleBias.y); + vec3 avg = specWeight * (reflect0 + (1.0 - reflect0) / 21.0); + vec3 AvgEms = avg * Ems; + vec3 FmsEms = AvgEms * FssEssLambert / (1.0 - AvgEms); + vec3 kDiffuse = colorDiffuse * (1.0 - FssEssLambert + FmsEms); + colorDiffuse += (FmsEms + kDiffuse) * irradiance; + + colorDiffuse *= packedORM.r; // Occlusion -- NOTE: pbropaque will need occlusion_strength pre-multiplied into spec.r + + color.rgb = colorDiffuse + colorEmissive + colorSpec; + + #if DEBUG_PBR_DIFFUSE + color.rgb = colorDiffuse; + #endif + #if DEBUG_PBR_EMISSIVE + color.rgb = colorEmissive; + #endif + #if DEBUG_PBR_METAL + color.rgb = vec3(metal); + #endif + #if DEBUG_PBR_OCCLUSION + color.rgb = vec3(packedORM.r); + #endif + #if DEBUG_PBR_ORM + color.rgb = packedORM; + #endif + #if DEBUG_PBR_ROUGH_PERCEPTUAL + color.rgb = vec3(perceptualRough); + #endif + #if DEBUG_PBR_ROUGH_ALPHA + color.rgb = vec3(alphaRough); + #endif + + #if DEBUG_PBR_NORMAL + color.rgb = norm.xyz; + #endif + #if DEBUG_PBR_TANGENT + color.rgb = t; + #endif + #if DEBUG_PBR_BITANGENT + color.rgb = b; + #endif + #if DEBUG_PBR_DOT_NV + color.rgb = vec3(dotNV); + #endif + #if DEBUG_PBR_DOT_TV + color.rgb = vec3(dotTV); + #endif + #if DEBUG_PBR_DOT_BV + color.rgb = vec3(dotBV); + #endif + + #if DEBUG_PBR_BRDF_UV + color.rgb = vec3(brdfPoint,0.0); + #endif + #if DEBUG_PBR_BRDF_SCALE_BIAS + color.rgb = vec3(vScaleBias,0.0); + #endif + #if DEBUG_PBR_DIFFUSE_K + color.rgb = kDiffuse; + #endif + #if DEBUG_PBR_DIFFUSE_MAP + color.rgb = diffuse.rgb; + #endif + #if DEBUG_PBR_FE_GGX + color.rgb = FssEssGGX; // spec + #endif + #if DEBUG_PBR_FE_LAMBERT + color.rgb = FssEssLambert; // diffuse + #endif + #if DEBUG_PBR_FRESNEL + color.rgb = fresnelR; + #endif + #if DEBUG_PBR_IOR + color.rgb = vec3(IOR); + #endif + #if DEBUG_PBR_IRRADIANCE + color.rgb = irradiance; + #endif + #if DEBUG_PBR_KSPEC + color.rgb = kSpec; + #endif + #if DEBUG_PBR_REFLECT0_BASE + color.rgb = vec3(debug_reflect0); + #endif + #if DEBUG_PBR_REFLECT0_MIX + color.rgb = vec3(reflect0); + #endif + #if DEBUG_PBR_REFLECTANCE + color.rgb = vec3(reflectance); + #endif + #if DEBUG_PBR_SPEC + color.rgb = colorSpec; + #endif + #if DEBUG_PBR_SPEC_REFLECTION + color.rgb = specLight; + #endif + #if DEBUG_PBR_V2C_RAW + color.rgb = v; + #endif + #if DEBUG_PBR_V2C_REMAP + color.rgb = v*0.5 + vec3(0.5); + #endif } +else +{ + sampleReflectionProbes(ambenv, glossenv, legacyenv, pos.xyz, norm.xyz, spec.a, envIntensity); + + amblit = max(ambenv, amblit); + color.rgb = amblit*ambocc; + + //float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0); + //ambient *= 0.5; + //ambient *= ambient; + //ambient = (1.0 - ambient); + //color.rgb *= ambient; + + vec3 sun_contrib = min(da, scol) * sunlit; + color.rgb += sun_contrib; + color.rgb = min(color.rgb, vec3(1,1,1)); + color.rgb *= diffuse.rgb; - //output linear since gamma correction happens down stream - frag_color.rgb = col; + vec3 refnormpersp = reflect(pos.xyz, norm.xyz); + + if (spec.a > 0.0) // specular reflection + { + float sa = dot(normalize(refnormpersp), light_dir.xyz); + vec3 dumbshiny = sunlit * scol * (texture2D(lightFunc, vec2(sa, spec.a)).r); + + // add the two types of shiny together + vec3 spec_contrib = dumbshiny * spec.rgb; + bloom = dot(spec_contrib, spec_contrib) / 6; + color.rgb += spec_contrib; + + // add reflection map - EXPERIMENTAL WORK IN PROGRESS + applyGlossEnv(color, glossenv, spec, pos.xyz, norm.xyz); + } + + color.rgb = mix(color.rgb, diffuse.rgb, diffuse.a); + + if (envIntensity > 0.0) + { // add environmentmap + //fudge darker + legacyenv *= 0.5*diffuse.a+0.5;; + applyLegacyEnv(color, legacyenv, spec, pos.xyz, norm.xyz, envIntensity); + } + + if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS)) + { + color = mix(atmosFragLighting(color, additive, atten), fullbrightAtmosTransportFrag(color, additive, atten), diffuse.a); + color = mix(scaleSoftClipFrag(color), fullbrightScaleSoftClip(color), diffuse.a); + } + +#ifdef WATER_FOG + vec4 fogged = applyWaterFogView(pos.xyz, vec4(color, bloom)); + color = fogged.rgb; + bloom = fogged.a; +#endif +} + // convert to linear as fullscreen lights need to sum in linear colorspace + // and will be gamma (re)corrected downstream... + //color = vec3(ambocc); + //color = ambenv; + //color.b = diffuse.a; + frag_color.rgb = srgb_to_linear(color.rgb); frag_color.a = bloom; } |