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 | |
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')
8 files changed, 268 insertions, 784 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); } diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index d78c47a36a..50aa93fea6 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -23,106 +23,6 @@ * $/LicenseInfo$ */ -#define PBR_USE_ATMOS 1 -#define PBR_USE_IBL 1 -#define PBR_USE_SUN 1 - -#define PBR_USE_LINEAR_ALBEDO 1 -#define PBR_USE_DEFAULT_IRRADIANCE 0 // PBR: irradiance, skins/default/textures/default_irradiance.png -#define PBR_USE_IRRADIANCE_HACK 1 - -#define DEBUG_PBR_LIGHT_TYPE 0 // Output no global light to make it easier to see pointLight and spotLight -#define DEBUG_PBR_PACK_ORM0 0 // Rough=0, Metal=0 -#define DEBUG_PBR_PACK_ORM1 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_SPECLIGHT051 0 // Force specLigh to be 0,0.5,1 - -// Pass input through "as is" -#define DEBUG_PBR_DIFFUSE_MAP 0 // Output: use diffuse in G-Buffer -#define DEBUG_PBR_EMISSIVE 0 // Output: Emissive -#define DEBUG_PBR_METAL 0 // Output: grayscale Metal map -#define DEBUG_PBR_NORMAL_MAP 0 // Output: Normal -- also need to set DEBUG_NORMAL_MAP in pbropaqueF -#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 Roughness map -#define DEBUG_PBR_ROUGH_ALPHA 0 // Output: grayscale Alpha Roughness - -#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_TV 0 // Output: grayscale dot(Tangent ,Vertex2Camera) - -// IBL Spec -#define DEBUG_PBR_NORMAL 0 // Output: passed in normal -#define DEBUG_PBR_V2C_RAW 0 // Output: vertex2camera -#define DEBUG_PBR_DOT_NV 0 // Output: grayscale dot(Normal ,Vertex2Camera) -#define DEBUG_PBR_BRDF_UV 0 // Output: red green BRDF UV (GGX input) -#define DEBUG_PBR_BRDF_SCALE_BIAS 0 // Output: red green BRDF Scale Bias (GGX output) -#define DEBUG_PBR_BRDF_SCALE_ONLY 0 // Output: grayscale BRDF Scale -#define DEBUG_PBR_BRDF_BIAS_ONLY 0 // Output: grayscale BRDER Bias -#define DEBUG_PBR_FRESNEL 0 // Output: roughness dependent fresnel -#define DEBUG_PBR_KSPEC 0 // Output: K spec -#define DEBUG_PBR_REFLECTION_DIR 0 // Output: reflection dir -#define DEBUG_PBR_SPEC_IBL 0 // Output: IBL specularity -#define DEBUG_PBR_SPEC_LEGACY 0 // Output: legacyenv -#define DEBUG_PBR_SPEC_REFLECTION 0 // Output: environment reflection -#define DEBUG_PBR_FSS_ESS_GGX 0 // Output: FssEssGGX -#define DEBUG_PBR_SPEC 0 // Output: Final spec - -// IBL Diffuse -#define DEBUG_PBR_DIFFUSE_C 0 // Output: diffuse non metal mix -#define DEBUG_PBR_IRRADIANCE_RAW 0 // Output: Diffuse Irradiance pre-mix -#define DEBUG_PBR_IRRADIANCE 0 // Output: Diffuse Irradiance, NOTE: SSAO is factored in -#define DEBUG_PBR_FSS_ESS_LAMBERT 0 // Output: FssEssLambert -#define DEBUG_PBR_EMS 0 // Output: Ems = (1 - BRDF Scale + BRDF Bias) -#define DEBUG_PBR_EMS_AVG 0 // Output: Avg Ems -#define DEBUG_PBR_AVG 0 // Output: Avg -#define DEBUG_PBR_FMS_EMS 0 // Output: FmsEms -#define DEBUG_PBR_DIFFUSE_K 0 // Output: diffuse FssEssLambert + FmsEms -#define DEBUG_PBR_DIFFUSE_PRE_AO 0 // Output: diffuse pre AO -#define DEBUG_PBR_DIFFUSE 0 // Output: diffuse post AO - -// Atmospheric Lighting -#define DEBUG_PBR_AMBENV 0 // Output: ambient environment -#define DEBUG_PBR_AMBOCC 0 // Output: ambient occlusion -#define DEBUG_PBR_DA_RAW 0 // Output: da pre pow() -#define DEBUG_PBR_DA_POW 0 // Output: da post pow() -#define DEBUG_PBR_SUN_LIT 0 // Ouput: sunlit -#define DEBUG_PBR_SUN_CONTRIB 0 // Output: sun_contrib -#define DEBUG_PBR_SKY_ADDITIVE 0 // Output: additive -#define DEBUG_PBR_SKY_ATTEN 0 // Output: greyscale atten.r - -// Sun -#define DEBUG_PBR_SUN_FULL_BRIGHT 0 // Sunlit color = <1,1,1> -#define DEBUG_PBR_SUN_OUT_DIFFUSE 0 // Final sun diffuse : intensity * nl * diffuse -#define DEBUG_PBR_SUN_OUT_SPECULAR 0 // Final sun specular: intensity * nl * specular -#define DEBUG_PBR_SUN_LAMBERT 0 // BRDF Diffuse: Lambertian Diffuse color -#define DEBUG_PBR_SUN_LAMBERT_NL 0 // BRDF Diffuse: nl * Lambertian Diffuse color -#define DEBUG_PBR_SUN_H 0 // Half Vector -#define DEBUG_PBR_SUN_L 0 // Light Vector -#define DEBUG_PBR_SUN_V 0 // Surface to Light Vector -#define DEBUG_PBR_SUN_NH 0 // dot(n,h) -#define DEBUG_PBR_SUN_NL 0 // dot(n,l) -#define DEBUG_PBR_SUN_NV 0 // dot(n,v) -#define DEBUG_PBR_SUN_VH 0 // dot(v,h) -#define DEBUG_PBR_SUN_REFLECT0 0 // reflect0 only -#define DEBUG_PBR_SUN_SPEC_FRESNEL 0 // Fresnel -#define DEBUG_PBR_SUN_SPEC_D 0 // D(h) -#define DEBUG_PBR_SUN_SPEC_V 0 // V(l,v,h) -#define DEBUG_PBR_SUN_SPEC_DF 0 // D() * F() -#define DEBUG_PBR_SUN_SPEC_DV 0 // D() * V() -#define DEBUG_PBR_SUN_SPEC_FV 0 // F() * V() -#define DEBUG_PBR_SUN_SPEC_DFV 0 // D() * F() * V() -#define DEBUG_PBR_SUN_SPEC_NL_DFV 0 // nl * D() * F() * V() -#define DEBUG_PBR_SUN_FINAL 0 // LAMBERT_NL + BRDF() - -#define DEBUG_PBR_IOR 0 // Output: grayscale IOR -#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_WEIGHT 0 // Output: specWeight -#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 @@ -169,16 +69,7 @@ uniform vec2 screen_res; vec3 getNorm(vec2 pos_screen); vec4 getPositionWithDepth(vec2 pos_screen, float depth); -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); -float calcF0(float ior); -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 getAmbientClamp(); -vec2 getGGX( vec2 brdfPoint ); -void initMaterial( vec3 diffuse, vec3 packedORM, - out float alphaRough, out vec3 c_diff, out vec3 reflect0, out vec3 reflect90, out float specWeight ); vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten); vec3 scaleSoftClipFrag(vec3 l); vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten); @@ -193,18 +84,39 @@ void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 vec3 linear_to_srgb(vec3 c); vec3 srgb_to_linear(vec3 c); -// Debug Utils -vec3 BRDFDiffuse(vec3 color); -vec3 colorize_dot(float x); -vec3 fresnelSchlick( vec3 reflect0, vec3 reflect90, float vh); -float D_GGX( float nh, float alphaRough ); -float V_GGX( float nl, float nv, float alphaRough ); - #ifdef WATER_FOG vec4 applyWaterFogView(vec3 pos, vec4 color); #endif -uniform vec3 view_dir; // PBR +// PBR interface +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 initMaterial( vec3 diffuse, vec3 packedORM, + out float alphaRough, out vec3 c_diff, out vec3 reflect0, out vec3 reflect90, out float specWeight ); +// perform PBR image based lighting according to GLTF spec +// all parameters are in linear space +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); + +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 main() { @@ -241,8 +153,6 @@ void main() calcAtmosphericVars(pos.xyz, light_dir, ambocc, sunlit, amblit, additive, atten, true); - //vec3 amb_vec = env_mat * norm.xyz; - vec3 ambenv; vec3 glossenv; vec3 legacyenv; @@ -262,480 +172,111 @@ void main() vec3 colorDiffuse = vec3(0); vec3 colorEmissive = spec.rgb; // PBR sRGB Emissive. See: pbropaqueF.glsl vec3 colorSpec = vec3(0); -// vec3 colorClearCoat = vec3(0); -// vec3 colorSheen = vec3(0); -// vec3 colorTransmission = vec3(0); vec3 packedORM = texture2DRect(emissiveRect, tc).rgb; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl -#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) -#if DEBUG_PBR_REFLECT0_BASE - vec3 debug_reflect0 = vec3(calcF0(IOR)); -#endif float ao = packedORM.r; float metal = packedORM.b; 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)); vec3 h, l; float nh, nl, nv, vh, lightDist; calcHalfVectors(light_dir, n, v, h, l, nh, nl, nv, vh, lightDist); - float tv = clamp(dot(t,v),0,1); - float bv = clamp(dot(b,v),0,1); - - // Reference: getMetallicRoughnessInfo -#if PBR_USE_LINEAR_ALBEDO - vec3 base = diffuse.rgb; -#else - vec3 base = linear_to_srgb(diffuse.rgb); -#endif float perceptualRough = packedORM.g; // NOTE: do NOT clamp here to be consistent with Blender, Blender is wrong and Substance is right + vec3 c_diff, reflect0, reflect90; float alphaRough, specWeight; - initMaterial( base, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight ); -#if DEBUG_PBR_REFLECTANCE - float reflectance = max( max( reflect0.r, reflect0.g ), reflect0.b ); -#endif - - // 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); + initMaterial( diffuse.rgb, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight ); - // 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 DEBUG_PBR_IRRADIANCE_RAW - vec3 debug_irradiance = irradiance; -#endif - -#if PBR_USE_DEFAULT_IRRADIANCE - vec2 iruv = vec2(0.5f + 0.5f * atan(reflectVN.z, reflectVN.x) / M_PI, 1.f - acos(reflectVN.y) / M_PI); - irradiance = texture2D(altDiffuseMap, iruv).rgb * ambocc; -#endif -#if PBR_USE_IRRADIANCE_HACK + vec3 irradiance = vec3(0); + vec3 radiance = vec3(0); + sampleReflectionProbes(irradiance, radiance, legacyenv, pos.xyz, norm.xyz, gloss, 0.0); irradiance = max(amblit,irradiance) * ambocc; -#endif -#if DEBUG_PBR_SPECLIGHT051 - specLight = vec3(0,0.5,1.0); - irradiance = specLight; -#endif - vec3 FssEssGGX = kSpec*vScaleBias.x + vScaleBias.y; -#if DEBUG_PBR_SPEC_IBL - vec3 debug_color_spec = specWeight * specLight * FssEssGGX; -#endif -#if PBR_USE_IBL - colorSpec += specWeight * specLight * FssEssGGX; -#endif - - // 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 = c_diff * (1.0 - FssEssLambert + FmsEms); -#if PBR_USE_IBL - colorDiffuse += (FmsEms + kDiffuse) * irradiance; -#endif - #if DEBUG_PBR_DIFFUSE_PRE_AO - vec3 debug_diffuse = colorDiffuse; - #endif - - colorDiffuse *= ao; // Occlusion -- NOTE: pbropaque will need occlusion_strength pre-multiplied into spec.r - colorSpec *= ao; - // Add in sun/moon reflection + pbrIbl(colorDiffuse, colorSpec, radiance, irradiance, ao, nv, perceptualRough, gloss, reflect0, c_diff); + + // Add in sun/moon punctual light if (nl > 0.0 || nv > 0.0) { - float scale = 4.9; - vec3 sunColor = srgb_to_linear(sunlit * scale); // NOTE: Midday should have strong sunlight -#if DEBUG_PBR_SUN_FULL_BRIGHT - sunColor = vec3(1); -#endif - // scol = sun shadow - vec3 intensity = ambocc * sunColor * nl * scol; -#if PBR_USE_LINEAR_ALBEDO - vec3 sunDiffuse = intensity * BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh); - vec3 sunSpec = intensity * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh); -#else - vec3 sunDiffuse = base * intensity * BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh); - vec3 sunSpec = intensity * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh); -#endif - // Disabling PBR bloom due to two reasons: - // 1. The glTF 2.0 Specification does not specify bloom, - // 2. As the camera moves there are lots of bloom shimmering. - //bloom = dot(sunSpec, sunSpec) / (scale * scale * scale); - - #if DEBUG_PBR_SUN_SPEC_FRESNEL - colorDiffuse = vec3(0); - colorSpec = fresnelSchlick( reflect0, reflect90, vh ); - bloom = 0; - #endif - #if DEBUG_PBR_SUN_SPEC_D - colorDiffuse = vec3(0); - colorSpec = vec3(D_GGX( nh, alphaRough )); - bloom = 0; - #endif - #if DEBUG_PBR_SUN_SPEC_V - colorDiffuse = vec3(0); - colorSpec = vec3(V_GGX( nl, nv, alphaRough )); - bloom = 0; - #endif - #if DEBUG_PBR_SUN_SPEC_DF - colorDiffuse = vec3(0); - colorSpec = fresnelSchlick( reflect0, reflect90, vh ); - colorSpec *= D_GGX( nh, alphaRough ); - bloom = 0; - #endif - #if DEBUG_PBR_SUN_SPEC_DV - colorDiffuse = vec3(0); - colorSpec = vec3(D_GGX( nh, alphaRough )); - colorSpec *= vec3(V_GGX( nl, nv, alphaRough )); - bloom = 0; - #endif - #if DEBUG_PBR_SUN_SPEC_FV - colorDiffuse = vec3(0); - colorSpec = fresnelSchlick( reflect0, reflect90, vh ); - colorSpec *= V_GGX( nl, nv, alphaRough ); - bloom = 0; - #endif - #if DEBUG_PBR_SUN_SPEC_DFV - colorDiffuse = vec3(0); - colorSpec = fresnelSchlick( reflect0, reflect90, vh ); - colorSpec *= D_GGX( nh, alphaRough ); - colorSpec *= V_GGX( nl, nv, alphaRough ); - bloom = 0; - #endif - #if DEBUG_PBR_SUN_SPEC_NL_DFV - colorDiffuse = vec3(0); - colorSpec = nl * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh); - #endif - #if DEBUG_PBR_SUN_FINAL - colorDiffuse = nl * BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh); - colorSpec = nl * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh); - #endif - - #if DEBUG_PBR_SUN_OUT_DIFFUSE - colorDiffuse = linear_to_srgb(sunDiffuse); - colorSpec = vec3(0); - bloom = 0.0; - #endif - #if DEBUG_PBR_SUN_OUT_SPECULAR - colorDiffuse = linear_to_srgb(sunSpec); - colorSpec = vec3(0); - #endif - #if DEBUG_PBR_SUN_REFLECT0 - colorDiffuse = reflect0; - colorSpec = vec3(0); - #endif - -#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); } -#if DEBUG_PBR_SUN_LAMBERT - colorDiffuse = BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh); - colorSpec = vec3(0); - bloom = 0; -#endif -#if DEBUG_PBR_SUN_LAMBERT_NL - colorDiffuse = nl * BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh); - colorSpec = vec3(0); - bloom = 0; -#endif - - #if DEBUG_PBR_SUN_H - colorDiffuse = h*0.5 + 0.5; colorSpec = vec3(0); - #endif - #if DEBUG_PBR_SUN_L - colorDiffuse = l*0.5 + 0.5; colorSpec = vec3(0); - #endif - #if DEBUG_PBR_SUN_V - colorDiffuse = v*0.5 + 0.5; colorSpec = vec3(0); - #endif - #if DEBUG_PBR_SUN_NH - colorDiffuse = colorize_dot(nh); colorSpec = vec3(0); - #endif - #if DEBUG_PBR_SUN_NL - colorDiffuse = colorize_dot(nl); colorSpec = vec3(0); - #endif - #if DEBUG_PBR_SUN_NV - colorDiffuse = colorize_dot(nv); colorSpec = vec3(0); - #endif - #if DEBUG_PBR_SUN_VH - colorDiffuse = colorize_dot(vh); colorSpec = vec3(0); - #endif - color.rgb = colorDiffuse + colorEmissive + colorSpec; -#if PBR_USE_ATMOS color = linear_to_srgb(color); color *= atten.r; color += 2.0*additive; color = scaleSoftClipFrag(color); color = srgb_to_linear(color); -#endif // PBR_USE_ATMOS - - #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_NORMAL_MAP - color.rgb = diffuse.rgb; - #endif - #if DEBUG_PBR_OCCLUSION - color.rgb = vec3(ao); - #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*0.5 + vec3(0.5); - color.rgb = srgb_to_linear(color.rgb); - #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(nv); - #endif - #if DEBUG_PBR_DOT_TV - color.rgb = vec3(tv); - #endif - #if DEBUG_PBR_DOT_BV - color.rgb = vec3(bv); - #endif - - #if DEBUG_PBR_AVG - color.rgb = avg; - #endif - #if DEBUG_PBR_BRDF_UV - color.rgb = vec3(brdfPoint,0.0); - color.rgb = linear_to_srgb(color.rgb); - #endif - #if DEBUG_PBR_BRDF_SCALE_BIAS - color.rgb = vec3(vScaleBias,0.0); - #endif - #if DEBUG_PBR_DIFFUSE_C - color.rgb = c_diff; - #endif - #if DEBUG_PBR_BRDF_SCALE_ONLY - color.rgb = vec3(vScaleBias.x); - #endif - #if DEBUG_PBR_BRDF_BIAS_ONLY - color.rgb = vec3(vScaleBias.y); - #endif - #if DEBUG_PBR_DIFFUSE_K - color.rgb = kDiffuse; - #endif - #if DEBUG_PBR_DIFFUSE_MAP - color.rgb = diffuse.rgb; - #endif - #if DEBUG_PBR_DIFFUSE_PRE_AO - color.rgb = debug_diffuse; - #endif - #if DEBUG_PBR_EMS - color.rgb = vec3(Ems); - #endif - #if DEBUG_PBR_EMS_AVG - color.rgb = AvgEms; - #endif - #if DEBUG_PBR_FMS_EMS - color.rgb = FmsEms; - #endif - #if DEBUG_PBR_FSS_ESS_GGX - color.rgb = FssEssGGX; // spec - #endif - #if DEBUG_PBR_FSS_ESS_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_RAW - color.rgb = debug_irradiance; - bloom = 0; - #endif - #if DEBUG_PBR_IRRADIANCE - color.rgb = irradiance; - bloom = 0; - #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_REFLECTION_DIR - color.rgb = reflect(-v, n); // NOTE: equivalent to normalize(reflect(pos.xyz, norm.xyz)); - #endif - #if DEBUG_PBR_SPEC - color.rgb = colorSpec; - #endif - #if DEBUG_PBR_SPEC_REFLECTION - color.rgb = specLight; - #endif - #if DEBUG_PBR_SPEC_WEIGHT - color.rgb = vec3(specWeight); - #endif - #if DEBUG_PBR_V2C_RAW - color.rgb = v; - #endif - #if DEBUG_PBR_V2C_REMAP - color.rgb = v*0.5 + vec3(0.5); - #endif - - #if DEBUG_PBR_DA_RAW - color.rgb = vec3(debug_da); - #endif - #if DEBUG_PBR_DA_POW - color.rgb = vec3(da); - #endif - #if DEBUG_PBR_SKY_ADDITIVE - color.rgb = additive; - #endif - #if DEBUG_PBR_SKY_ATTEN - color.rgb = vec3(atten.r); - #endif - #if DEBUG_PBR_SUN_LIT - color.rgb = sunlit; - #endif - #if DEBUG_PBR_SUN_CONTRIB - color.rgb = sun_contrib; - #endif - #if DEBUG_PBR_LIGHT_TYPE - color.rgb = vec3(0); - #endif - - frag_color.rgb = color.rgb; // PBR is done in linear + frag_color.rgb = color.rgb; //output linear since local lights will be added to this shader's results } -else -{ - float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0); -#if DEBUG_PBR_DA_RAW - float debug_da = da; -#endif - da = pow(da, light_gamma); + else + { + float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0); + da = pow(da, light_gamma); - diffuse.rgb = linear_to_srgb(diffuse.rgb); // SL-14035 + diffuse.rgb = linear_to_srgb(diffuse.rgb); // SL-14035 - sampleReflectionProbes(ambenv, glossenv, legacyenv, pos.xyz, norm.xyz, spec.a, envIntensity); - ambenv.rgb = linear_to_srgb(ambenv.rgb); - glossenv.rgb = linear_to_srgb(glossenv.rgb); - legacyenv.rgb = linear_to_srgb(legacyenv.rgb); + sampleReflectionProbes(ambenv, glossenv, legacyenv, pos.xyz, norm.xyz, spec.a, envIntensity); + ambenv.rgb = linear_to_srgb(ambenv.rgb); + glossenv.rgb = linear_to_srgb(glossenv.rgb); + legacyenv.rgb = linear_to_srgb(legacyenv.rgb); - amblit = max(ambenv, amblit); - color.rgb = amblit*ambocc; + 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; - vec3 sun_contrib = min(da, scol) * sunlit; - color.rgb += sun_contrib; - color.rgb = min(color.rgb, vec3(1,1,1)); - color.rgb *= diffuse.rgb; + vec3 refnormpersp = reflect(pos.xyz, norm.xyz); - 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); - 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 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); + } - // add reflection map - EXPERIMENTAL WORK IN PROGRESS - applyGlossEnv(color, glossenv, spec, pos.xyz, norm.xyz); - } + color.rgb = mix(color.rgb, diffuse.rgb, diffuse.a); - 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 (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); + } - 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 = ambenv; + //color.b = diffuse.a; + frag_color.rgb = srgb_to_linear(color.rgb); } -#ifdef WATER_FOG - vec4 fogged = applyWaterFogView(pos.xyz, vec4(color, bloom)); - color = fogged.rgb; - bloom = fogged.a; -#endif - #if DEBUG_PBR_LIGHT_TYPE - color.rgb = vec3(0); - #endif - // convert to linear as fullscreen lights need to sum in linear colorspace - // and will be gamma (re)corrected downstream... - //color = ambenv; - //color.b = diffuse.a; - frag_color.rgb = srgb_to_linear(color.rgb); -} -#if DEBUG_PBR_AMBOCC - frag_color.rgb = vec3(ambocc); -#endif -#if DEBUG_PBR_AMBENV - frag_color.rgb = ambenv; -#endif frag_color.a = bloom; } diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index ee085a65c2..b992ab0394 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -617,7 +617,12 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged) if (is_pbr && gltf_mat->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_BLEND) { - target_shader = &gDeferredPBRAlphaProgram[rigged]; + target_shader = &gDeferredPBRAlphaProgram; + if (params.mAvatar != nullptr) + { + target_shader = target_shader->mRiggedVariant; + } + if (current_shader != target_shader) { gPipeline.bindDeferredShader(*target_shader); @@ -662,9 +667,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged) target_shader->uniform1f(LLShaderMgr::ROUGHNESS_FACTOR, params.mGLTFMaterial->mRoughnessFactor); target_shader->uniform1f(LLShaderMgr::METALLIC_FACTOR, params.mGLTFMaterial->mMetallicFactor); target_shader->uniform3fv(LLShaderMgr::EMISSIVE_COLOR, 1, params.mGLTFMaterial->mEmissiveColor.mV); - - target_shader->mLightHash = 0; - gGL.syncLightState(); // Set light uniforms } else { diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 391cfab5c0..2ebe0f826f 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -265,7 +265,8 @@ LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2]; LLGLSLShader gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2]; LLGLSLShader gDeferredPBROpaqueProgram; LLGLSLShader gDeferredSkinnedPBROpaqueProgram; -LLGLSLShader gDeferredPBRAlphaProgram[2]; // not skinned, skinned +LLGLSLShader gDeferredPBRAlphaProgram; +LLGLSLShader gDeferredSkinnedPBRAlphaProgram; //helper for making a rigged variant of a given shader bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader) @@ -374,7 +375,10 @@ LLViewerShaderMgr::LLViewerShaderMgr() : mShaderList.push_back(&gDeferredWLSkyProgram); mShaderList.push_back(&gDeferredWLCloudProgram); mShaderList.push_back(&gDeferredWLMoonProgram); - mShaderList.push_back(&gDeferredWLSunProgram); + mShaderList.push_back(&gDeferredWLSunProgram); + mShaderList.push_back(&gDeferredPBRAlphaProgram); + mShaderList.push_back(&gDeferredSkinnedPBRAlphaProgram); + } LLViewerShaderMgr::~LLViewerShaderMgr() @@ -1284,8 +1288,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredPBROpaqueProgram.unload(); gDeferredSkinnedPBROpaqueProgram.unload(); - gDeferredPBRAlphaProgram[0].unload(); - gDeferredPBRAlphaProgram[1].unload(); + gDeferredPBRAlphaProgram.unload(); + gDeferredSkinnedPBRAlphaProgram.unload(); return TRUE; } @@ -1622,76 +1626,70 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { - for (int rigged = 0; rigged < 2 && success; ++rigged) - { - LLGLSLShader* shader = &gDeferredPBRAlphaProgram[rigged]; - shader->mName = rigged - ? "Skinned Deferred PBR Alpha Shader" - : "Deferred PBR Alpha Shader"; - shader->mRiggedVariant = rigged - ? &gDeferredPBRAlphaProgram[1] - : nullptr; - shader->mFeatures.hasObjectSkinning = (bool)rigged; - shader->mFeatures.calculatesLighting = false; - shader->mFeatures.hasLighting = false; - shader->mFeatures.isAlphaLighting = true; - shader->mFeatures.hasSrgb = true; - shader->mFeatures.encodesNormal = true; - shader->mFeatures.calculatesAtmospherics = true; - shader->mFeatures.hasAtmospherics = true; - shader->mFeatures.hasGamma = true; - shader->mFeatures.hasTransport = true; - shader->mFeatures.hasShadows = use_sun_shadow; - shader->mFeatures.isDeferred = true; // include deferredUtils - shader->mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED]; - - shader->mShaderFiles.clear(); - shader->mShaderFiles.push_back(make_pair("deferred/pbralphaV.glsl", GL_VERTEX_SHADER_ARB)); - shader->mShaderFiles.push_back(make_pair("deferred/pbralphaF.glsl", GL_FRAGMENT_SHADER_ARB)); - - shader->clearPermutations(); + LLGLSLShader* shader = &gDeferredPBRAlphaProgram; + shader->mName = "Deferred PBR Alpha Shader"; + + shader->mFeatures.calculatesLighting = false; + shader->mFeatures.hasLighting = false; + shader->mFeatures.isAlphaLighting = true; + shader->mFeatures.hasSrgb = true; + shader->mFeatures.encodesNormal = true; + shader->mFeatures.calculatesAtmospherics = true; + shader->mFeatures.hasAtmospherics = true; + shader->mFeatures.hasGamma = true; + shader->mFeatures.hasTransport = true; + shader->mFeatures.hasShadows = use_sun_shadow; + shader->mFeatures.isDeferred = true; // include deferredUtils + shader->mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED]; + + shader->mShaderFiles.clear(); + shader->mShaderFiles.push_back(make_pair("deferred/pbralphaV.glsl", GL_VERTEX_SHADER_ARB)); + shader->mShaderFiles.push_back(make_pair("deferred/pbralphaF.glsl", GL_FRAGMENT_SHADER_ARB)); + + shader->clearPermutations(); + + U32 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; + shader->addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode)); + shader->addPermutation("HAS_NORMAL_MAP", "1"); + shader->addPermutation("HAS_SPECULAR_MAP", "1"); // PBR: Packed: Occlusion, Metal, Roughness + shader->addPermutation("HAS_EMISSIVE_MAP", "1"); + shader->addPermutation("USE_VERTEX_COLOR", "1"); - U32 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; - shader->addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode)); - shader->addPermutation("HAS_NORMAL_MAP", "1"); - shader->addPermutation("HAS_SPECULAR_MAP", "1"); // PBR: Packed: Occlusion, Metal, Roughness - shader->addPermutation("HAS_EMISSIVE_MAP", "1"); - shader->addPermutation("USE_VERTEX_COLOR", "1"); - if (use_sun_shadow) - { - shader->addPermutation("HAS_SHADOW", "1"); - } - - if (ambient_kill) - { - shader->addPermutation("AMBIENT_KILL", "1"); - } - - if (sunlight_kill) - { - shader->addPermutation("SUNLIGHT_KILL", "1"); - } + if (use_sun_shadow) + { + shader->addPermutation("HAS_SHADOW", "1"); + } - if (local_light_kill) - { - shader->addPermutation("LOCAL_LIGHT_KILL", "1"); - } + if (ambient_kill) + { + shader->addPermutation("AMBIENT_KILL", "1"); + } - if (rigged) - { - shader->addPermutation("HAS_SKIN", "1"); - } + if (sunlight_kill) + { + shader->addPermutation("SUNLIGHT_KILL", "1"); + } - shader->mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + if (local_light_kill) + { + shader->addPermutation("LOCAL_LIGHT_KILL", "1"); + } + shader->mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = make_rigged_variant(*shader, gDeferredSkinnedPBRAlphaProgram); + if (success) + { success = shader->createShader(NULL, NULL); - llassert(success); - - // Alpha Shader Hack - // See: LLRender::syncMatrices() - shader->mFeatures.calculatesLighting = true; - shader->mFeatures.hasLighting = true; } + llassert(success); + + // Alpha Shader Hack + // See: LLRender::syncMatrices() + shader->mFeatures.calculatesLighting = true; + shader->mFeatures.hasLighting = true; + + shader->mRiggedVariant->mFeatures.calculatesLighting = true; + shader->mRiggedVariant->mFeatures.hasLighting = true; } diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 38f67cd23c..19d8e87d66 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -322,5 +322,5 @@ extern LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2]; extern LLGLSLShader gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2]; extern LLGLSLShader gDeferredPBROpaqueProgram; -extern LLGLSLShader gDeferredPBRAlphaProgram[2]; // not skinned, skinned +extern LLGLSLShader gDeferredPBRAlphaProgram; #endif |