From 6a0b8ae6b6ed98012d0a68c9903c7d0c58b64ca8 Mon Sep 17 00:00:00 2001 From: Ken Pruiksma Date: Thu, 1 Jul 2021 21:50:01 -0500 Subject: [PATCH] [ATOM-15854] Adjusting alpha on grazing angles so it doesn't affect the diffuse response. (#1708) Signed-off-by: Ken Pruiksma --- .../Types/EnhancedPBR_ForwardPass.azsl | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl index 87afd1936d..4150d213a0 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl @@ -324,16 +324,21 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float // Finalize Lighting lightingData.FinalizeLighting(surface.transmission.tint); + PbrLightingOutput lightingOutput = GetPbrLightingOutput(surface, lightingData, alpha); + + // ------- Opacity ------- + if (o_opacity_mode == OpacityMode::Blended || o_opacity_mode == OpacityMode::TintedTransparent) { - float fresnelAlpha = FresnelSchlickWithRoughness(lightingData.NdotV, alpha, surface.roughnessLinear).x; // Increase opacity at grazing angles. + // Increase opacity at grazing angles for surfaces with a low m_opacityAffectsSpecularFactor. + // For m_opacityAffectsSpecularFactor values close to 0, that indicates a transparent surface + // like glass, so it becomes less transparent at grazing angles. For m_opacityAffectsSpecularFactor + // values close to 1.0, that indicates the absence of a surface entirely, so this effect should + // not apply. + float fresnelAlpha = FresnelSchlickWithRoughness(lightingData.NdotV, alpha, surface.roughnessLinear).x; alpha = lerp(fresnelAlpha, alpha, MaterialSrg::m_opacityAffectsSpecularFactor); } - PbrLightingOutput lightingOutput = GetPbrLightingOutput(surface, lightingData, alpha); - - // ------- Opacity ------- - // Note: lightingOutput rendertargets are not always used as named, particularly m_diffuseColor (target 0) and // m_specularColor (target 1). Comments below describe the differences when appropriate. @@ -347,11 +352,13 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float // It's done this way because surface transparency doesn't really change specular response (eg, glass). lightingOutput.m_diffuseColor.rgb *= lightingOutput.m_diffuseColor.w; // pre-multiply diffuse - + // Add specular. m_opacityAffectsSpecularFactor controls how much the alpha masks out specular contribution. float3 specular = lightingOutput.m_specularColor.rgb; specular = lerp(specular, specular * lightingOutput.m_diffuseColor.w, MaterialSrg::m_opacityAffectsSpecularFactor); lightingOutput.m_diffuseColor.rgb += specular; + + lightingOutput.m_diffuseColor.w = alpha; } else if (o_opacity_mode == OpacityMode::TintedTransparent) { @@ -374,7 +381,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float specular = lerp(specular, specular * lightingOutput.m_diffuseColor.w, MaterialSrg::m_opacityAffectsSpecularFactor); lightingOutput.m_diffuseColor.rgb += specular; - lightingOutput.m_specularColor.rgb = baseColor * (1.0 - lightingOutput.m_diffuseColor.w); + lightingOutput.m_specularColor.rgb = baseColor * (1.0 - alpha); } else {