diff options
author | Dave Parks <davep@lindenlab.com> | 2022-09-13 15:25:15 -0500 |
---|---|---|
committer | Dave Parks <davep@lindenlab.com> | 2022-09-13 15:25:15 -0500 |
commit | 402ab8c8f657f050a2ea30ebe562008130cb9bcd (patch) | |
tree | c12dfd8f9b51fac80ff34e73dc716e8318a07fa8 /indra/newview/app_settings/shaders/class1 | |
parent | 0af4adbb8696178767b5972e4c7d879bcdc527e9 (diff) |
SL-17701 WIP -- Cleanup/refactor PBR lighting implementation and get parity between deferred and alpha passes for sunlight and IBL.
Diffstat (limited to 'indra/newview/app_settings/shaders/class1')
4 files changed, 107 insertions, 164 deletions
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl index 02b2daf0ac..fc1cee1f59 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl @@ -262,27 +262,15 @@ void main() vec3 sun_contrib = min(final_da, shadow) * sunlit; -#if !defined(AMBIENT_KILL) color.rgb = amblit; color.rgb *= ambient; -#endif // !defined(AMBIENT_KILL) -vec3 post_ambient = color.rgb; - -#if !defined(SUNLIGHT_KILL) color.rgb += sun_contrib; -#endif // !defined(SUNLIGHT_KILL) - -vec3 post_sunlight = color.rgb; color.rgb *= diffuse_srgb.rgb; -vec3 post_diffuse = color.rgb; - color.rgb = atmosFragLighting(color.rgb, additive, atten); -vec3 post_atmo = color.rgb; - vec4 light = vec4(0,0,0,0); color.rgb = scaleSoftClipFrag(color.rgb); diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl index 449cbeaa28..78f6a5b130 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl @@ -471,7 +471,7 @@ vec3 BRDFDiffuse(vec3 color) vec3 BRDFLambertian( vec3 reflect0, vec3 reflect90, vec3 c_diff, float specWeight, float vh ) { - return (1.0 - specWeight * fresnelSchlick( reflect0, reflect90, vh)) * BRDFDiffuse(c_diff); + return (1.0 - fresnelSchlick( reflect0, reflect90, vh)) * BRDFDiffuse(c_diff); } vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRough, float specWeight, float vh, float nl, float nv, float nh ) @@ -479,5 +479,64 @@ vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRough, float spe vec3 fresnel = fresnelSchlick( reflect0, reflect90, vh ); // Fresnel float vis = V_GGX( nl, nv, alphaRough ); // Visibility float d = D_GGX( nh, alphaRough ); // Distribution - return specWeight * fresnel * vis * d; -} + return fresnel * vis * d; +} + +// set colorDiffuse and colorSpec to the results of GLTF PBR style IBL +void pbrIbl(out vec3 colorDiffuse, // diffuse color output + out vec3 colorSpec, // specular color output, + vec3 radiance, // radiance map sample + vec3 irradiance, // irradiance map sample + float ao, // ambient occlusion factor + float nv, // normal dot view vector + float perceptualRough, // roughness factor + float gloss, // 1.0 - roughness factor + vec3 reflect0, // see also: initMaterial + vec3 c_diff) +{ + // Common to RadianceGGX and RadianceLambertian + vec2 brdfPoint = clamp(vec2(nv, perceptualRough), vec2(0,0), vec2(1,1)); + vec2 vScaleBias = getGGX( brdfPoint); // Environment BRDF: scale and bias applied to reflect0 + vec3 fresnelR = max(vec3(gloss), reflect0) - reflect0; // roughness dependent fresnel + vec3 kSpec = reflect0 + fresnelR*pow(1.0 - nv, 5.0); + + vec3 FssEssGGX = kSpec*vScaleBias.x + vScaleBias.y; + colorSpec = radiance * FssEssGGX; + + // Reference: getIBLRadianceLambertian fs + vec3 FssEssLambert = 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 = (reflect0 + (1.0 - reflect0) / 21.0); + vec3 AvgEms = avg * Ems; + vec3 FmsEms = AvgEms * FssEssLambert / (1.0 - AvgEms); + vec3 kDiffuse = c_diff * (1.0 - FssEssLambert + FmsEms); + colorDiffuse = (FmsEms + kDiffuse) * irradiance; + + colorDiffuse *= ao; + colorSpec *= ao; +} + +void pbrDirectionalLight(inout vec3 colorDiffuse, + inout vec3 colorSpec, + vec3 sunlit, + float scol, + vec3 reflect0, + vec3 reflect90, + vec3 c_diff, + float alphaRough, + float vh, + float nl, + float nv, + float nh) +{ + float scale = 16.0; + vec3 sunColor = sunlit * scale; + + // scol = sun shadow + vec3 intensity = sunColor * nl * scol; + vec3 sunDiffuse = intensity * BRDFLambertian (reflect0, reflect90, c_diff , 1.0, vh); + vec3 sunSpec = intensity * BRDFSpecularGGX(reflect0, reflect90, alphaRough, 1.0, vh, nl, nv, nh); + + colorDiffuse += sunDiffuse; + colorSpec += sunSpec; +}
\ No newline at end of file diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl index 6f087632a5..e87d90aa9e 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl @@ -345,35 +345,6 @@ void main() if (spec.a > 0.0) // specular reflection { - /* // Reverting this specular calculation to previous 'dumbshiny' version - DJH 6/17/2020 - // Preserving the refactored version as a comment for potential reconsideration, - // overriding the general rule to avoid pollutiong the source with commented code. - // - // If you're reading this in 2021+, feel free to obliterate. - - vec3 npos = -normalize(pos.xyz); - - //vec3 ref = dot(pos+lv, norm); - vec3 h = normalize(light_dir.xyz + npos); - float nh = dot(norm.xyz, h); - float nv = dot(norm.xyz, npos); - float vh = dot(npos, h); - float sa = nh; - float fres = pow(1 - dot(h, npos), 5)*0.4 + 0.5; - - float gtdenom = 2 * nh; - float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh)); - - if (nh > 0.0) - { - float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt / (nh*da); - vec3 sp = sun_contrib*scol / 6.0f; - sp = clamp(sp, vec3(0), vec3(1)); - bloom = dot(sp, sp) / 4.0; - color += sp * spec.rgb; - } - */ - float sa = dot(refnormpersp, sun_dir.xyz); vec3 dumbshiny = sunlit * shadow * (texture2D(lightFunc, vec2(sa, spec.a)).r); diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl index bde015d109..c57ae3e51f 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl @@ -25,24 +25,11 @@ /*[EXTRA_CODE_HERE]*/ -#define PBR_USE_IBL 1 -#define PBR_USE_SUN 1 -#define PBR_USE_IRRADIANCE_HACK 1 - #define DIFFUSE_ALPHA_MODE_NONE 0 #define DIFFUSE_ALPHA_MODE_BLEND 1 #define DIFFUSE_ALPHA_MODE_MASK 2 #define DIFFUSE_ALPHA_MODE_EMISSIVE 3 -#define DEBUG_PBR_LIGHT_TYPE 0 // Output Diffuse=0.75, Emissive=0, ORM=0,0,0 - -#define DEBUG_BASIC 0 -#define DEBUG_VERTEX 0 -#define DEBUG_NORMAL_MAP 0 // Output packed normal map "as is" to diffuse -#define DEBUG_NORMAL_OUT 0 // Output unpacked normal to diffuse -#define DEBUG_ORM 0 // Output Occlusion Roughness Metal "as is" to diffuse -#define DEBUG_POSITION 0 - uniform sampler2D diffuseMap; //always in sRGB space uniform sampler2D bumpMap; uniform sampler2D emissiveMap; @@ -56,8 +43,6 @@ uniform vec3 emissiveColor; uniform sampler2DRect lightMap; #endif -uniform samplerCube environmentMap; -uniform mat3 env_mat; uniform int sun_up_factor; uniform vec3 sun_dir; uniform vec3 moon_dir; @@ -108,14 +93,15 @@ uniform vec3 light_direction[8]; // spot direction uniform vec4 light_attenuation[8]; // linear, quadratic, is omni, unused, See: LLPipeline::setupHWLights() and syncLightState() uniform vec3 light_diffuse[8]; -vec2 encode_normal(vec3 n); vec3 srgb_to_linear(vec3 c); vec3 linear_to_srgb(vec3 c); // These are in deferredUtil.glsl but we can't set: mFeatures.isDeferred to include it vec3 BRDFLambertian( vec3 reflect0, vec3 reflect90, vec3 c_diff, float specWeight, float vh ); -vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRoughness, float specWeight, float vh, float nl, float nv, float nh ); void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao); +vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten); +vec3 scaleSoftClipFrag(vec3 l); + 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); float calcLegacyDistanceAttenuation(float distance, float falloff); vec2 getGGX( vec2 brdfPoint ); @@ -125,7 +111,29 @@ float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen); void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyEnv, vec3 pos, vec3 norm, float glossiness, float envIntensity); -vec3 hue_to_rgb(float hue); +void pbrDirectionalLight(inout vec3 colorDiffuse, + inout vec3 colorSpec, + vec3 sunlit, + float scol, + vec3 reflect0, + vec3 reflect90, + vec3 c_diff, + float alphaRough, + float vh, + float nl, + float nv, + float nh); + +void pbrIbl(out vec3 colorDiffuse, // diffuse color output + out vec3 colorSpec, // specular color output, + vec3 radiance, // radiance map sample + vec3 irradiance, // irradiance map sample + float ao, // ambient occlusion factor + float nv, + float perceptualRough, // roughness factor + float gloss, // 1.0 - roughness factor + vec3 reflect0, + vec3 c_diff); // lp = light position // la = linear attenuation, light radius @@ -192,21 +200,14 @@ void main() } #endif -// vec3 base = vertex_color.rgb * albedo.rgb * albedo.a; - vec3 base = vertex_color.rgb * albedo.rgb; + vec3 base = srgb_to_linear(vertex_color.rgb) * albedo.rgb; -#ifdef HAS_NORMAL_MAP vec4 norm = texture2D(bumpMap, vary_texcoord1.xy); norm.xyz = normalize(norm.xyz * 2 - 1); vec3 tnorm = vec3(dot(norm.xyz,vary_mat0), dot(norm.xyz,vary_mat1), dot(norm.xyz,vary_mat2)); -#else - vec4 norm = vec4(0,0,0,1.0); -// vec3 tnorm = vary_normal; - vec3 tnorm = vec3(0,0,1); -#endif tnorm = normalize(tnorm.xyz); norm.xyz = tnorm.xyz; @@ -222,19 +223,13 @@ void main() // occlusion 1.0 // roughness 0.0 // metal 0.0 -#ifdef HAS_SPECULAR_MAP vec3 packedORM = texture2D(specularMap, vary_texcoord2.xy).rgb; // PBR linear packed Occlusion, Roughness, Metal. See: lldrawpoolapha.cpp -#else - vec3 packedORM = vec3(1,0,0); -#endif packedORM.g *= roughnessFactor; packedORM.b *= metallicFactor; - vec3 colorEmissive = emissiveColor; -#ifdef HAS_EMISSIVE_MAP - colorEmissive *= texture2D(emissiveMap, vary_texcoord0.xy).rgb; -#endif + vec3 colorEmissive = srgb_to_linear(emissiveColor); + colorEmissive *= srgb_to_linear(texture2D(emissiveMap, vary_texcoord0.xy).rgb); vec3 colorDiffuse = vec3(0); vec3 colorSpec = vec3(0); @@ -246,9 +241,6 @@ void main() vec3 v = -normalize(vary_position.xyz); vec3 n = norm.xyz; - vec3 t = vec3(1,0,0); - vec3 b = normalize(cross(n,t)); - vec3 reflectVN = normalize(reflect(-v,n)); vec3 h, l; float nh, nl, nv, vh, lightDist; @@ -258,62 +250,27 @@ void main() float alphaRough, specWeight; initMaterial( base, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight ); - // Common to RadianceGGX and RadianceLambertian - vec2 brdfPoint = clamp(vec2(nv, 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 - nv, 5.0); - - vec3 legacyenv; - - 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 PBR_USE_IRRADIANCE_HACK - irradiance = max(amblit,irradiance) * ambocc; -#else -irradiance = vec3(amblit); -#endif - - vec3 FssEssGGX = kSpec*vScaleBias.x + vScaleBias.y; -#if PBR_USE_IBL - colorSpec += specWeight * specLight * FssEssGGX; -#endif - - 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 = c_diff * (1.0 - FssEssLambert + FmsEms); -#if PBR_USE_IBL - colorDiffuse += (FmsEms + kDiffuse) * irradiance; -#endif - - colorDiffuse *= ao; - colorSpec *= ao; + vec3 irradiance = vec3(0); + vec3 radiance = vec3(0); + vec3 legacyenv = vec3(0); + sampleReflectionProbes(irradiance, radiance, legacyenv, pos.xyz, norm.xyz, gloss, 0.0); + irradiance = max(amblit,irradiance) * ambocc; + pbrIbl(colorDiffuse, colorSpec, radiance, irradiance, ao, nv, perceptualRough, gloss, reflect0, c_diff); + // Sun/Moon Lighting if (nl > 0.0 || nv > 0.0) { - float scale = 4.9; - vec3 sunColor = srgb_to_linear(sunlit * scale); // NOTE: Midday should have strong sunlight - - // scol = sun shadow - vec3 intensity = ambocc * sunColor * nl * scol; - vec3 sunDiffuse = intensity * BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh); - vec3 sunSpec = intensity * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh); -#if PBR_USE_SUN - colorDiffuse += sunDiffuse; - colorSpec += sunSpec; -#endif - } + pbrDirectionalLight(colorDiffuse, colorSpec, srgb_to_linear(sunlit), scol, reflect0, reflect90, c_diff, alphaRough, vh, nl, nv, nh); + } + vec3 col = colorDiffuse + colorEmissive + colorSpec; + vec3 light = vec3(0); // Punctual lights -#define LIGHT_LOOP(i) light += srgb_to_linear(vec3(scol)) * calcPointLightOrSpotLight( reflect0, c_diff, srgb_to_linear(2.2*light_diffuse[i].rgb), albedo.rgb, pos.xyz, n, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, light_attenuation[i].w ); +#define LIGHT_LOOP(i) light += srgb_to_linear(vec3(scol)) * calcPointLightOrSpotLight( reflect0, c_diff, srgb_to_linear(2.2*light_diffuse[i].rgb), base.rgb, pos.xyz, n, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, light_attenuation[i].w ); LIGHT_LOOP(1) LIGHT_LOOP(2) @@ -323,42 +280,10 @@ irradiance = vec3(amblit); LIGHT_LOOP(6) LIGHT_LOOP(7) -#if !defined(LOCAL_LIGHT_KILL) - col += light; -#endif // !defined(LOCAL_LIGHT_KILL) - -#if DEBUG_PBR_LIGHT_TYPE - col.rgb = vec3(0.75); - emissive = vec3(0); - spec.rgb = vec3(0); -#endif -#if DEBUG_BASIC - col.rgb = vec3( 1, 0, 1 ); -#endif -#if DEBUG_VERTEX - col.rgb = vertex_color.rgb; -#endif -#if DEBUG_NORMAL_MAP - col.rgb = texture2D(bumpMap, vary_texcoord1.xy).rgb; -#endif -#if DEBUG_NORMAL_OUT - col.rgb = vary_normal; -#endif -#if DEBUG_ORM - col.rgb = linear_to_srgb(spec); -#endif -#if DEBUG_POSITION - col.rgb = vary_position.xyz; -#endif + col.rgb = linear_to_srgb(col.rgb); + col *= atten.r; + col += 2.0*additive; + col = scaleSoftClipFrag(col); -// col.rgb = linear_to_srgb(col.rgb); -// frag_color = vec4(albedo.rgb,albedo.a); -// frag_color = vec4(base.rgb,albedo.a); -// frag_color = vec4(irradiance,albedo.a); -// frag_color = vec4(colorDiffuse,albedo.a); -// frag_color = vec4(colorEmissive,albedo.a); -// frag_color = vec4(sun_dir,albedo.a); -// frag_color = vec4(sunlit,albedo.a); - col = linear_to_srgb(col.rgb); frag_color = vec4(col,albedo.a); } |