From 97c36a71a26a92b98fa33fe42fa4edacc31cd155 Mon Sep 17 00:00:00 2001 From: Santi Paprika Date: Thu, 2 Dec 2021 17:49:26 +0100 Subject: [PATCH] Move directional shadow coordinates computation to PS + Fix clamp values Signed-off-by: Santi Paprika --- .../Common/Assets/Materials/Types/Skin.azsl | 15 +++++---------- .../Atom/Features/PBR/BackLighting.azsli | 2 +- .../Atom/Features/PBR/Lighting/LightingData.azsli | 3 +++ .../Features/PBR/Lights/DirectionalLight.azsli | 8 ++++++++ 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.azsl index 2e861a61bb..4908e736f4 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.azsl @@ -92,7 +92,6 @@ struct VSOutput float3 m_bitangent : BITANGENT; float3 m_worldPosition : UV0; float3 m_shadowCoords[ViewSrg::MaxCascadeCount] : UV4; - float3 m_shrinkedShadowCoords[ViewSrg::MaxCascadeCount] : UV9; // Extended fields (only referenced in this azsl file)... float2 m_uv[UvSetCount] : UV1; @@ -137,14 +136,6 @@ VSOutput SkinVS(VSInput IN) } VertexHelper(IN, OUT, worldPosition, false); - - // Fetch shadow coords for shrinked world position (used in thin transmission materials) - const uint shadowIndex = ViewSrg::m_shadowIndexDirectionalLight; - DirectionalLightShadow::GetShadowCoords( - shadowIndex, - worldPosition - MaterialSrg::m_shrinkFactor * OUT.m_normal, - OUT.m_normal, - OUT.m_shrinkedShadowCoords); return OUT; } @@ -345,15 +336,19 @@ PbrLightingOutput SkinPS_Common(VSOutput IN) // Directional light shadow coordinates lightingData.shadowCoords = IN.m_shadowCoords; - lightingData.shrinkedShadowCoords = IN.m_shrinkedShadowCoords; // Diffuse and Specular response (used in IBL calculations) lightingData.specularResponse = FresnelSchlickWithRoughness(lightingData.NdotV, surface.specularF0, surface.roughnessLinear); lightingData.diffuseResponse = 1.0 - lightingData.specularResponse; + // ------- Thin Object Light Transmission ------- + // Angle offset for subsurface scattering through thin objects lightingData.angleOffset = MaterialSrg::m_angleOffset; + // Shrink (absolute) offset towards the normal opposite direction to ensure correct shadow map projection + lightingData.shrinkFactor = MaterialSrg::m_shrinkFactor; + // ------- Occlusion ------- lightingData.diffuseAmbientOcclusion = GetOcclusionInput(MaterialSrg::m_diffuseOcclusionMap, MaterialSrg::m_sampler, IN.m_uv[MaterialSrg::m_diffuseOcclusionMapUvIndex], MaterialSrg::m_diffuseOcclusionFactor, o_diffuseOcclusion_useTexture); diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/BackLighting.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/BackLighting.azsli index 0e39739fcb..cd2ce763e4 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/BackLighting.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/BackLighting.azsli @@ -65,7 +65,7 @@ float3 GetBackLighting(Surface surface, LightingData lightingData, float3 lightI { // Irradiance arround surface point. // Begin the transmittance dot product slightly before it would with the regular dot(N,L) - float E = saturate(lightingData.angleOffset + dot(-surface.normal, dirToLight)); + float E = max(lightingData.angleOffset + dot(-surface.normal, dirToLight),0.0); // Transmission distance computed from shadowmaps modulated by editor-exposed parameters float s = transmissionDistance * surface.transmission.thickness * (100 - transmissionParams.w) * 10; diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lighting/LightingData.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lighting/LightingData.azsli index 7ca8a797a8..8f3bca703e 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lighting/LightingData.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lighting/LightingData.azsli @@ -33,6 +33,9 @@ class LightingData // Angle to accept below (N . L = 0) in scattering through thin objects float angleOffset; + + // Shrink (absolute) offset towards the normal opposite direction to ensure correct shadow map projection + float shrinkFactor; // Normalized direction from surface to camera float3 dirToCamera; 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 82bad459cf..d7fa77d701 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 @@ -29,6 +29,14 @@ void ApplyDirectionalLights(Surface surface, inout LightingData lightingData) lightingData.shadowCoords, surface.vertexNormal, debugInfo); + + // Fetch shadow coords for shrinked world position (used in thin transmission materials) + float3 shrinkedShadowCoords[ViewSrg::MaxCascadeCount]; + DirectionalLightShadow::GetShadowCoords( + shadowIndex, + surface.position - lightingData.shrinkFactor * surface.normal, + surface.normal, + lightingData.shrinkedShadowCoords); if (o_transmission_mode == TransmissionMode::ThickObject) {