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 dfd06a57ff..95482d432f 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 @@ -15,64 +15,62 @@ #include #include -int GetShadowDirectionIndex(float3 targetPos, float3 lightPos) +int GetShadowDirectionIndex(const float3 targetPos, const float3 lightPos) { - float3 toPoint = targetPos - lightPos; - toPoint = normalize(toPoint); - - const float maxElement = max(abs(toPoint.z), max(abs(toPoint.x), abs(toPoint.y))); - if (toPoint.x == -maxElement) - { - return 0; - } - else if (toPoint.x == maxElement) - { - return 1; - } - else if (toPoint.y == -maxElement) - { - return 2; - } - else if (toPoint.y == maxElement) - { - return 3; - } - else if (toPoint.z == -maxElement) - { - return 4; - } - else - { - return 5; - } + const float3 toPoint = targetPos - lightPos; + const float maxElement = max(abs(toPoint.z), max(abs(toPoint.x), abs(toPoint.y))); + if (toPoint.x == -maxElement) + { + return 0; + } + else if (toPoint.x == maxElement) + { + return 1; + } + else if (toPoint.y == -maxElement) + { + return 2; + } + else if (toPoint.y == maxElement) + { + return 3; + } + else if (toPoint.z == -maxElement) + { + return 4; + } + else + { + return 5; + } } -int GetShadowIndex(ViewSrg::PointLight light, int i) +int UnpackShadowIndex(const ViewSrg::PointLight light, const int i) { - if (i == 0) - { - return light.m_shadowIndices[0] & 0xFFFF; - } - else if (i==1) - { - return (light.m_shadowIndices[0] >> 16) & 0xFFFF; - } - else if (i==2) - { - return (light.m_shadowIndices[1]) & 0xFFFF; - } - else if (i==3) - { - return (light.m_shadowIndices[1] >> 16) & 0xFFFF; - } - else if (i==4) - { - return (light.m_shadowIndices[2]) & 0xFFFF; - } - else - { - return (light.m_shadowIndices[2] >> 16) & 0xFFFF; - } + if (i == 0) + { + return light.m_shadowIndices[0] & 0xFFFF; + } + else if (i==1) + { + return (light.m_shadowIndices[0] >> 16) & 0xFFFF; + } + else if (i==2) + { + return (light.m_shadowIndices[1]) & 0xFFFF; + } + else if (i==3) + { + return (light.m_shadowIndices[1] >> 16) & 0xFFFF; + } + else if (i==4) + { + return (light.m_shadowIndices[2]) & 0xFFFF; + } + else + { + return (light.m_shadowIndices[2] >> 16) & 0xFFFF; + } } void ApplyPointLight(ViewSrg::PointLight light, Surface surface, inout LightingData lightingData) @@ -99,16 +97,17 @@ void ApplyPointLight(ViewSrg::PointLight light, Surface surface, inout LightingD float backShadowRatio = 0.0; if (o_enableShadows) { - const float3 Directions[6] = {float3(-1,0,0), float3(1,0,0), float3(0,-1,0), float3(0,1,0), float3(0,0,-1), float3(0,0,1)}; - const int shadowDirectionIndex = GetShadowDirectionIndex(surface.position, light.m_position); - const int shadowIndex = GetShadowIndex(light, shadowDirectionIndex); - litRatio *= ProjectedShadow::GetVisibility( - shadowIndex, - light.m_position, - surface.position, - Directions[shadowDirectionIndex], - surface.normal); - + // The order should match m_pointShadowTransforms in PointLightFeatureProcessor.h/.cpp + const float3 PointShadowDirections[6] = {float3(-1,0,0), float3(1,0,0), float3(0,-1,0), float3(0,1,0), float3(0,0,-1), float3(0,0,1)}; + const int shadowDirectionIndex = GetShadowDirectionIndex(surface.position, light.m_position); + const int shadowIndex = UnpackShadowIndex(light, shadowDirectionIndex); + litRatio *= ProjectedShadow::GetVisibility( + shadowIndex, + light.m_position, + surface.position, + PointShadowDirections[shadowDirectionIndex], + surface.normal); + // Use backShadowRatio to carry thickness from shadow map for thick mode backShadowRatio = 1.0 - litRatio; if (o_transmission_mode == TransmissionMode::ThickObject) @@ -116,9 +115,8 @@ void ApplyPointLight(ViewSrg::PointLight light, Surface surface, inout LightingD backShadowRatio = ProjectedShadow::GetThickness( shadowIndex, surface.position); - } - - } + } + } // Diffuse contribution lightingData.diffuseLighting += GetDiffuseLighting(surface, lightingData, lightIntensity, normalize(posToLight)) * litRatio; diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp index 8480bec2ce..9a940ea7b0 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp @@ -44,12 +44,13 @@ namespace AZ PointLightFeatureProcessor::PointLightFeatureProcessor() : PointLightFeatureProcessorInterface() { - m_directions[0] = -AZ::Vector3::CreateAxisX(); - m_directions[1] = AZ::Vector3::CreateAxisX(); - m_directions[2] = -AZ::Vector3::CreateAxisY(); - m_directions[3] = AZ::Vector3::CreateAxisY(); - m_directions[4] = -AZ::Vector3::CreateAxisZ(); - m_directions[5] = AZ::Vector3::CreateAxisZ(); + // Note must match PointShadowDirections in PointLight.azsli + m_pointShadowTransforms[0] = AZ::Transform::CreateLookAt(AZ::Vector3::CreateZero(), -AZ::Vector3::CreateAxisX()); + m_pointShadowTransforms[1] = AZ::Transform::CreateLookAt(AZ::Vector3::CreateZero(), AZ::Vector3::CreateAxisX()); + m_pointShadowTransforms[2] = AZ::Transform::CreateLookAt(AZ::Vector3::CreateZero(), -AZ::Vector3::CreateAxisY()); + m_pointShadowTransforms[3] = AZ::Transform::CreateLookAt(AZ::Vector3::CreateZero(), AZ::Vector3::CreateAxisY()); + m_pointShadowTransforms[4] = AZ::Transform::CreateLookAt(AZ::Vector3::CreateZero(), -AZ::Vector3::CreateAxisZ()); + m_pointShadowTransforms[5] = AZ::Transform::CreateLookAt(AZ::Vector3::CreateZero(), AZ::Vector3::CreateAxisZ()); } void PointLightFeatureProcessor::Activate() @@ -241,10 +242,9 @@ namespace AZ } ProjectedShadowFeatureProcessorInterface::ProjectedShadowDescriptor desc = m_shadowFeatureProcessor->GetShadowProperties(shadowId); - Vector3 position = Vector3::CreateFromFloat3(pointLight.m_position.data()); - desc.m_fieldOfViewYRadians = DegToRad(90.5f); // Make it slightly larger than 90 degrees to avoid artifacts on the boundary between 2 cubemap faces - desc.m_transform = Transform::CreateLookAt(position, position + m_directions[i]); + desc.m_transform = m_pointShadowTransforms[i]; + desc.m_transform.SetTranslation(pointLight.m_position[0], pointLight.m_position[1], pointLight.m_position[2]); desc.m_aspectRatio = 1.0f; desc.m_nearPlaneDistance = 0.0f; diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.h index 437ebc2f0a..c0c377e960 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.h @@ -77,7 +77,7 @@ namespace AZ GpuBufferHandler m_lightBufferHandler; bool m_deviceBufferNeedsUpdate = false; - AZStd::array m_directions; + AZStd::array m_pointShadowTransforms; }; } // namespace Render } // namespace AZ