From c700b95c8d4aed5605b28c901a49a7287725e9cb Mon Sep 17 00:00:00 2001 From: Santi Paprika Date: Thu, 23 Dec 2021 15:33:00 +0100 Subject: [PATCH] Avoid mode-specific transmission distance initialization (potential fix for https://github.com/o3de/o3de/pull/6428#discussion_r774259781) Signed-off-by: Santi Paprika --- .../PBR/Lights/DirectionalLight.azsli | 20 +++--- .../Atom/Features/PBR/Lights/DiskLight.azsli | 61 ++++++++++--------- .../Atom/Features/PBR/Lights/PointLight.azsli | 25 ++++---- 3 files changed, 53 insertions(+), 53 deletions(-) diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/DirectionalLight.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/DirectionalLight.azsli index ffac82232f..d2aeb4b5f8 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/DirectionalLight.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/DirectionalLight.azsli @@ -19,7 +19,8 @@ void ApplyDirectionalLights(Surface surface, inout LightingData lightingData) const uint shadowIndex = ViewSrg::m_shadowIndexDirectionalLight; float litRatio = 1.0f; float camToSurfDist = distance(ViewSrg::m_worldPosition, surface.position); - // Transmission distance inside object + + // Distance travelled by the light inside the object float transmissionDistance = 0.0f; if (o_enableShadows && shadowIndex < SceneSrg::m_directionalLightCount) @@ -69,28 +70,25 @@ void ApplyDirectionalLights(Surface surface, inout LightingData lightingData) float currentLitRatio = 1.0f; // Transmission distance from current light inside object (default non-influential values) - // o_transmission_mode == NONE is not taken into account because GetBackLighting already ignores this case - float currentTransmissionDistance = (o_transmission_mode == TransmissionMode::ThickObject) ? 0.0f : 9999.0f; if (o_enableShadows) { bool activeLight = index == shadowIndex; + + // Add contribution only if current directional light is the active one for shadows currentLitRatio = activeLight ? litRatio : 1.; if (activeLight) { - // Transmission distance (add contribution only if current directional light is the active one for shadows) - currentTransmissionDistance = transmissionDistance; + float3 backLighting = GetBackLighting(surface, lightingData, light.m_rgbIntensityLux, dirToLight, transmissionDistance); + + // Attenuation applied to hide artifacts due to low-res shadow maps (might need some work in the future) + float attenuation = 1.0 / pow(max(1.0, camToSurfDist/2.0), lightingData.distanceAttenuation + 1.0); + lightingData.translucentBackLighting += backLighting * attenuation; } } lightingData.diffuseLighting += GetDiffuseLighting(surface, lightingData, light.m_rgbIntensityLux, dirToLight) * currentLitRatio; lightingData.specularLighting += GetSpecularLighting(surface, lightingData, light.m_rgbIntensityLux, dirToLight) * currentLitRatio; - float3 backLighting = GetBackLighting(surface, lightingData, light.m_rgbIntensityLux, dirToLight, currentTransmissionDistance); - - // Attenuation applied to hide artifacts due to low-res shadow maps (might need some work in the future) - float attenuation = 1.0 / pow(max(1.0, camToSurfDist/2.0), lightingData.distanceAttenuation + 1.0); - - lightingData.translucentBackLighting += backLighting * attenuation; } // Add debug coloring for directional light shadow diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/DiskLight.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/DiskLight.azsli index 209a6af823..9d4e503df6 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/DiskLight.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/DiskLight.azsli @@ -76,28 +76,6 @@ void ApplyDiskLight(ViewSrg::DiskLight light, Surface surface, inout LightingDat // shadow float litRatio = 1.0; - - // Transmission distance from current light inside object (default non-influential values) - // o_transmission_mode == NONE is not taken into account because GetBackLighting already ignores this case - float transmissionDistance = (o_transmission_mode == TransmissionMode::ThickObject) ? 0.0f : 9999.0f; - if (o_enableShadows) - { - litRatio = ProjectedShadow::GetVisibility( - light.m_shadowIndex, - light.m_position, - surface.position, - -dirToConeTip, - surface.vertexNormal); - - if (o_transmission_mode == TransmissionMode::ThickObject) - { - transmissionDistance = ProjectedShadow::GetThickness(light.m_shadowIndex, surface.position); - } - else if (o_transmission_mode == TransmissionMode::ThinObject) - { - transmissionDistance = ProjectedShadow::GetThickness(light.m_shadowIndex, surface.position - lightingData.shrinkFactor * surface.vertexNormal); - } - } if (useConeAngle && dotWithDirection < light.m_cosInnerConeAngle) // in penumbra { @@ -110,17 +88,40 @@ void ApplyDiskLight(ViewSrg::DiskLight light, Surface surface, inout LightingDat lightIntensity *= penumbraMask; } + if (o_enableShadows) + { + litRatio = ProjectedShadow::GetVisibility( + light.m_shadowIndex, + light.m_position, + surface.position, + -dirToConeTip, + surface.vertexNormal); + + // Distance travelled by the light inside the object + float transmissionDistance = 0.0f; + + // o_transmission_mode == NONE is not taken into account because GetBackLighting already ignores this case + if (o_transmission_mode == TransmissionMode::ThickObject) + { + transmissionDistance = ProjectedShadow::GetThickness(light.m_shadowIndex, surface.position); + } + else if (o_transmission_mode == TransmissionMode::ThinObject) + { + transmissionDistance = ProjectedShadow::GetThickness(light.m_shadowIndex, surface.position - lightingData.shrinkFactor * surface.vertexNormal); + } + + // Attenuation applied to hide artifacts due to low-res shadow maps (might need some work in the future) + float attenuation = 1.0 / pow(max(1.0, sqrt(distanceToLight2)), lightingData.distanceAttenuation + 1.0); + + // Transmission contribution + float3 backLighting = GetBackLighting(surface, lightingData, lightIntensity, posToLightDir, transmissionDistance); + + lightingData.translucentBackLighting += backLighting * attenuation; + } + // Diffuse contribution lightingData.diffuseLighting += GetDiffuseLighting(surface, lightingData, lightIntensity, posToLightDir) * litRatio; - // Transmission contribution - float3 backLighting = GetBackLighting(surface, lightingData, lightIntensity, posToLightDir, transmissionDistance); - - // Attenuation applied to hide artifacts due to low-res shadow maps (might need some work in the future) - float attenuation = 1.0 / pow(max(1.0, sqrt(distanceToLight2)), lightingData.distanceAttenuation + 1.0); - - lightingData.translucentBackLighting += backLighting * attenuation; - // Adjust the light direction for specular based on disk size // Calculate the reflection off the normal from the view direction diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli index 2eb815410d..e2297fd3d3 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli @@ -85,9 +85,6 @@ void ApplyPointLight(ViewSrg::PointLight light, Surface surface, inout LightingD // shadow float litRatio = 1.0; - // Transmission distance from current light inside object (default non-influential values) - // o_transmission_mode == NONE is not taken into account because GetBackLighting already ignores this case - float transmissionDistance = (o_transmission_mode == TransmissionMode::ThickObject) ? 0.0f : 9999.0f; if (o_enableShadows) { const float3 lightDir = normalize(light.m_position - surface.position); @@ -99,6 +96,10 @@ void ApplyPointLight(ViewSrg::PointLight light, Surface surface, inout LightingD lightDir, surface.vertexNormal); + // Distance travelled by the light inside the object + float transmissionDistance = 0.0f; + + // o_transmission_mode == NONE is not taken into account because GetBackLighting already ignores this case if (o_transmission_mode == TransmissionMode::ThickObject) { transmissionDistance = ProjectedShadow::GetThickness(shadowIndex, surface.position); @@ -106,20 +107,20 @@ void ApplyPointLight(ViewSrg::PointLight light, Surface surface, inout LightingD else if (o_transmission_mode == TransmissionMode::ThinObject) { transmissionDistance = ProjectedShadow::GetThickness(shadowIndex, surface.position - lightingData.shrinkFactor * surface.vertexNormal); - } + } + + // Transmission contribution + float3 backLighting = GetBackLighting(surface, lightingData, lightIntensity, normalize(posToLight), transmissionDistance); + + // Attenuation applied to hide artifacts due to low-res shadow maps (might need some work in the future) + float attenuation = 1.0 / pow(max(1.0, posToLightDist), lightingData.distanceAttenuation + 1.0); + + lightingData.translucentBackLighting += backLighting * attenuation; } // Diffuse contribution lightingData.diffuseLighting += GetDiffuseLighting(surface, lightingData, lightIntensity, normalize(posToLight)) * litRatio; - // Transmission contribution - float3 backLighting = GetBackLighting(surface, lightingData, lightIntensity, normalize(posToLight), transmissionDistance); - - // Attenuation applied to hide artifacts due to low-res shadow maps (might need some work in the future) - float attenuation = 1.0 / pow(max(1.0, posToLightDist), lightingData.distanceAttenuation + 1.0); - - lightingData.translucentBackLighting += backLighting * attenuation; - // Adjust the light direcion for specular based on bulb size // Calculate the reflection off the normal from the view direction