From 880f4d96cc7773e2378bd051b1dcfb1ee37b9989 Mon Sep 17 00:00:00 2001 From: dmcdiar Date: Wed, 15 Sep 2021 18:19:39 -0700 Subject: [PATCH 1/9] Changed the ReflectionProbe component to use an OBB Signed-off-by: dmcdiar --- .../Atom/Features/PBR/DefaultObjectSrg.azsli | 37 ++++++++++++-- .../Atom/Features/PBR/LightingUtils.azsli | 11 +++- .../Atom/Features/PBR/Lights/Ibl.azsli | 16 +++--- .../ReflectionProbeBlendWeight.azsl | 10 ++-- .../ReflectionProbeRenderCommon.azsli | 10 ++-- .../ReflectionProbeRenderInner.azsl | 2 +- .../ReflectionProbeRenderObjectSrg.azsli | 23 ++++++--- .../ReflectionProbeRenderOuter.azsl | 12 +++-- .../Code/Source/Mesh/MeshFeatureProcessor.cpp | 28 +++++------ .../ReflectionProbe/ReflectionProbe.cpp | 50 +++++++++---------- .../Source/ReflectionProbe/ReflectionProbe.h | 20 ++++---- .../ReflectionProbeFeatureProcessor.cpp | 40 +++++++-------- .../RPI/Assets/ShaderLib/Atom/RPI/Math.azsli | 16 ++++++ .../EditorReflectionProbeComponent.cpp | 7 +-- 14 files changed, 172 insertions(+), 110 deletions(-) diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/DefaultObjectSrg.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/DefaultObjectSrg.azsli index ccaf5cf5d0..7a2d2ee428 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/DefaultObjectSrg.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/DefaultObjectSrg.azsli @@ -40,11 +40,10 @@ ShaderResourceGroup ObjectSrg : SRG_PerObject //! Reflection Probe (smallest probe volume that overlaps the object position) struct ReflectionProbeData { - float3 m_aabbPos; - float3 m_outerAabbMin; - float3 m_outerAabbMax; - float3 m_innerAabbMin; - float3 m_innerAabbMax; + row_major float3x4 m_modelToWorld; + row_major float3x4 m_modelToWorldInverse; // does not include extents + float3 m_outerObbHalfLengths; + float3 m_innerObbHalfLengths; float m_padding; bool m_useReflectionProbe; bool m_useParallaxCorrection; @@ -52,4 +51,32 @@ ShaderResourceGroup ObjectSrg : SRG_PerObject ReflectionProbeData m_reflectionProbeData; TextureCube m_reflectionProbeCubeMap; + + float4x4 GetReflectionProbeWorldMatrix() + { + float4x4 modelToWorld = float4x4( + float4(1, 0, 0, 0), + float4(0, 1, 0, 0), + float4(0, 0, 1, 0), + float4(0, 0, 0, 1)); + + modelToWorld[0] = m_reflectionProbeData.m_modelToWorld[0]; + modelToWorld[1] = m_reflectionProbeData.m_modelToWorld[1]; + modelToWorld[2] = m_reflectionProbeData.m_modelToWorld[2]; + return modelToWorld; + } + + float4x4 GetReflectionProbeWorldMatrixInverse() + { + float4x4 modelToWorldInverse = float4x4( + float4(1, 0, 0, 0), + float4(0, 1, 0, 0), + float4(0, 0, 1, 0), + float4(0, 0, 0, 1)); + + modelToWorldInverse[0] = m_reflectionProbeData.m_modelToWorldInverse[0]; + modelToWorldInverse[1] = m_reflectionProbeData.m_modelToWorldInverse[1]; + modelToWorldInverse[2] = m_reflectionProbeData.m_modelToWorldInverse[2]; + return modelToWorldInverse; + } } diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/LightingUtils.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/LightingUtils.azsli index 503095020c..3248fc83eb 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/LightingUtils.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/LightingUtils.azsli @@ -50,10 +50,10 @@ float GetRoughnessMip(float roughness) return roughness * maxRoughnessMip; } -// compute parallax corrected reflection vector +// compute parallax corrected reflection vector, AABB version // we do this by finding the intersection with the volume and adjusting the reflection vector for the surface position // https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ -float3 ApplyParallaxCorrection(float3 aabbMin, float3 aabbMax, float3 aabbPos, float3 positionWS, float3 reflectDir) +float3 ApplyParallaxCorrectionAABB(float3 aabbMin, float3 aabbMax, float3 aabbPos, float3 positionWS, float3 reflectDir) { float3 rcpReflectDir = 1.0f / reflectDir; float3 intersectA = (aabbMax - positionWS) * rcpReflectDir; @@ -63,3 +63,10 @@ float3 ApplyParallaxCorrection(float3 aabbMin, float3 aabbMax, float3 aabbPos, f float3 intersectPos = reflectDir * distance + positionWS; return (intersectPos - aabbPos); } + +// compute parallax corrected reflection vector, OBB version +float3 ApplyParallaxCorrectionOBB(float4x4 obbTransformInverse, float3 obbHalfExtents, float3 positionWS, float3 reflectDir) +{ + float4 p = mul(obbTransformInverse, float4(positionWS, 1.0f)); + return ApplyParallaxCorrectionAABB(-obbHalfExtents, obbHalfExtents, float3(0.0f, 0.0f, 0.0f), p, reflectDir); +} diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ibl.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ibl.azsli index 5a0e150dbb..b1cfb47be6 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ibl.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ibl.azsli @@ -48,10 +48,9 @@ float3 GetIblSpecular( { if (ObjectSrg::m_reflectionProbeData.m_useParallaxCorrection) { - reflectDir = ApplyParallaxCorrection( - ObjectSrg::m_reflectionProbeData.m_outerAabbMin, - ObjectSrg::m_reflectionProbeData.m_outerAabbMax, - ObjectSrg::m_reflectionProbeData.m_aabbPos, + reflectDir = ApplyParallaxCorrectionOBB( + ObjectSrg::GetReflectionProbeWorldMatrixInverse(), + ObjectSrg::m_reflectionProbeData.m_outerObbHalfLengths, position, reflectDir); } @@ -60,11 +59,10 @@ float3 GetIblSpecular( probeSpecular *= (specularF0 * brdf.x + brdf.y); // compute blend amount based on world position in the reflection probe volume - float blendAmount = ComputeLerpBetweenInnerOuterAABBs( - ObjectSrg::m_reflectionProbeData.m_innerAabbMin, - ObjectSrg::m_reflectionProbeData.m_innerAabbMax, - ObjectSrg::m_reflectionProbeData.m_outerAabbMax, - ObjectSrg::m_reflectionProbeData.m_aabbPos, + float blendAmount = ComputeLerpBetweenInnerOuterOBBs( + ObjectSrg::m_reflectionProbeData.m_modelToWorldInverse, + ObjectSrg::m_reflectionProbeData.m_innerObbHalfLengths, + ObjectSrg::m_reflectionProbeData.m_outerObbHalfLengths, position); outSpecular = lerp(outSpecular, probeSpecular, blendAmount); diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionProbeBlendWeight.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionProbeBlendWeight.azsl index 095576caaf..0fca4d03c6 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionProbeBlendWeight.azsl +++ b/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionProbeBlendWeight.azsl @@ -63,7 +63,7 @@ PSOutput MainPS(VSOutput IN, in uint sampleIndex : SV_SampleIndex) // make sure the pixel belongs to this probe volume // this is necessary since it could have the correct stencil value but actually reside // in another volume that's in between the camera and the volume we're rendering - if (!AabbContainsPoint(ObjectSrg::m_outerAabbMin, ObjectSrg::m_outerAabbMax, positionWS)) + if (!ObbContainsPoint(ObjectSrg::GetWorldMatrixInverse(), ObjectSrg::m_outerObbHalfLengths, positionWS)) { discard; } @@ -71,11 +71,15 @@ PSOutput MainPS(VSOutput IN, in uint sampleIndex : SV_SampleIndex) // determine blend based on position with respect to the inner and outer AABBs // if it's inside the inner AABB it blends at 100%, otherwise it's the percentage of the distance between the inner/outer AABB float blendWeight = 1.0f; - if (!AabbContainsPoint(ObjectSrg::m_innerAabbMin, ObjectSrg::m_innerAabbMax, positionWS)) + if (!ObbContainsPoint(ObjectSrg::GetWorldMatrixInverse(), ObjectSrg::m_innerObbHalfLengths, positionWS)) { // not inside the inner AABB, so it's in between the inner and outer AABBs // compute blend amount based on the distance to the outer AABB - blendWeight = ComputeLerpBetweenInnerOuterAABBs(ObjectSrg::m_innerAabbMin, ObjectSrg::m_innerAabbMax, ObjectSrg::m_outerAabbMax, ObjectSrg::m_aabbPos, positionWS); + blendWeight = ComputeLerpBetweenInnerOuterOBBs( + ObjectSrg::GetWorldMatrixInverse(), + ObjectSrg::m_innerObbHalfLengths, + ObjectSrg::m_outerObbHalfLengths, + positionWS); } // write the blend weight (additive) at this position for the probe volume diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionProbeRenderCommon.azsli b/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionProbeRenderCommon.azsli index f172035177..ce4684b150 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionProbeRenderCommon.azsli +++ b/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionProbeRenderCommon.azsli @@ -12,12 +12,12 @@ #include // compute final probe specular using the probe cubemap and the roughness, normals, and specularF0 for the surface -bool ComputeProbeSpecular(float2 screenCoords, float3 positionWS, float3 aabbMin, float3 aabbMax, uint sampleIndex, out float3 specular) +bool ComputeProbeSpecular(float2 screenCoords, float3 positionWS, float4x4 obbTransformInverse, float3 outerObbHalfLengths, uint sampleIndex, out float3 specular) { // make sure the pixel belongs to this probe volume // this is necessary since it could have the correct stencil value but actually reside // in another volume that's in between the camera and the volume we're rendering - if (!AabbContainsPoint(aabbMin, aabbMax, positionWS)) + if (!ObbContainsPoint(obbTransformInverse, outerObbHalfLengths, positionWS)) { return false; } @@ -47,7 +47,11 @@ bool ComputeProbeSpecular(float2 screenCoords, float3 positionWS, float3 aabbMin float3 localReflectDir = reflectDir; if (ObjectSrg::m_useParallaxCorrection) { - localReflectDir = ApplyParallaxCorrection(ObjectSrg::m_outerAabbMin, ObjectSrg::m_outerAabbMax, ObjectSrg::m_aabbPos, positionWS, reflectDir); + localReflectDir = ApplyParallaxCorrectionOBB( + ObjectSrg::GetWorldMatrixInverse(), + ObjectSrg::m_outerObbHalfLengths, + positionWS, + reflectDir); } // sample reflection cubemap with the appropriate roughness mip diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionProbeRenderInner.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionProbeRenderInner.azsl index 209605be03..a0734caf02 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionProbeRenderInner.azsl +++ b/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionProbeRenderInner.azsl @@ -75,7 +75,7 @@ PSOutput MainPS(VSOutput IN, in uint sampleIndex : SV_SampleIndex) // compute specular using the probe cubemap and the roughness, normals, and specularF0 for the surface float3 specular = float3(0.0f, 0.0f, 0.0f); - if (!ComputeProbeSpecular(IN.m_position.xy, positionWS, ObjectSrg::m_innerAabbMin, ObjectSrg::m_innerAabbMax, sampleIndex, specular)) + if (!ComputeProbeSpecular(IN.m_position.xy, positionWS, ObjectSrg::GetWorldMatrixInverse(), ObjectSrg::m_innerObbHalfLengths, sampleIndex, specular)) { discard; } diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionProbeRenderObjectSrg.azsli b/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionProbeRenderObjectSrg.azsli index 92ecd82dee..8151ed2fd5 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionProbeRenderObjectSrg.azsli +++ b/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionProbeRenderObjectSrg.azsli @@ -13,12 +13,9 @@ ShaderResourceGroup ObjectSrg : SRG_PerObject { row_major float3x4 m_modelToWorld; - - float3 m_aabbPos; - float3 m_outerAabbMin; - float3 m_outerAabbMax; - float3 m_innerAabbMin; - float3 m_innerAabbMax; + row_major float3x4 m_modelToWorldInverse; // does not include extents + float3 m_outerObbHalfLengths; + float3 m_innerObbHalfLengths; bool m_useParallaxCorrection; TextureCube m_reflectionCubeMap; @@ -35,4 +32,18 @@ ShaderResourceGroup ObjectSrg : SRG_PerObject modelToWorld[2] = ObjectSrg::m_modelToWorld[2]; return modelToWorld; } + + float4x4 GetWorldMatrixInverse() + { + float4x4 modelToWorldInverse = float4x4( + float4(1, 0, 0, 0), + float4(0, 1, 0, 0), + float4(0, 0, 1, 0), + float4(0, 0, 0, 1)); + + modelToWorldInverse[0] = ObjectSrg::m_modelToWorldInverse[0]; + modelToWorldInverse[1] = ObjectSrg::m_modelToWorldInverse[1]; + modelToWorldInverse[2] = ObjectSrg::m_modelToWorldInverse[2]; + return modelToWorldInverse; + } } diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionProbeRenderOuter.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionProbeRenderOuter.azsl index be94a53588..ac97172f1f 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionProbeRenderOuter.azsl +++ b/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionProbeRenderOuter.azsl @@ -77,7 +77,7 @@ PSOutput MainPS(VSOutput IN, in uint sampleIndex : SV_SampleIndex) // compute specular using the probe cubemap and the roughness, normals, and specularF0 for the surface float3 specular = float3(0.0f, 0.0f, 0.0f); - if (!ComputeProbeSpecular(IN.m_position.xy, positionWS, ObjectSrg::m_outerAabbMin, ObjectSrg::m_outerAabbMax, sampleIndex, specular)) + if (!ComputeProbeSpecular(IN.m_position.xy, positionWS, ObjectSrg::GetWorldMatrixInverse(), ObjectSrg::m_outerObbHalfLengths, sampleIndex, specular)) { discard; } @@ -85,13 +85,17 @@ PSOutput MainPS(VSOutput IN, in uint sampleIndex : SV_SampleIndex) // determine blend based on position with respect to the inner and outer AABBs // if it's inside the inner AABB it blends at 100%, otherwise it's the percentage of the distance between the inner/outer AABB float blendWeight = 1.0f; - if (!AabbContainsPoint(ObjectSrg::m_innerAabbMin, ObjectSrg::m_innerAabbMax, positionWS)) + if (!ObbContainsPoint(ObjectSrg::GetWorldMatrixInverse(), ObjectSrg::m_innerObbHalfLengths, positionWS)) { // not inside the inner AABB, so it's in between the inner and outer AABBs // compute blend amount based on the distance to the outer AABB - blendWeight = ComputeLerpBetweenInnerOuterAABBs(ObjectSrg::m_innerAabbMin, ObjectSrg::m_innerAabbMax, ObjectSrg::m_outerAabbMax, ObjectSrg::m_aabbPos, positionWS); + blendWeight = ComputeLerpBetweenInnerOuterOBBs( + ObjectSrg::GetWorldMatrixInverse(), + ObjectSrg::m_innerObbHalfLengths, + ObjectSrg::m_outerObbHalfLengths, + positionWS); } - + // retrieve the blend weight of all probes at this location float blendWeightAllProbes = PassSrg::m_blendWeight.Load(IN.m_position.xy, sampleIndex).r; diff --git a/Gems/Atom/Feature/Common/Code/Source/Mesh/MeshFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/Mesh/MeshFeatureProcessor.cpp index 67702a8176..41ccec0fb5 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Mesh/MeshFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/Mesh/MeshFeatureProcessor.cpp @@ -1119,20 +1119,17 @@ namespace AZ if (reflectionProbeFeatureProcessor && (m_descriptor.m_useForwardPassIblSpecular || m_hasForwardPassIblSpecularMaterial)) { // retrieve probe constant indices - AZ::RHI::ShaderInputConstantIndex posConstantIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name("m_reflectionProbeData.m_aabbPos")); - AZ_Error("MeshDataInstance", posConstantIndex.IsValid(), "Failed to find ReflectionProbe constant index"); + AZ::RHI::ShaderInputConstantIndex modelToWorldConstantIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name("m_reflectionProbeData.m_modelToWorld")); + AZ_Error("MeshDataInstance", modelToWorldConstantIndex.IsValid(), "Failed to find ReflectionProbe constant index"); - AZ::RHI::ShaderInputConstantIndex outerAabbMinConstantIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name("m_reflectionProbeData.m_outerAabbMin")); - AZ_Error("MeshDataInstance", outerAabbMinConstantIndex.IsValid(), "Failed to find ReflectionProbe constant index"); + AZ::RHI::ShaderInputConstantIndex modelToWorldInverseConstantIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name("m_reflectionProbeData.m_modelToWorldInverse")); + AZ_Error("MeshDataInstance", modelToWorldInverseConstantIndex.IsValid(), "Failed to find ReflectionProbe constant index"); - AZ::RHI::ShaderInputConstantIndex outerAabbMaxConstantIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name("m_reflectionProbeData.m_outerAabbMax")); - AZ_Error("MeshDataInstance", outerAabbMaxConstantIndex.IsValid(), "Failed to find ReflectionProbe constant index"); + AZ::RHI::ShaderInputConstantIndex outerObbHalfLengthsConstantIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name("m_reflectionProbeData.m_outerObbHalfLengths")); + AZ_Error("MeshDataInstance", outerObbHalfLengthsConstantIndex.IsValid(), "Failed to find ReflectionProbe constant index"); - AZ::RHI::ShaderInputConstantIndex innerAabbMinConstantIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name("m_reflectionProbeData.m_innerAabbMin")); - AZ_Error("MeshDataInstance", innerAabbMinConstantIndex.IsValid(), "Failed to find ReflectionProbe constant index"); - - AZ::RHI::ShaderInputConstantIndex innerAabbMaxConstantIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name("m_reflectionProbeData.m_innerAabbMax")); - AZ_Error("MeshDataInstance", innerAabbMaxConstantIndex.IsValid(), "Failed to find ReflectionProbe constant index"); + AZ::RHI::ShaderInputConstantIndex innerObbHalfLengthsConstantIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name("m_reflectionProbeData.m_innerObbHalfLengths")); + AZ_Error("MeshDataInstance", innerObbHalfLengthsConstantIndex.IsValid(), "Failed to find ReflectionProbe constant index"); AZ::RHI::ShaderInputConstantIndex useReflectionProbeConstantIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name("m_reflectionProbeData.m_useReflectionProbe")); AZ_Error("MeshDataInstance", useReflectionProbeConstantIndex.IsValid(), "Failed to find ReflectionProbe constant index"); @@ -1154,11 +1151,10 @@ namespace AZ if (!reflectionProbes.empty() && reflectionProbes[0]) { - m_shaderResourceGroup->SetConstant(posConstantIndex, reflectionProbes[0]->GetPosition()); - m_shaderResourceGroup->SetConstant(outerAabbMinConstantIndex, reflectionProbes[0]->GetOuterAabbWs().GetMin()); - m_shaderResourceGroup->SetConstant(outerAabbMaxConstantIndex, reflectionProbes[0]->GetOuterAabbWs().GetMax()); - m_shaderResourceGroup->SetConstant(innerAabbMinConstantIndex, reflectionProbes[0]->GetInnerAabbWs().GetMin()); - m_shaderResourceGroup->SetConstant(innerAabbMaxConstantIndex, reflectionProbes[0]->GetInnerAabbWs().GetMax()); + m_shaderResourceGroup->SetConstant(modelToWorldConstantIndex, reflectionProbes[0]->GetTransform()); + m_shaderResourceGroup->SetConstant(modelToWorldInverseConstantIndex, reflectionProbes[0]->GetTransform().GetInverse()); + m_shaderResourceGroup->SetConstant(outerObbHalfLengthsConstantIndex, reflectionProbes[0]->GetOuterObbWs().GetHalfLengths()); + m_shaderResourceGroup->SetConstant(innerObbHalfLengthsConstantIndex, reflectionProbes[0]->GetInnerObbWs().GetHalfLengths()); m_shaderResourceGroup->SetConstant(useReflectionProbeConstantIndex, true); m_shaderResourceGroup->SetConstant(useParallaxCorrectionConstantIndex, reflectionProbes[0]->GetUseParallaxCorrection()); diff --git a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.cpp b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.cpp index 66c326e6e7..2be2ec72c8 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.cpp @@ -138,43 +138,40 @@ namespace AZ if (m_updateSrg) { // stencil Srg - // Note: the stencil pass uses a slightly reduced inner AABB to avoid seams + // Note: the stencil pass uses a slightly reduced inner OBB to avoid seams Vector3 innerExtentsReduced = m_innerExtents - Vector3(0.1f, 0.1f, 0.1f); - Matrix3x4 modelToWorldStencil = Matrix3x4::CreateFromMatrix3x3AndTranslation(Matrix3x3::CreateIdentity(), m_transform.GetTranslation()) * Matrix3x4::CreateScale(innerExtentsReduced); + Matrix3x4 modelToWorldStencil = Matrix3x4::CreateFromQuaternionAndTranslation(m_transform.GetRotation(), m_transform.GetTranslation()) * Matrix3x4::CreateScale(innerExtentsReduced); m_stencilSrg->SetConstant(m_reflectionRenderData->m_modelToWorldStencilConstantIndex, modelToWorldStencil); + m_stencilSrg->SetConstant(m_reflectionRenderData->m_modelToWorldInverseStencilConstantIndex, modelToWorldStencil.GetInverseFull()); m_stencilSrg->Compile(); + Matrix3x4 modelToWorldInverse = Matrix3x4::CreateFromTransform(m_transform).GetInverseFull(); + // blend weight Srg - Matrix3x4 modelToWorldOuter = Matrix3x4::CreateFromMatrix3x3AndTranslation(Matrix3x3::CreateIdentity(), m_transform.GetTranslation()) * Matrix3x4::CreateScale(m_outerExtents); + Matrix3x4 modelToWorldOuter = Matrix3x4::CreateFromQuaternionAndTranslation(m_transform.GetRotation(), m_transform.GetTranslation()) * Matrix3x4::CreateScale(m_outerExtents); m_blendWeightSrg->SetConstant(m_reflectionRenderData->m_modelToWorldRenderConstantIndex, modelToWorldOuter); - m_blendWeightSrg->SetConstant(m_reflectionRenderData->m_aabbPosRenderConstantIndex, m_outerAabbWs.GetCenter()); - m_blendWeightSrg->SetConstant(m_reflectionRenderData->m_outerAabbMinRenderConstantIndex, m_outerAabbWs.GetMin()); - m_blendWeightSrg->SetConstant(m_reflectionRenderData->m_outerAabbMaxRenderConstantIndex, m_outerAabbWs.GetMax()); - m_blendWeightSrg->SetConstant(m_reflectionRenderData->m_innerAabbMinRenderConstantIndex, m_innerAabbWs.GetMin()); - m_blendWeightSrg->SetConstant(m_reflectionRenderData->m_innerAabbMaxRenderConstantIndex, m_innerAabbWs.GetMax()); + m_blendWeightSrg->SetConstant(m_reflectionRenderData->m_modelToWorldInverseRenderConstantIndex, modelToWorldInverse); + m_blendWeightSrg->SetConstant(m_reflectionRenderData->m_outerObbHalfLengthsRenderConstantIndex, m_outerObbWs.GetHalfLengths()); + m_blendWeightSrg->SetConstant(m_reflectionRenderData->m_innerObbHalfLengthsRenderConstantIndex, m_innerObbWs.GetHalfLengths()); m_blendWeightSrg->SetConstant(m_reflectionRenderData->m_useParallaxCorrectionRenderConstantIndex, m_useParallaxCorrection); m_blendWeightSrg->SetImage(m_reflectionRenderData->m_reflectionCubeMapRenderImageIndex, m_cubeMapImage); m_blendWeightSrg->Compile(); // render outer Srg m_renderOuterSrg->SetConstant(m_reflectionRenderData->m_modelToWorldRenderConstantIndex, modelToWorldOuter); - m_renderOuterSrg->SetConstant(m_reflectionRenderData->m_aabbPosRenderConstantIndex, m_outerAabbWs.GetCenter()); - m_renderOuterSrg->SetConstant(m_reflectionRenderData->m_outerAabbMinRenderConstantIndex, m_outerAabbWs.GetMin()); - m_renderOuterSrg->SetConstant(m_reflectionRenderData->m_outerAabbMaxRenderConstantIndex, m_outerAabbWs.GetMax()); - m_renderOuterSrg->SetConstant(m_reflectionRenderData->m_innerAabbMinRenderConstantIndex, m_innerAabbWs.GetMin()); - m_renderOuterSrg->SetConstant(m_reflectionRenderData->m_innerAabbMaxRenderConstantIndex, m_innerAabbWs.GetMax()); + m_renderOuterSrg->SetConstant(m_reflectionRenderData->m_modelToWorldInverseRenderConstantIndex, modelToWorldInverse); + m_renderOuterSrg->SetConstant(m_reflectionRenderData->m_outerObbHalfLengthsRenderConstantIndex, m_outerObbWs.GetHalfLengths()); + m_renderOuterSrg->SetConstant(m_reflectionRenderData->m_innerObbHalfLengthsRenderConstantIndex, m_innerObbWs.GetHalfLengths()); m_renderOuterSrg->SetConstant(m_reflectionRenderData->m_useParallaxCorrectionRenderConstantIndex, m_useParallaxCorrection); m_renderOuterSrg->SetImage(m_reflectionRenderData->m_reflectionCubeMapRenderImageIndex, m_cubeMapImage); m_renderOuterSrg->Compile(); // render inner Srg - Matrix3x4 modelToWorldInner = Matrix3x4::CreateFromMatrix3x3AndTranslation(Matrix3x3::CreateIdentity(), m_transform.GetTranslation()) * Matrix3x4::CreateScale(m_innerExtents); + Matrix3x4 modelToWorldInner = Matrix3x4::CreateFromQuaternionAndTranslation(m_transform.GetRotation(), m_transform.GetTranslation()) * Matrix3x4::CreateScale(m_innerExtents); m_renderInnerSrg->SetConstant(m_reflectionRenderData->m_modelToWorldRenderConstantIndex, modelToWorldInner); - m_renderInnerSrg->SetConstant(m_reflectionRenderData->m_aabbPosRenderConstantIndex, m_outerAabbWs.GetCenter()); - m_renderInnerSrg->SetConstant(m_reflectionRenderData->m_outerAabbMinRenderConstantIndex, m_outerAabbWs.GetMin()); - m_renderInnerSrg->SetConstant(m_reflectionRenderData->m_outerAabbMaxRenderConstantIndex, m_outerAabbWs.GetMax()); - m_renderInnerSrg->SetConstant(m_reflectionRenderData->m_innerAabbMinRenderConstantIndex, m_innerAabbWs.GetMin()); - m_renderInnerSrg->SetConstant(m_reflectionRenderData->m_innerAabbMaxRenderConstantIndex, m_innerAabbWs.GetMax()); + m_renderInnerSrg->SetConstant(m_reflectionRenderData->m_modelToWorldInverseRenderConstantIndex, modelToWorldInverse); + m_renderInnerSrg->SetConstant(m_reflectionRenderData->m_outerObbHalfLengthsRenderConstantIndex, m_outerObbWs.GetHalfLengths()); + m_renderInnerSrg->SetConstant(m_reflectionRenderData->m_innerObbHalfLengthsRenderConstantIndex, m_innerObbWs.GetHalfLengths()); m_renderInnerSrg->SetConstant(m_reflectionRenderData->m_useParallaxCorrectionRenderConstantIndex, m_useParallaxCorrection); m_renderInnerSrg->SetImage(m_reflectionRenderData->m_reflectionCubeMapRenderImageIndex, m_cubeMapImage); m_renderInnerSrg->Compile(); @@ -244,22 +241,22 @@ namespace AZ m_outerExtents *= m_transform.GetUniformScale(); m_innerExtents *= m_transform.GetUniformScale(); - m_outerAabbWs = Aabb::CreateCenterHalfExtents(m_transform.GetTranslation(), m_outerExtents / 2.0f); - m_innerAabbWs = Aabb::CreateCenterHalfExtents(m_transform.GetTranslation(), m_innerExtents / 2.0f); + m_outerObbWs = Obb::CreateFromPositionRotationAndHalfLengths(m_transform.GetTranslation(), m_transform.GetRotation(), m_outerExtents / 2.0f); + m_innerObbWs = Obb::CreateFromPositionRotationAndHalfLengths(m_transform.GetTranslation(), m_transform.GetRotation(), m_innerExtents / 2.0f); m_updateSrg = true; } void ReflectionProbe::SetOuterExtents(const AZ::Vector3& outerExtents) { m_outerExtents = outerExtents * m_transform.GetUniformScale(); - m_outerAabbWs = Aabb::CreateCenterHalfExtents(m_transform.GetTranslation(), m_outerExtents / 2.0f); + m_outerObbWs = Obb::CreateFromPositionRotationAndHalfLengths(m_transform.GetTranslation(), m_transform.GetRotation(), m_outerExtents / 2.0f); m_updateSrg = true; } void ReflectionProbe::SetInnerExtents(const AZ::Vector3& innerExtents) { m_innerExtents = innerExtents * m_transform.GetUniformScale(); - m_innerAabbWs = Aabb::CreateCenterHalfExtents(m_transform.GetTranslation(), m_innerExtents / 2.0f); + m_innerObbWs = Obb::CreateFromPositionRotationAndHalfLengths(m_transform.GetTranslation(), m_transform.GetRotation(), m_innerExtents / 2.0f); m_updateSrg = true; } @@ -394,13 +391,14 @@ namespace AZ lod.m_screenCoverageMax = 1.0f; // update cullable bounds + Aabb outerAabb = Aabb::CreateFromObb(m_outerObbWs); Vector3 center; float radius; - m_outerAabbWs.GetAsSphere(center, radius); + outerAabb.GetAsSphere(center, radius); m_cullable.m_cullData.m_boundingSphere = Sphere(center, radius); - m_cullable.m_cullData.m_boundingObb = m_outerAabbWs.GetTransformedObb(AZ::Transform::CreateIdentity()); - m_cullable.m_cullData.m_visibilityEntry.m_boundingVolume = m_outerAabbWs; + m_cullable.m_cullData.m_boundingObb = m_outerObbWs; + m_cullable.m_cullData.m_visibilityEntry.m_boundingVolume = outerAabb; m_cullable.m_cullData.m_visibilityEntry.m_userData = &m_cullable; m_cullable.m_cullData.m_visibilityEntry.m_typeFlags = AzFramework::VisibilityEntry::TYPE_RPI_Cullable; diff --git a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.h b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.h index bb30ce9470..169c4f1df2 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.h +++ b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.h @@ -56,12 +56,11 @@ namespace AZ RHI::DrawListTag m_renderInnerDrawListTag; RHI::ShaderInputConstantIndex m_modelToWorldStencilConstantIndex; + RHI::ShaderInputConstantIndex m_modelToWorldInverseStencilConstantIndex; RHI::ShaderInputConstantIndex m_modelToWorldRenderConstantIndex; - RHI::ShaderInputConstantIndex m_aabbPosRenderConstantIndex; - RHI::ShaderInputConstantIndex m_outerAabbMinRenderConstantIndex; - RHI::ShaderInputConstantIndex m_outerAabbMaxRenderConstantIndex; - RHI::ShaderInputConstantIndex m_innerAabbMinRenderConstantIndex; - RHI::ShaderInputConstantIndex m_innerAabbMaxRenderConstantIndex; + RHI::ShaderInputConstantIndex m_modelToWorldInverseRenderConstantIndex; + RHI::ShaderInputConstantIndex m_outerObbHalfLengthsRenderConstantIndex; + RHI::ShaderInputConstantIndex m_innerObbHalfLengthsRenderConstantIndex; RHI::ShaderInputConstantIndex m_useParallaxCorrectionRenderConstantIndex; RHI::ShaderInputImageIndex m_reflectionCubeMapRenderImageIndex; }; @@ -78,6 +77,7 @@ namespace AZ void Simulate(uint32_t probeIndex); const Vector3& GetPosition() const { return m_transform.GetTranslation(); } + const AZ::Transform& GetTransform() const { return m_transform; } void SetTransform(const AZ::Transform& transform); const AZ::Vector3& GetOuterExtents() const { return m_outerExtents; } @@ -86,8 +86,8 @@ namespace AZ const AZ::Vector3& GetInnerExtents() const { return m_innerExtents; } void SetInnerExtents(const AZ::Vector3& innerExtents); - const Aabb& GetOuterAabbWs() const { return m_outerAabbWs; } - const Aabb& GetInnerAabbWs() const { return m_innerAabbWs; } + const Obb& GetOuterObbWs() const { return m_outerObbWs; } + const Obb& GetInnerObbWs() const { return m_innerObbWs; } const Data::Instance& GetCubeMapImage() const { return m_cubeMapImage; } void SetCubeMapImage(const Data::Instance& cubeMapImage, const AZStd::string& relativePath); @@ -133,9 +133,9 @@ namespace AZ AZ::Vector3 m_outerExtents = AZ::Vector3(0.0f, 0.0f, 0.0f); AZ::Vector3 m_innerExtents = AZ::Vector3(0.0f, 0.0f, 0.0f); - // probe volume AABBs (world space), built from position and extents - Aabb m_outerAabbWs; - Aabb m_innerAabbWs; + // probe volume OBBs (world space), built from position and extents + Obb m_outerObbWs; + Obb m_innerObbWs; // cubemap Data::Instance m_cubeMapImage; diff --git a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbeFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbeFeatureProcessor.cpp index 341d1a0274..5c07fbae66 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbeFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbeFeatureProcessor.cpp @@ -92,6 +92,10 @@ namespace AZ m_reflectionRenderData.m_modelToWorldStencilConstantIndex = stencilSrgLayout->FindShaderInputConstantIndex(modelToWorldConstantName); AZ_Error("ReflectionProbeFeatureProcessor", m_reflectionRenderData.m_modelToWorldStencilConstantIndex.IsValid(), "Failed to find stencil shader input constant [%s]", modelToWorldConstantName.GetCStr()); + Name modelToWorldInverseConstantName = Name("m_modelToWorldInverse"); + m_reflectionRenderData.m_modelToWorldInverseStencilConstantIndex = stencilSrgLayout->FindShaderInputConstantIndex(modelToWorldInverseConstantName); + AZ_Error("ReflectionProbeFeatureProcessor", m_reflectionRenderData.m_modelToWorldInverseStencilConstantIndex.IsValid(), "Failed to find stencil shader input constant [%s]", modelToWorldInverseConstantName.GetCStr()); + // cache probe render shader indices // Note: the outer and inner render shaders use the same Srg Data::Instance renderReflectionSrg = RPI::ShaderResourceGroup::Create( @@ -104,25 +108,16 @@ namespace AZ m_reflectionRenderData.m_modelToWorldRenderConstantIndex = renderReflectionSrgLayout->FindShaderInputConstantIndex(modelToWorldConstantName); AZ_Error("ReflectionProbeFeatureProcessor", m_reflectionRenderData.m_modelToWorldRenderConstantIndex.IsValid(), "Failed to find render shader input constant [%s]", modelToWorldConstantName.GetCStr()); - Name aabbPosConstantName = Name("m_aabbPos"); - m_reflectionRenderData.m_aabbPosRenderConstantIndex = renderReflectionSrgLayout->FindShaderInputConstantIndex(aabbPosConstantName); - AZ_Error("ReflectionProbeFeatureProcessor", m_reflectionRenderData.m_aabbPosRenderConstantIndex.IsValid(), "Failed to find render shader input constant [%s]", aabbPosConstantName.GetCStr()); + m_reflectionRenderData.m_modelToWorldInverseRenderConstantIndex = renderReflectionSrgLayout->FindShaderInputConstantIndex(modelToWorldInverseConstantName); + AZ_Error("ReflectionProbeFeatureProcessor", m_reflectionRenderData.m_modelToWorldRenderConstantIndex.IsValid(), "Failed to find render shader input constant [%s]", modelToWorldInverseConstantName.GetCStr()); - Name outerAabbMinConstantName = Name("m_outerAabbMin"); - m_reflectionRenderData.m_outerAabbMinRenderConstantIndex = renderReflectionSrgLayout->FindShaderInputConstantIndex(outerAabbMinConstantName); - AZ_Error("ReflectionProbeFeatureProcessor", m_reflectionRenderData.m_outerAabbMinRenderConstantIndex.IsValid(), "Failed to find render shader input constant [%s]", outerAabbMinConstantName.GetCStr()); + Name outerObbHalfLengthsConstantName = Name("m_outerObbHalfLengths"); + m_reflectionRenderData.m_outerObbHalfLengthsRenderConstantIndex = renderReflectionSrgLayout->FindShaderInputConstantIndex(outerObbHalfLengthsConstantName); + AZ_Error("ReflectionProbeFeatureProcessor", m_reflectionRenderData.m_outerObbHalfLengthsRenderConstantIndex.IsValid(), "Failed to find render shader input constant [%s]", outerObbHalfLengthsConstantName.GetCStr()); - Name outerAabbMaxConstantName = Name("m_outerAabbMax"); - m_reflectionRenderData.m_outerAabbMaxRenderConstantIndex = renderReflectionSrgLayout->FindShaderInputConstantIndex(outerAabbMaxConstantName); - AZ_Error("ReflectionProbeFeatureProcessor", m_reflectionRenderData.m_outerAabbMaxRenderConstantIndex.IsValid(), "Failed to find render shader input constant [%s]", outerAabbMaxConstantName.GetCStr()); - - Name innerAabbMinConstantName = Name("m_innerAabbMin"); - m_reflectionRenderData.m_innerAabbMinRenderConstantIndex = renderReflectionSrgLayout->FindShaderInputConstantIndex(innerAabbMinConstantName); - AZ_Error("ReflectionProbeFeatureProcessor", m_reflectionRenderData.m_innerAabbMinRenderConstantIndex.IsValid(), "Failed to find render shader input constant [%s]", innerAabbMinConstantName.GetCStr()); - - Name innerAabbMaxConstantName = Name("m_innerAabbMax"); - m_reflectionRenderData.m_innerAabbMaxRenderConstantIndex = renderReflectionSrgLayout->FindShaderInputConstantIndex(innerAabbMaxConstantName); - AZ_Error("ReflectionProbeFeatureProcessor", m_reflectionRenderData.m_innerAabbMaxRenderConstantIndex.IsValid(), "Failed to find render shader input constant [%s]", innerAabbMaxConstantName.GetCStr()); + Name innerObbHalfLengthsConstantName = Name("m_innerObbHalfLengths"); + m_reflectionRenderData.m_innerObbHalfLengthsRenderConstantIndex = renderReflectionSrgLayout->FindShaderInputConstantIndex(innerObbHalfLengthsConstantName); + AZ_Error("ReflectionProbeFeatureProcessor", m_reflectionRenderData.m_innerObbHalfLengthsRenderConstantIndex.IsValid(), "Failed to find render shader input constant [%s]", innerObbHalfLengthsConstantName.GetCStr()); Name useParallaxCorrectionConstantName = Name("m_useParallaxCorrection"); m_reflectionRenderData.m_useParallaxCorrectionRenderConstantIndex = renderReflectionSrgLayout->FindShaderInputConstantIndex(useParallaxCorrectionConstantName); @@ -199,10 +194,11 @@ namespace AZ // sort the probes by descending inner volume size, so the smallest volumes are rendered last auto sortFn = [](AZStd::shared_ptr const& probe1, AZStd::shared_ptr const& probe2) -> bool { - const Aabb& aabb1 = probe1->GetInnerAabbWs(); - const Aabb& aabb2 = probe2->GetInnerAabbWs(); - float size1 = aabb1.GetXExtent() * aabb1.GetZExtent() * aabb1.GetYExtent(); - float size2 = aabb2.GetXExtent() * aabb2.GetZExtent() * aabb2.GetYExtent(); + const Obb& obb1 = probe1->GetInnerObbWs(); + const Obb& obb2 = probe2->GetInnerObbWs(); + float size1 = obb1.GetHalfLengthX() * obb1.GetHalfLengthZ() * obb1.GetHalfLengthY(); + float size2 = obb2.GetHalfLengthX() * obb2.GetHalfLengthZ() * obb2.GetHalfLengthY(); + return (size1 > size2); }; @@ -347,7 +343,7 @@ namespace AZ // simple AABB check to find the reflection probes that contain the position for (auto& reflectionProbe : m_reflectionProbes) { - if (reflectionProbe->GetOuterAabbWs().Contains(position) + if (reflectionProbe->GetOuterObbWs().Contains(position) && reflectionProbe->GetCubeMapImage() && reflectionProbe->GetCubeMapImage()->IsInitialized()) { diff --git a/Gems/Atom/RPI/Assets/ShaderLib/Atom/RPI/Math.azsli b/Gems/Atom/RPI/Assets/ShaderLib/Atom/RPI/Math.azsli index a94e01e11b..b004623c4e 100644 --- a/Gems/Atom/RPI/Assets/ShaderLib/Atom/RPI/Math.azsli +++ b/Gems/Atom/RPI/Assets/ShaderLib/Atom/RPI/Math.azsli @@ -116,6 +116,22 @@ float ComputeLerpBetweenInnerOuterAABBs(float3 innerAabbMin, float3 innerAabbMax return totalDistance > 0.0f ? saturate(shortestDistance / totalDistance) : 1.0f; } +// returns true if the Obb contains the specified point +bool ObbContainsPoint(float4x4 obbTransformInverse, float3 obbHalfExtents, float3 testPoint) +{ + // get the position in Obb local space, force to positive quadrant with abs() + float4 p = abs(mul(obbTransformInverse, float4(testPoint, 1.0f))); + return AabbContainsPoint(-obbHalfExtents, obbHalfExtents, p); +} + +// computes [0..1] percentage of a point that's in between the inner and outer OBBs +float ComputeLerpBetweenInnerOuterOBBs(float3x4 obbTransformInverse, float3 innerObbHalfExtents, float3 outerObbHalfExtents, float3 position) +{ + // get the position in Obb local space, force to positive quadrant with abs() + float3 p = abs(mul(obbTransformInverse, float4(position, 1.0f))); + return ComputeLerpBetweenInnerOuterAABBs(-innerObbHalfExtents, innerObbHalfExtents, outerObbHalfExtents, float3(0.0f, 0.0f, 0.0f), p); +} + // ---------- Normal Encoding ----------- // Encode/Decode functions for Signed Octahedron normals diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/ReflectionProbe/EditorReflectionProbeComponent.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/ReflectionProbe/EditorReflectionProbeComponent.cpp index 4f4f21ab0f..aa68333108 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/ReflectionProbe/EditorReflectionProbeComponent.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/ReflectionProbe/EditorReflectionProbeComponent.cpp @@ -212,6 +212,9 @@ namespace AZ AZ::Vector3 position = AZ::Vector3::CreateZero(); AZ::TransformBus::EventResult(position, GetEntityId(), &AZ::TransformBus::Events::GetWorldTranslation); + AZ::Quaternion rotationQuaternion = AZ::Quaternion::CreateIdentity(); + AZ::TransformBus::EventResult(rotationQuaternion, GetEntityId(), &AZ::TransformBus::Events::GetWorldRotationQuaternion); + AZ::Matrix3x3 rotationMatrix = AZ::Matrix3x3::CreateFromQuaternion(rotationQuaternion); float scale = 1.0f; AZ::TransformBus::EventResult(scale, GetEntityId(), &AZ::TransformBus::Events::GetLocalUniformScale); @@ -224,9 +227,7 @@ namespace AZ AZ::Vector3 innerExtents(configuration.m_innerWidth, configuration.m_innerLength, configuration.m_innerHeight); innerExtents *= scale; - AZ::Vector3 innerMin(position.GetX() - innerExtents.GetX() / 2, position.GetY() - innerExtents.GetY() / 2, position.GetZ() - innerExtents.GetZ() / 2); - AZ::Vector3 innerMax(position.GetX() + innerExtents.GetX() / 2, position.GetY() + innerExtents.GetY() / 2, position.GetZ() + innerExtents.GetZ() / 2); - debugDisplay.DrawWireBox(innerMin, innerMax); + debugDisplay.DrawWireOBB(position, rotationMatrix.GetBasisX(), rotationMatrix.GetBasisY(), rotationMatrix.GetBasisZ(), innerExtents / 2.0f); } AZ::Aabb EditorReflectionProbeComponent::GetEditorSelectionBoundsViewport([[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo) From 2bd01f09fb0b8570089524bb2549080123abe277 Mon Sep 17 00:00:00 2001 From: dmcdiar Date: Mon, 20 Sep 2021 11:37:17 -0700 Subject: [PATCH 2/9] Removed modelToWorldInverse from the stencil Srg. Signed-off-by: dmcdiar --- .../Common/Code/Source/ReflectionProbe/ReflectionProbe.cpp | 1 - .../Common/Code/Source/ReflectionProbe/ReflectionProbe.h | 1 - .../ReflectionProbe/ReflectionProbeFeatureProcessor.cpp | 5 +---- 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.cpp b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.cpp index 1c1766073b..e86d91d387 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.cpp @@ -142,7 +142,6 @@ namespace AZ Vector3 innerExtentsReduced = m_innerExtents - Vector3(0.1f, 0.1f, 0.1f); Matrix3x4 modelToWorldStencil = Matrix3x4::CreateFromQuaternionAndTranslation(m_transform.GetRotation(), m_transform.GetTranslation()) * Matrix3x4::CreateScale(innerExtentsReduced); m_stencilSrg->SetConstant(m_reflectionRenderData->m_modelToWorldStencilConstantIndex, modelToWorldStencil); - m_stencilSrg->SetConstant(m_reflectionRenderData->m_modelToWorldInverseStencilConstantIndex, modelToWorldStencil.GetInverseFull()); m_stencilSrg->Compile(); Matrix3x4 modelToWorldInverse = Matrix3x4::CreateFromTransform(m_transform).GetInverseFull(); diff --git a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.h b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.h index 169c4f1df2..4f6a3337be 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.h +++ b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.h @@ -56,7 +56,6 @@ namespace AZ RHI::DrawListTag m_renderInnerDrawListTag; RHI::ShaderInputConstantIndex m_modelToWorldStencilConstantIndex; - RHI::ShaderInputConstantIndex m_modelToWorldInverseStencilConstantIndex; RHI::ShaderInputConstantIndex m_modelToWorldRenderConstantIndex; RHI::ShaderInputConstantIndex m_modelToWorldInverseRenderConstantIndex; RHI::ShaderInputConstantIndex m_outerObbHalfLengthsRenderConstantIndex; diff --git a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbeFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbeFeatureProcessor.cpp index 5c07fbae66..09f75c07a6 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbeFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbeFeatureProcessor.cpp @@ -92,10 +92,6 @@ namespace AZ m_reflectionRenderData.m_modelToWorldStencilConstantIndex = stencilSrgLayout->FindShaderInputConstantIndex(modelToWorldConstantName); AZ_Error("ReflectionProbeFeatureProcessor", m_reflectionRenderData.m_modelToWorldStencilConstantIndex.IsValid(), "Failed to find stencil shader input constant [%s]", modelToWorldConstantName.GetCStr()); - Name modelToWorldInverseConstantName = Name("m_modelToWorldInverse"); - m_reflectionRenderData.m_modelToWorldInverseStencilConstantIndex = stencilSrgLayout->FindShaderInputConstantIndex(modelToWorldInverseConstantName); - AZ_Error("ReflectionProbeFeatureProcessor", m_reflectionRenderData.m_modelToWorldInverseStencilConstantIndex.IsValid(), "Failed to find stencil shader input constant [%s]", modelToWorldInverseConstantName.GetCStr()); - // cache probe render shader indices // Note: the outer and inner render shaders use the same Srg Data::Instance renderReflectionSrg = RPI::ShaderResourceGroup::Create( @@ -108,6 +104,7 @@ namespace AZ m_reflectionRenderData.m_modelToWorldRenderConstantIndex = renderReflectionSrgLayout->FindShaderInputConstantIndex(modelToWorldConstantName); AZ_Error("ReflectionProbeFeatureProcessor", m_reflectionRenderData.m_modelToWorldRenderConstantIndex.IsValid(), "Failed to find render shader input constant [%s]", modelToWorldConstantName.GetCStr()); + Name modelToWorldInverseConstantName = Name("m_modelToWorldInverse"); m_reflectionRenderData.m_modelToWorldInverseRenderConstantIndex = renderReflectionSrgLayout->FindShaderInputConstantIndex(modelToWorldInverseConstantName); AZ_Error("ReflectionProbeFeatureProcessor", m_reflectionRenderData.m_modelToWorldRenderConstantIndex.IsValid(), "Failed to find render shader input constant [%s]", modelToWorldInverseConstantName.GetCStr()); From 61a92232568130970500557aae48de9b858d0cef Mon Sep 17 00:00:00 2001 From: jiaweig <51759646+jiaweig-amzn@users.noreply.github.com> Date: Tue, 21 Sep 2021 13:46:22 -0700 Subject: [PATCH 3/9] ATOM-16079 [RHI][Vulkan] - Linux Swapchain rendering issue on the first frame (#4129) * Fix out-of-date swapchain when QT window is not activated. Signed-off-by: jiaweig * Removed new code of the previous hack. Signed-off-by: jiaweig --- .../RHI/Code/Include/Atom/RHI/SwapChain.h | 9 --------- Gems/Atom/RHI/Code/Source/RHI/SwapChain.cpp | 6 ------ .../Vulkan/Code/Source/RHI/CommandQueue.cpp | 9 --------- .../RHI/Vulkan/Code/Source/RHI/SwapChain.cpp | 11 ---------- .../Viewport/RenderViewportWidget.h | 2 -- .../Source/Viewport/RenderViewportWidget.cpp | 20 +------------------ 6 files changed, 1 insertion(+), 56 deletions(-) diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI/SwapChain.h b/Gems/Atom/RHI/Code/Include/Atom/RHI/SwapChain.h index 42ba2d2e25..14e9968e42 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI/SwapChain.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI/SwapChain.h @@ -81,15 +81,6 @@ namespace AZ AZ_RTTI(SwapChain, "{888B64A5-D956-406F-9C33-CF6A54FC41B0}", Object); -#if defined(PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB) - // On Linux platforms that uses XCB, a resize may occur in the swap chain but the command queue may still - // reference the original surface. This flag is a temporary fix to make sure the swap chain is ready to present - // We need to remove this work around with - - // [GFX TODO][GHI - 2678] - AZStd::atomic_bool m_readyToPresent { false }; -#endif // PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB - protected: SwapChain(); diff --git a/Gems/Atom/RHI/Code/Source/RHI/SwapChain.cpp b/Gems/Atom/RHI/Code/Source/RHI/SwapChain.cpp index 92d7a125d8..b0501d937d 100644 --- a/Gems/Atom/RHI/Code/Source/RHI/SwapChain.cpp +++ b/Gems/Atom/RHI/Code/Source/RHI/SwapChain.cpp @@ -164,12 +164,6 @@ namespace AZ m_currentImageIndex = 0; } -#if defined(PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB) - // If we are presenting through the editor, the resize is triggered through the editor's window, which - // won't happen until after the surface is ready to present - m_readyToPresent.store(true); -#endif // PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB - return resultCode; } diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/CommandQueue.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/CommandQueue.cpp index e4d8212228..c712099172 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/CommandQueue.cpp +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/CommandQueue.cpp @@ -42,15 +42,6 @@ namespace AZ void CommandQueue::ExecuteWork(const RHI::ExecuteWorkRequest& rhiRequest) { -#if defined(PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB) - for (RHI::SwapChain* swapChain : rhiRequest.m_swapChainsToPresent) - { - if (!swapChain->m_readyToPresent) - { - return; - } - } -#endif // PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB const ExecuteWorkRequest& request = static_cast(rhiRequest); QueueCommand([=](void* queue) { diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/SwapChain.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/SwapChain.cpp index e1d3e8c060..7040defca8 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/SwapChain.cpp +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/SwapChain.cpp @@ -128,17 +128,6 @@ namespace AZ nativeDimensions->m_imageFormat = ConvertFormat(m_surfaceFormat.format); } -#if defined(PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB) - // When launching in game mode, the surface will be ready at this point, meaning that after - // intialization, this swap chain is ready to present - AZ::ApplicationTypeQuery appType; - ComponentApplicationBus::Broadcast(&AZ::ComponentApplicationBus::Events::QueryApplicationType, appType); - if (appType.IsGame()) - { - m_readyToPresent.store(true); - } -#endif // PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB - SetName(GetName()); return result; } diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h index 1b718f7710..318a49027a 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h @@ -159,8 +159,6 @@ namespace AtomToolsFramework AZ::RPI::ViewPtr m_defaultCamera; // Our viewport-local aux geom pipeline for supplemental rendering. AZ::RPI::AuxGeomDrawPtr m_auxGeom; - // Used to keep track of a pending resize event to avoid initialization before window activate. - bool m_windowResizedEvent = false; // Tracks whether the cursor is currently over our viewport, used for mouse input event book-keeping. bool m_mouseOver = false; // The last recorded mouse position, in local viewport screen coordinates. diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp index 4446e11231..2a15041e20 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp @@ -254,28 +254,11 @@ namespace AtomToolsFramework void RenderViewportWidget::resizeEvent([[maybe_unused]] QResizeEvent* event) { - // We need to wait until the window is activated, so the underlying surface - // has been created and has the correct size. - if (windowHandle()->isActive()) - { - SendWindowResizeEvent(); - } - else - { - m_windowResizedEvent = true; - } + SendWindowResizeEvent(); } bool RenderViewportWidget::event(QEvent* event) { - // Check if we have a pending resize event. - // At this point the surface has been created and has - // the proper dimensions. - if (event->type() == QEvent::WindowActivate && m_windowResizedEvent) - { - SendWindowResizeEvent(); - } - return QWidget::event(event); } @@ -372,7 +355,6 @@ namespace AtomToolsFramework AzFramework::WindowNotificationBus::Event( GetNativeWindowHandle(), &AzFramework::WindowNotifications::OnWindowResized, windowSize.width(), windowSize.height()); - m_windowResizedEvent = false; } void RenderViewportWidget::NotifyUpdateRefreshRate() From 9477da799b78146e7b1d4f1d7c6cecfa89d38ac7 Mon Sep 17 00:00:00 2001 From: Tobias Alexander Franke Date: Tue, 21 Sep 2021 23:05:11 +0200 Subject: [PATCH 4/9] Jobify view culling (#3983) * Jobify culling * Move JobCompletion to stack Signed-off-by: Tobias Alexander Franke Co-authored-by: Tobias Alexander Franke --- Gems/Atom/RPI/Code/Source/RPI.Public/Culling.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Culling.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Culling.cpp index f67343faa1..fbfabe4f2a 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Culling.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Culling.cpp @@ -730,12 +730,22 @@ namespace AZ m_debugCtx.ResetCullStats(); m_debugCtx.m_numCullablesInScene = GetNumCullables(); + AZ::JobCompletion beginCullingCompletion; for (auto& view : views) { - view->BeginCulling(); + const auto cullingLambda = [&view]() + { + view->BeginCulling(); + }; + + AZ::Job* cullingJob = AZ::CreateJobFunction(AZStd::move(cullingLambda), true, nullptr); + cullingJob->SetDependent(&beginCullingCompletion); + cullingJob->Start(); } + beginCullingCompletion.StartAndWaitForCompletion(); + AuxGeomDrawPtr auxGeom; if (m_debugCtx.m_debugDraw) { From 30da67fe7d95c9ea13c13d0adeaba0c50aac628f Mon Sep 17 00:00:00 2001 From: hershey5045 <43485729+hershey5045@users.noreply.github.com> Date: Tue, 21 Sep 2021 14:19:30 -0700 Subject: [PATCH 5/9] Editor HDR Color Grading Component implemented under the PostFx stack (#4159) * Add HDR color grading pass and shaders. * Remove color grading pass from light adaptation parent pass due to failing ASV tests. This will be added back later on. * Editor HDR Color Grading Component implemented under the PostFx stack (#219) * Add softmin/max for unbounded color grading properties. * Revert channel mixer properties to vector3. Refactor mix to weight. Fix color grading pass to convert any color variable into vec4. Signed-off-by: rbarrand Co-authored-by: Robin --- .../Common/Assets/Passes/HDRColorGrading.pass | 8 +- .../Assets/Passes/LightAdaptationParent.pass | 18 ++- .../PostProcessing/HDRColorGrading.azsl | 19 +-- .../ColorGrading/HDRColorGradingParams.inl | 37 +++++ .../HDRColorGradingSettingsInterface.h | 33 ++++ .../PostProcess/PostProcessSettings.inl | 1 + .../PostProcessSettingsInterface.h | 1 + .../Code/Source/CommonSystemComponent.cpp | 2 + .../ColorGrading/HDRColorGradingSettings.cpp | 59 +++++++ .../ColorGrading/HDRColorGradingSettings.h | 69 +++++++++ .../Source/PostProcess/PostProcessSettings.h | 1 + .../PostProcessing/HDRColorGradingPass.cpp | 135 ++++++++++++++++ .../PostProcessing/HDRColorGradingPass.h | 77 +++++++++ .../Code/atom_feature_common_files.cmake | 4 + .../atom_feature_common_public_files.cmake | 2 + .../ColorGrading/HDRColorGradingBus.h | 34 ++++ .../HDRColorGradingComponentConfig.h | 39 +++++ .../CommonFeatures/Code/Source/Module.cpp | 4 + .../EditorHDRColorGradingComponent.cpp | 145 +++++++++++++++++ .../EditorHDRColorGradingComponent.h | 35 +++++ .../ColorGrading/HDRColorGradingComponent.cpp | 30 ++++ .../ColorGrading/HDRColorGradingComponent.h | 33 ++++ .../HDRColorGradingComponentConfig.cpp | 47 ++++++ .../HDRColorGradingComponentController.cpp | 146 ++++++++++++++++++ .../HDRColorGradingComponentController.h | 59 +++++++ ...egration_commonfeatures_editor_files.cmake | 2 + ...omlyintegration_commonfeatures_files.cmake | 5 + ...egration_commonfeatures_public_files.cmake | 2 + 28 files changed, 1030 insertions(+), 17 deletions(-) create mode 100644 Gems/Atom/Feature/Common/Code/Include/Atom/Feature/PostProcess/ColorGrading/HDRColorGradingParams.inl create mode 100644 Gems/Atom/Feature/Common/Code/Include/Atom/Feature/PostProcess/ColorGrading/HDRColorGradingSettingsInterface.h create mode 100644 Gems/Atom/Feature/Common/Code/Source/PostProcess/ColorGrading/HDRColorGradingSettings.cpp create mode 100644 Gems/Atom/Feature/Common/Code/Source/PostProcess/ColorGrading/HDRColorGradingSettings.h create mode 100644 Gems/Atom/Feature/Common/Code/Source/PostProcessing/HDRColorGradingPass.cpp create mode 100644 Gems/Atom/Feature/Common/Code/Source/PostProcessing/HDRColorGradingPass.h create mode 100644 Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/PostProcess/ColorGrading/HDRColorGradingBus.h create mode 100644 Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/PostProcess/ColorGrading/HDRColorGradingComponentConfig.h create mode 100644 Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/EditorHDRColorGradingComponent.cpp create mode 100644 Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/EditorHDRColorGradingComponent.h create mode 100644 Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/HDRColorGradingComponent.cpp create mode 100644 Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/HDRColorGradingComponent.h create mode 100644 Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/HDRColorGradingComponentConfig.cpp create mode 100644 Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/HDRColorGradingComponentController.cpp create mode 100644 Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/HDRColorGradingComponentController.h diff --git a/Gems/Atom/Feature/Common/Assets/Passes/HDRColorGrading.pass b/Gems/Atom/Feature/Common/Assets/Passes/HDRColorGrading.pass index f1e8304b30..adcd43ce83 100644 --- a/Gems/Atom/Feature/Common/Assets/Passes/HDRColorGrading.pass +++ b/Gems/Atom/Feature/Common/Assets/Passes/HDRColorGrading.pass @@ -5,7 +5,7 @@ "ClassData": { "PassTemplate": { "Name": "HDRColorGradingTemplate", - "PassClass": "FullScreenTriangle", + "PassClass": "HDRColorGradingPass", "Slots": [ { "Name": "Input", @@ -85,7 +85,7 @@ }, { "Name": "m_whiteBalanceKelvin", - "Value": 6500.0 // 1000.0f ... 40000.0f kelvin + "Value": 6600.0 // 1000.0f ... 40000.0f kelvin }, { "Name": "m_whiteBalanceTint", @@ -96,7 +96,7 @@ "Value": 0.0 // -1 ... 1 }, { - "Name": "m_splitToneMix", + "Name": "m_splitToneWeight", "Value": 0.0 // 0 ... 1 }, { @@ -120,7 +120,7 @@ "Value": 1.0 // 0 ... 1 }, { - "Name": "m_smhMix", + "Name": "m_smhWeight", "Value": 0.0 // 0 ... 1 } ], diff --git a/Gems/Atom/Feature/Common/Assets/Passes/LightAdaptationParent.pass b/Gems/Atom/Feature/Common/Assets/Passes/LightAdaptationParent.pass index ff55ebc200..eec3634045 100644 --- a/Gems/Atom/Feature/Common/Assets/Passes/LightAdaptationParent.pass +++ b/Gems/Atom/Feature/Common/Assets/Passes/LightAdaptationParent.pass @@ -92,8 +92,8 @@ ] }, { - "Name": "LookModificationTransformPass", - "TemplateName": "LookModificationTransformTemplate", + "Name": "HDRColorGradingPass", + "TemplateName": "HDRColorGradingTemplate", "Enabled": true, "Connections": [ { @@ -102,6 +102,20 @@ "Pass": "Parent", "Attachment": "LightingInput" } + } + ] + }, + { + "Name": "LookModificationTransformPass", + "TemplateName": "LookModificationTransformTemplate", + "Enabled": true, + "Connections": [ + { + "LocalSlot": "Input", + "AttachmentRef": { + "Pass": "HDRColorGradingPass", + "Attachment": "Output" + } }, { "LocalSlot": "EyeAdaptationDataInput", diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/HDRColorGrading.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/HDRColorGrading.azsl index 9ae4a2bd68..cfa149f0d5 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/HDRColorGrading.azsl +++ b/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/HDRColorGrading.azsl @@ -50,13 +50,13 @@ ShaderResourceGroup PassSrg : SRG_PerPass_WithFallback float m_whiteBalanceKelvin; float m_whiteBalanceTint; float m_splitToneBalance; - float m_splitToneMix; + float m_splitToneWeight; float m_colorGradingPostSaturation; float m_smhShadowsStart; float m_smhShadowsEnd; float m_smhHighlightsStart; float m_smhHighlightsEnd; - float m_smhMix; + float m_smhWeight; float3 m_channelMixingRed; float3 m_channelMixingGreen; @@ -69,9 +69,6 @@ ShaderResourceGroup PassSrg : SRG_PerPass_WithFallback float4 m_smhShadowsColor; float4 m_smhMidtonesColor; float4 m_smhHighlightsColor; - - // my color grading output - float4 m_color; } float SaturateWithEpsilon(float value) @@ -133,7 +130,7 @@ float3 NoNanPow(float3 base, float3 power) return pow(max(abs(base), float3(FloatEpsilon, FloatEpsilon, FloatEpsilon)), power); } -float3 ColorGradeSplitTone (float3 frameColor, float balance, float mix) +float3 ColorGradeSplitTone (float3 frameColor, float balance, float weight) { float3 frameSplitTone = NoNanPow(frameColor, 1.0 / 2.2); const float t = SaturateWithEpsilon(CalculateLuminance(SaturateWithEpsilon(frameSplitTone), ColorSpaceId::ACEScg) + balance); @@ -142,7 +139,7 @@ float3 ColorGradeSplitTone (float3 frameColor, float balance, float mix) frameSplitTone = BlendMode_SoftLight(frameSplitTone, shadows); frameSplitTone = BlendMode_SoftLight(frameSplitTone, highlights); frameSplitTone = NoNanPow(frameSplitTone, 2.2); - return lerp(frameColor.rgb, frameSplitTone.rgb, mix); + return lerp(frameColor.rgb, frameSplitTone.rgb, weight); } float3 ColorGradeChannelMixer (float3 frameColor) @@ -154,7 +151,7 @@ float3 ColorGradeChannelMixer (float3 frameColor) } float3 ColorGradeShadowsMidtonesHighlights (float3 frameColor, float shadowsStart, float shadowsEnd, - float highlightsStart, float highlightsEnd, float mix, + float highlightsStart, float highlightsEnd, float weight, float4 shadowsColor, float4 midtonesColor, float4 highlightsColor) { const float3 shadowsColorACEScg = TransformColor(shadowsColor.rgb, ColorSpaceId::LinearSRGB, ColorSpaceId::ACEScg); @@ -169,7 +166,7 @@ float3 ColorGradeShadowsMidtonesHighlights (float3 frameColor, float shadowsStar const float3 frameSmh = frameColor * shadowsColorACEScg * shadowsWeight + frameColor * midtonesColorACEScg * midtonesWeight + frameColor * highlightsColorACEScg * highlightsWeight; - return lerp(frameColor.rgb, frameSmh.rgb, mix); + return lerp(frameColor.rgb, frameSmh.rgb, weight); } float3 ColorGrade (float3 frameColor) @@ -181,11 +178,11 @@ float3 ColorGrade (float3 frameColor) PassSrg::m_colorFilterMultiply); frameColor = max(frameColor, 0.0); frameColor = ColorGradeSaturation(frameColor, PassSrg::m_colorGradingPreSaturation); - frameColor = ColorGradeSplitTone(frameColor, PassSrg::m_splitToneBalance, PassSrg::m_splitToneMix); + frameColor = ColorGradeSplitTone(frameColor, PassSrg::m_splitToneBalance, PassSrg::m_splitToneWeight); frameColor = ColorGradeChannelMixer(frameColor); frameColor = max(frameColor, 0.0); frameColor = ColorGradeShadowsMidtonesHighlights(frameColor, PassSrg::m_smhShadowsStart, PassSrg::m_smhShadowsEnd, - PassSrg::m_smhHighlightsStart, PassSrg::m_smhHighlightsEnd, PassSrg::m_smhMix, + PassSrg::m_smhHighlightsStart, PassSrg::m_smhHighlightsEnd, PassSrg::m_smhWeight, PassSrg::m_smhShadowsColor, PassSrg::m_smhMidtonesColor, PassSrg::m_smhHighlightsColor); frameColor = ColorGradeHueShift(frameColor, PassSrg::m_colorGradingHueShift); frameColor = ColorGradeSaturation(frameColor, PassSrg::m_colorGradingPostSaturation); diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/PostProcess/ColorGrading/HDRColorGradingParams.inl b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/PostProcess/ColorGrading/HDRColorGradingParams.inl new file mode 100644 index 0000000000..241ba3b5de --- /dev/null +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/PostProcess/ColorGrading/HDRColorGradingParams.inl @@ -0,0 +1,37 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +// Macros below are of the form: +// PARAM(NAME, MEMBER_NAME, DEFAULT_VALUE, ...) + +AZ_GFX_BOOL_PARAM(Enabled, m_enabled, false) +AZ_GFX_FLOAT_PARAM(ColorGradingExposure, m_colorGradingExposure, 0.0) +AZ_GFX_FLOAT_PARAM(ColorGradingContrast, m_colorGradingContrast, 0.0) +AZ_GFX_FLOAT_PARAM(ColorGradingHueShift, m_colorGradingHueShift, 0.0) +AZ_GFX_FLOAT_PARAM(ColorGradingPreSaturation, m_colorGradingPreSaturation, 1.0) +AZ_GFX_FLOAT_PARAM(ColorGradingFilterIntensity, m_colorGradingFilterIntensity, 1.0) +AZ_GFX_FLOAT_PARAM(ColorGradingFilterMultiply, m_colorGradingFilterMultiply, 0.0) +AZ_GFX_FLOAT_PARAM(ColorGradingPostSaturation, m_colorGradingPostSaturation, 1.0) +AZ_GFX_FLOAT_PARAM(WhiteBalanceKelvin, m_whiteBalanceKelvin, 6600.0) +AZ_GFX_FLOAT_PARAM(WhiteBalanceTint, m_whiteBalanceTint, 0.0) +AZ_GFX_FLOAT_PARAM(SplitToneBalance, m_splitToneBalance, 0.0) +AZ_GFX_FLOAT_PARAM(SplitToneWeight, m_splitToneWeight, 0.0) +AZ_GFX_FLOAT_PARAM(SmhShadowsStart, m_smhShadowsStart, 0.0) +AZ_GFX_FLOAT_PARAM(SmhShadowsEnd, m_smhShadowsEnd, 0.3) +AZ_GFX_FLOAT_PARAM(SmhHighlightsStart, m_smhHighlightsStart, 0.55) +AZ_GFX_FLOAT_PARAM(SmhHighlightsEnd, m_smhHighlightsEnd, 1.0) +AZ_GFX_FLOAT_PARAM(SmhWeight, m_smhWeight, 0.0) +AZ_GFX_VEC3_PARAM(ChannelMixingRed, m_channelMixingRed, AZ::Vector3(1.0f, 0.0f, 0.0f)) +AZ_GFX_VEC3_PARAM(ChannelMixingGreen, m_channelMixingGreen, AZ::Vector3(0.0f, 1.0f, 0.0f)) +AZ_GFX_VEC3_PARAM(ChannelMixingBlue, m_channelMixingBlue, AZ::Vector3(0.0f, 0.f, 1.0f)) +AZ_GFX_VEC3_PARAM(ColorFilterSwatch, m_colorFilterSwatch, AZ::Vector3(1.0f, 0.5f, 0.5f)) +AZ_GFX_VEC3_PARAM(SplitToneShadowsColor, m_splitToneShadowsColor, AZ::Vector3(1.0f, 0.5f, 0.5f)) +AZ_GFX_VEC3_PARAM(SplitToneHighlightsColor, m_splitToneHighlightsColor, AZ::Vector3(0.1f, 1.0f, 0.1f)) +AZ_GFX_VEC3_PARAM(SmhShadowsColor, m_smhShadowsColor, AZ::Vector3(1.0f, 0.25f, 0.25f)) +AZ_GFX_VEC3_PARAM(SmhMidtonesColor, m_smhMidtonesColor, AZ::Vector3(0.1f, 0.1f, 1.0f)) +AZ_GFX_VEC3_PARAM(SmhHighlightsColor, m_smhHighlightsColor, AZ::Vector3(1.0f, 0.0f, 1.0f)) diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/PostProcess/ColorGrading/HDRColorGradingSettingsInterface.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/PostProcess/ColorGrading/HDRColorGradingSettingsInterface.h new file mode 100644 index 0000000000..019df206eb --- /dev/null +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/PostProcess/ColorGrading/HDRColorGradingSettingsInterface.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include +#include +#include + +namespace AZ +{ + namespace Render + { + class HDRColorGradingSettingsInterface + { + public: + AZ_RTTI(AZ::Render::HDRColorGradingSettingsInterface, "{CB5ADF78-27DE-438C-A991-1E5433046A42}"); + + // Auto-gen virtual getter and setter functions... +#include +#include +#include + + virtual void OnConfigChanged() = 0; + }; + } +} diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/PostProcess/PostProcessSettings.inl b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/PostProcess/PostProcessSettings.inl index 0259f07525..8409732f34 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/PostProcess/PostProcessSettings.inl +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/PostProcess/PostProcessSettings.inl @@ -25,3 +25,4 @@ POST_PROCESS_MEMBER(ExposureControlSettings, m_exposureControlSettings) POST_PROCESS_MEMBER(SsaoSettings, m_ssaoSettings) POST_PROCESS_MEMBER(LookModificationSettings, m_lookModificationSettings) POST_PROCESS_MEMBER(DeferredFogSettings, m_deferredFogSettings) +POST_PROCESS_MEMBER(HDRColorGradingSettings, m_hdrColorGradingSettings) diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/PostProcess/PostProcessSettingsInterface.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/PostProcess/PostProcessSettingsInterface.h index 12c0017aad..905aa9f2ca 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/PostProcess/PostProcessSettingsInterface.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/PostProcess/PostProcessSettingsInterface.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include diff --git a/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.cpp b/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.cpp index de03c08c6f..db49fba96f 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -222,6 +223,7 @@ namespace AZ passSystem->AddPassCreator(Name("LightCullingRemapPass"), &LightCullingRemap::Create); passSystem->AddPassCreator(Name("LightCullingTilePreparePass"), &LightCullingTilePreparePass::Create); passSystem->AddPassCreator(Name("BlendColorGradingLutsPass"), &BlendColorGradingLutsPass::Create); + passSystem->AddPassCreator(Name("HDRColorGradingPass"), &HDRColorGradingPass::Create); passSystem->AddPassCreator(Name("LookModificationCompositePass"), &LookModificationCompositePass::Create); passSystem->AddPassCreator(Name("LookModificationTransformPass"), &LookModificationPass::Create); passSystem->AddPassCreator(Name("SMAAEdgeDetectionPass"), &SMAAEdgeDetectionPass::Create); diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcess/ColorGrading/HDRColorGradingSettings.cpp b/Gems/Atom/Feature/Common/Code/Source/PostProcess/ColorGrading/HDRColorGradingSettings.cpp new file mode 100644 index 0000000000..4542b53a15 --- /dev/null +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcess/ColorGrading/HDRColorGradingSettings.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ +#include + +#include +#include + +namespace AZ +{ + namespace Render + { + HDRColorGradingSettings::HDRColorGradingSettings(PostProcessFeatureProcessor* featureProcessor) + : PostProcessBase(featureProcessor) + { + } + + void HDRColorGradingSettings::OnConfigChanged() + { + m_parentSettings->OnConfigChanged(); + } + + void HDRColorGradingSettings::ApplySettingsTo(HDRColorGradingSettings* target, [[maybe_unused]] float alpha) const + { + AZ_Assert(target != nullptr, "HDRColorGradingSettings::ApplySettingsTo called with nullptr as argument."); + + if (GetEnabled()) + { + target->m_enabled = m_enabled; + +#define AZ_GFX_BOOL_PARAM(NAME, MEMBER_NAME, DefaultValue) ; +#define AZ_GFX_FLOAT_PARAM(NAME, MEMBER_NAME, DefaultValue) \ + { \ + target->Set##NAME(AZ::Lerp(target->MEMBER_NAME, MEMBER_NAME, alpha)); \ + } + +#define AZ_GFX_VEC3_PARAM(NAME, MEMBER_NAME, DefaultValue) \ + { \ + target->MEMBER_NAME.Set(AZ::Lerp(target->MEMBER_NAME.GetX(), MEMBER_NAME.GetX(), alpha), \ + AZ::Lerp(target->MEMBER_NAME.GetY(), MEMBER_NAME.GetY(), alpha), \ + AZ::Lerp(target->MEMBER_NAME.GetZ(), MEMBER_NAME.GetZ(), alpha)); \ + } + +#include +#include + } + } + + void HDRColorGradingSettings::Simulate([[maybe_unused]] float deltaTime) + { + } + } // namespace Render +} // namespace AZ + + diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcess/ColorGrading/HDRColorGradingSettings.h b/Gems/Atom/Feature/Common/Code/Source/PostProcess/ColorGrading/HDRColorGradingSettings.h new file mode 100644 index 0000000000..2358919c28 --- /dev/null +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcess/ColorGrading/HDRColorGradingSettings.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include + +#include + +#include + +namespace AZ +{ + namespace Render + { + class PostProcessSettings; + + class HDRColorGradingSettings final + : public HDRColorGradingSettingsInterface + , public PostProcessBase + { + friend class PostProcessSettings; + friend class PostProcessFeatureProcessor; + + public: + AZ_RTTI(HDRColorGradingSettings, "{EA8C05D4-66D0-4141-8D4D-68E5D764C2ED}", HDRColorGradingSettingsInterface, PostProcessBase); + AZ_CLASS_ALLOCATOR(HDRColorGradingSettings, SystemAllocator, 0); + + HDRColorGradingSettings(PostProcessFeatureProcessor* featureProcessor); + ~HDRColorGradingSettings() = default; + + void OnConfigChanged() override; + + void ApplySettingsTo(HDRColorGradingSettings* target, float alpha) const; + + // Generate all getters and override setters. + // Declare non-override setters, which will be defined in the .cpp +#define AZ_GFX_COMMON_PARAM(ValueType, Name, MemberName, DefaultValue) \ + ValueType Get##Name() const override { return MemberName; } \ + void Set##Name(ValueType val) override \ + { \ + MemberName = val; \ + } \ + +#define AZ_GFX_COMMON_OVERRIDE(ValueType, Name, MemberName, OverrideValueType) \ + OverrideValueType Get##Name##Override() const override { return MemberName##Override; } \ + void Set##Name##Override(OverrideValueType val) override { MemberName##Override = val; } \ + +#include +#include +#include + + private: + // Generate members... +#include +#include +#include + + void Simulate(float deltaTime); + + PostProcessSettings* m_parentSettings = nullptr; + }; + } +} diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcess/PostProcessSettings.h b/Gems/Atom/Feature/Common/Code/Source/PostProcess/PostProcessSettings.h index 515326e357..c2a32e6cee 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcess/PostProcessSettings.h +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcess/PostProcessSettings.h @@ -17,6 +17,7 @@ #include #include #include +#include #include namespace AZ diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/HDRColorGradingPass.cpp b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/HDRColorGradingPass.cpp new file mode 100644 index 0000000000..62fff6b6fe --- /dev/null +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/HDRColorGradingPass.cpp @@ -0,0 +1,135 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include + +#include +#include +#include + + namespace AZ +{ + namespace Render + { + RPI::Ptr HDRColorGradingPass::Create(const RPI::PassDescriptor& descriptor) + { + RPI::Ptr pass = aznew HDRColorGradingPass(descriptor); + return AZStd::move(pass); + } + + HDRColorGradingPass::HDRColorGradingPass(const RPI::PassDescriptor& descriptor) + : AZ::RPI::FullscreenTrianglePass(descriptor) + { + } + + void HDRColorGradingPass::InitializeInternal() + { + FullscreenTrianglePass::InitializeInternal(); + + m_colorGradingExposureIndex.Reset(); + m_colorGradingContrastIndex.Reset(); + m_colorGradingHueShiftIndex.Reset(); + m_colorGradingPreSaturationIndex.Reset(); + m_colorFilterIntensityIndex.Reset(); + m_colorFilterMultiplyIndex.Reset(); + m_whiteBalanceKelvinIndex.Reset(); + m_whiteBalanceTintIndex.Reset(); + m_splitToneBalanceIndex.Reset(); + m_splitToneWeightIndex.Reset(); + m_colorGradingPostSaturationIndex.Reset(); + m_smhShadowsStartIndex.Reset(); + m_smhShadowsEndIndex.Reset(); + m_smhHighlightsStartIndex.Reset(); + m_smhHighlightsEndIndex.Reset(); + m_smhWeightIndex.Reset(); + + m_channelMixingRedIndex.Reset(); + m_channelMixingGreenIndex.Reset(); + m_channelMixingBlueIndex.Reset(); + + m_colorFilterSwatchIndex.Reset(); + m_splitToneShadowsColorIndex.Reset(); + m_splitToneHighlightsColorIndex.Reset(); + m_smhShadowsColorIndex.Reset(); + m_smhMidtonesColorIndex.Reset(); + m_smhHighlightsColorIndex.Reset(); + } + + void HDRColorGradingPass::FrameBeginInternal(FramePrepareParams params) + { + SetSrgConstants(); + + FullscreenTrianglePass::FrameBeginInternal(params); + } + + bool HDRColorGradingPass::IsEnabled() const + { + const auto* colorGradingSettings = GetHDRColorGradingSettings(); + return colorGradingSettings ? colorGradingSettings->GetEnabled() : false; + } + + void HDRColorGradingPass::SetSrgConstants() + { + const HDRColorGradingSettings* settings = GetHDRColorGradingSettings(); + if (settings) + { + m_shaderResourceGroup->SetConstant(m_colorGradingExposureIndex, settings->GetColorGradingExposure()); + m_shaderResourceGroup->SetConstant(m_colorGradingContrastIndex, settings->GetColorGradingContrast()); + m_shaderResourceGroup->SetConstant(m_colorGradingHueShiftIndex, settings->GetColorGradingHueShift()); + m_shaderResourceGroup->SetConstant(m_colorGradingPreSaturationIndex, settings->GetColorGradingPreSaturation()); + m_shaderResourceGroup->SetConstant(m_colorFilterIntensityIndex, settings->GetColorGradingFilterIntensity()); + m_shaderResourceGroup->SetConstant(m_colorFilterMultiplyIndex, settings->GetColorGradingFilterMultiply()); + m_shaderResourceGroup->SetConstant(m_whiteBalanceKelvinIndex, settings->GetWhiteBalanceKelvin()); + m_shaderResourceGroup->SetConstant(m_whiteBalanceTintIndex, settings->GetWhiteBalanceTint()); + m_shaderResourceGroup->SetConstant(m_splitToneBalanceIndex, settings->GetSplitToneBalance()); + m_shaderResourceGroup->SetConstant(m_splitToneWeightIndex, settings->GetSplitToneWeight()); + m_shaderResourceGroup->SetConstant(m_colorGradingPostSaturationIndex, settings->GetColorGradingPostSaturation()); + m_shaderResourceGroup->SetConstant(m_smhShadowsStartIndex, settings->GetSmhShadowsStart()); + m_shaderResourceGroup->SetConstant(m_smhShadowsEndIndex, settings->GetSmhShadowsEnd()); + m_shaderResourceGroup->SetConstant(m_smhHighlightsStartIndex, settings->GetSmhHighlightsStart()); + m_shaderResourceGroup->SetConstant(m_smhHighlightsEndIndex, settings->GetSmhHighlightsEnd()); + m_shaderResourceGroup->SetConstant(m_smhWeightIndex, settings->GetSmhWeight()); + + m_shaderResourceGroup->SetConstant(m_channelMixingRedIndex, settings->GetChannelMixingRed()); + m_shaderResourceGroup->SetConstant(m_channelMixingGreenIndex, settings->GetChannelMixingGreen()); + m_shaderResourceGroup->SetConstant(m_channelMixingBlueIndex, settings->GetChannelMixingBlue()); + + m_shaderResourceGroup->SetConstant(m_colorFilterSwatchIndex, AZ::Vector4(settings->GetColorFilterSwatch())); + m_shaderResourceGroup->SetConstant(m_splitToneShadowsColorIndex, AZ::Vector4(settings->GetSplitToneShadowsColor())); + m_shaderResourceGroup->SetConstant(m_splitToneHighlightsColorIndex, AZ::Vector4(settings->GetSplitToneHighlightsColor())); + m_shaderResourceGroup->SetConstant(m_smhShadowsColorIndex, AZ::Vector4(settings->GetSmhShadowsColor())); + m_shaderResourceGroup->SetConstant(m_smhMidtonesColorIndex, AZ::Vector4(settings->GetSmhMidtonesColor())); + m_shaderResourceGroup->SetConstant(m_smhHighlightsColorIndex, AZ::Vector4(settings->GetSmhHighlightsColor())); + } + } + + const AZ::Render::HDRColorGradingSettings* HDRColorGradingPass::GetHDRColorGradingSettings() const + { + RPI::Scene* scene = GetScene(); + if (scene) + { + PostProcessFeatureProcessor* fp = scene->GetFeatureProcessor(); + AZ::RPI::ViewPtr view = scene->GetDefaultRenderPipeline()->GetDefaultView(); + if (fp) + { + PostProcessSettings* postProcessSettings = fp->GetLevelSettingsFromView(view); + if (postProcessSettings) + { + const HDRColorGradingSettings* colorGradingSettings = postProcessSettings->GetHDRColorGradingSettings(); + if (colorGradingSettings != nullptr && colorGradingSettings->GetEnabled()) + { + return postProcessSettings->GetHDRColorGradingSettings(); + } + } + } + } + return nullptr; + } + } +} diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/HDRColorGradingPass.h b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/HDRColorGradingPass.h new file mode 100644 index 0000000000..e5eaf7db26 --- /dev/null +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/HDRColorGradingPass.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ +#pragma once + +#include +#include +#include +#include +#include + +namespace AZ +{ + namespace Render + { + /** + * The color grading pass. + */ + class HDRColorGradingPass + : public AZ::RPI::FullscreenTrianglePass + //TODO: , public PostProcessingShaderOptionBase + { + public: + AZ_RTTI(HDRColorGradingPass, "{E68E31A1-DB24-4AFF-A029-456A8B74C03C}", AZ::RPI::FullscreenTrianglePass); + AZ_CLASS_ALLOCATOR(HDRColorGradingPass, SystemAllocator, 0); + + virtual ~HDRColorGradingPass() = default; + + //! Creates a ColorGradingPass + static RPI::Ptr Create(const RPI::PassDescriptor& descriptor); + + protected: + HDRColorGradingPass(const RPI::PassDescriptor& descriptor); + + //! Pass behavior overrides + void InitializeInternal() override; + void FrameBeginInternal(FramePrepareParams params) override; + bool IsEnabled() const override; + + private: + const HDRColorGradingSettings* GetHDRColorGradingSettings() const; + void SetSrgConstants(); + + RHI::ShaderInputNameIndex m_colorGradingExposureIndex = "m_colorGradingExposure"; + RHI::ShaderInputNameIndex m_colorGradingContrastIndex = "m_colorGradingContrast"; + RHI::ShaderInputNameIndex m_colorGradingHueShiftIndex = "m_colorGradingHueShift"; + RHI::ShaderInputNameIndex m_colorGradingPreSaturationIndex = "m_colorGradingPreSaturation"; + RHI::ShaderInputNameIndex m_colorFilterIntensityIndex = "m_colorFilterIntensity"; + RHI::ShaderInputNameIndex m_colorFilterMultiplyIndex = "m_colorFilterMultiply"; + RHI::ShaderInputNameIndex m_whiteBalanceKelvinIndex = "m_whiteBalanceKelvin"; + RHI::ShaderInputNameIndex m_whiteBalanceTintIndex = "m_whiteBalanceTint"; + RHI::ShaderInputNameIndex m_splitToneBalanceIndex = "m_splitToneBalance"; + RHI::ShaderInputNameIndex m_splitToneWeightIndex = "m_splitToneWeight"; + RHI::ShaderInputNameIndex m_colorGradingPostSaturationIndex = "m_colorGradingPostSaturation"; + RHI::ShaderInputNameIndex m_smhShadowsStartIndex = "m_smhShadowsStart"; + RHI::ShaderInputNameIndex m_smhShadowsEndIndex = "m_smhShadowsEnd"; + RHI::ShaderInputNameIndex m_smhHighlightsStartIndex = "m_smhHighlightsStart"; + RHI::ShaderInputNameIndex m_smhHighlightsEndIndex = "m_smhHighlightsEnd"; + RHI::ShaderInputNameIndex m_smhWeightIndex = "m_smhWeight"; + + RHI::ShaderInputNameIndex m_channelMixingRedIndex = "m_channelMixingRed"; + RHI::ShaderInputNameIndex m_channelMixingGreenIndex = "m_channelMixingGreen"; + RHI::ShaderInputNameIndex m_channelMixingBlueIndex = "m_channelMixingBlue"; + + RHI::ShaderInputNameIndex m_colorFilterSwatchIndex = "m_colorFilterSwatch"; + RHI::ShaderInputNameIndex m_splitToneShadowsColorIndex = "m_splitToneShadowsColor"; + RHI::ShaderInputNameIndex m_splitToneHighlightsColorIndex = "m_splitToneHighlightsColor"; + RHI::ShaderInputNameIndex m_smhShadowsColorIndex = "m_smhShadowsColor"; + RHI::ShaderInputNameIndex m_smhMidtonesColorIndex = "m_smhMidtonesColor"; + RHI::ShaderInputNameIndex m_smhHighlightsColorIndex = "m_smhHighlightsColor"; + }; + } // namespace Render +} // namespace AZ diff --git a/Gems/Atom/Feature/Common/Code/atom_feature_common_files.cmake b/Gems/Atom/Feature/Common/Code/atom_feature_common_files.cmake index 40188109ca..92f96a591b 100644 --- a/Gems/Atom/Feature/Common/Code/atom_feature_common_files.cmake +++ b/Gems/Atom/Feature/Common/Code/atom_feature_common_files.cmake @@ -183,6 +183,8 @@ set(FILES Source/PostProcess/PostProcessFeatureProcessor.h Source/PostProcess/PostProcessSettings.cpp Source/PostProcess/PostProcessSettings.h + Source/PostProcess/ColorGrading/HDRColorGradingSettings.h + Source/PostProcess/ColorGrading/HDRColorGradingSettings.cpp Source/PostProcess/Bloom/BloomSettings.cpp Source/PostProcess/Bloom/BloomSettings.h Source/PostProcess/DepthOfField/DepthOfFieldSettings.cpp @@ -205,6 +207,8 @@ set(FILES Source/PostProcessing/BloomCompositePass.cpp Source/PostProcessing/BloomParentPass.h Source/PostProcessing/BloomParentPass.cpp + Source/PostProcessing/HDRColorGradingPass.cpp + Source/PostProcessing/HDRColorGradingPass.h Source/PostProcessing/DepthOfFieldCompositePass.h Source/PostProcessing/DepthOfFieldCompositePass.cpp Source/PostProcessing/DepthOfFieldBokehBlurPass.h diff --git a/Gems/Atom/Feature/Common/Code/atom_feature_common_public_files.cmake b/Gems/Atom/Feature/Common/Code/atom_feature_common_public_files.cmake index 89febbcf3d..d7af7b0108 100644 --- a/Gems/Atom/Feature/Common/Code/atom_feature_common_public_files.cmake +++ b/Gems/Atom/Feature/Common/Code/atom_feature_common_public_files.cmake @@ -51,6 +51,8 @@ set(FILES Include/Atom/Feature/PostProcess/Bloom/BloomConstants.h Include/Atom/Feature/PostProcess/Bloom/BloomParams.inl Include/Atom/Feature/PostProcess/Bloom/BloomSettingsInterface.h + Include/Atom/Feature/PostProcess/ColorGrading/HDRColorGradingParams.inl + Include/Atom/Feature/PostProcess/ColorGrading/HDRColorGradingSettingsInterface.h Include/Atom/Feature/PostProcess/DepthOfField/DepthOfFieldConstants.h Include/Atom/Feature/PostProcess/DepthOfField/DepthOfFieldParams.inl Include/Atom/Feature/PostProcess/DepthOfField/DepthOfFieldSettingsInterface.h diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/PostProcess/ColorGrading/HDRColorGradingBus.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/PostProcess/ColorGrading/HDRColorGradingBus.h new file mode 100644 index 0000000000..32b1c97429 --- /dev/null +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/PostProcess/ColorGrading/HDRColorGradingBus.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include + +namespace AZ +{ + namespace Render + { + class HDRColorGradingRequests + : public ComponentBus + { + public: + AZ_RTTI(AZ::Render::HDRColorGradingRequests, "{E414A96B-0AA7-4574-ABC0-968B1F5CEE56}"); + + /// Overrides the default AZ::EBusTraits handler policy to allow one listener only. + static const EBusHandlerPolicy HandlerPolicy = EBusHandlerPolicy::Single; + virtual ~HDRColorGradingRequests() {} + // Auto-gen virtual getters/setters... +#include +#include +#include + }; + + typedef AZ::EBus HDRColorGradingRequestBus; + } // namespace Render +} // namespace AZ diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/PostProcess/ColorGrading/HDRColorGradingComponentConfig.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/PostProcess/ColorGrading/HDRColorGradingComponentConfig.h new file mode 100644 index 0000000000..fe7bc874a4 --- /dev/null +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/PostProcess/ColorGrading/HDRColorGradingComponentConfig.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include + +namespace AZ +{ + namespace Render + { + class HDRColorGradingComponentConfig final + : public ComponentConfig + { + public: + AZ_RTTI(AZ::Render::HDRColorGradingComponentConfig, "{8613EA4A-6E1C-49AD-87F3-9FECCB7EA36D}", AZ::ComponentConfig); + + static void Reflect(ReflectContext* context); + + // Generate members... +#include +#include +#include + + // Generate Getters/Setters... +#include +#include +#include + + void CopySettingsTo(HDRColorGradingSettingsInterface* settings); + }; + } // namespace Render +} // namespace AZ diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Module.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Module.cpp index a83e2e9fa1..230130826e 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Module.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Module.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -57,6 +58,7 @@ #include #include #include +#include #include #include #include @@ -93,6 +95,7 @@ namespace AZ DecalComponent::CreateDescriptor(), DirectionalLightComponent::CreateDescriptor(), BloomComponent::CreateDescriptor(), + HDRColorGradingComponent::CreateDescriptor(), DisplayMapperComponent::CreateDescriptor(), DepthOfFieldComponent::CreateDescriptor(), ExposureControlComponent::CreateDescriptor(), @@ -124,6 +127,7 @@ namespace AZ EditorDecalComponent::CreateDescriptor(), EditorDirectionalLightComponent::CreateDescriptor(), EditorBloomComponent::CreateDescriptor(), + EditorHDRColorGradingComponent::CreateDescriptor(), EditorDepthOfFieldComponent::CreateDescriptor(), EditorDisplayMapperComponent::CreateDescriptor(), EditorExposureControlComponent::CreateDescriptor(), diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/EditorHDRColorGradingComponent.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/EditorHDRColorGradingComponent.cpp new file mode 100644 index 0000000000..49c8275141 --- /dev/null +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/EditorHDRColorGradingComponent.cpp @@ -0,0 +1,145 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include + +namespace AZ +{ + namespace Render + { + void EditorHDRColorGradingComponent::Reflect(AZ::ReflectContext* context) + { + BaseClass::Reflect(context); + + if (AZ::SerializeContext* serializeContext = azrtti_cast(context)) + { + serializeContext->Class()->Version(1); + + if (AZ::EditContext* editContext = serializeContext->GetEditContext()) + { + editContext->Class( + "HDR Color Grading", "Tune and apply color grading in HDR.") + ->ClassElement(Edit::ClassElements::EditorData, "") + ->Attribute(Edit::Attributes::Category, "Atom") + ->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/Component_Placeholder.svg") // [GFX TODO ATOM-2672][PostFX] need to create icons for PostProcessing. + ->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/Component_Placeholder.svg") // [GFX TODO ATOM-2672][PostFX] need to create icons for PostProcessing. + ->Attribute(Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("Game")) + ->Attribute(Edit::Attributes::AutoExpand, true) + ->Attribute(Edit::Attributes::HelpPageURL, "https://") // [TODO ATOM-2672][PostFX] need to create page for PostProcessing. + ; + + editContext->Class( + "HDRColorGradingComponentControl", "") + ->ClassElement(AZ::Edit::ClassElements::EditorData, "") + ->Attribute(AZ::Edit::Attributes::AutoExpand, true) + ->DataElement(AZ::Edit::UIHandlers::Default, &HDRColorGradingComponentController::m_configuration, "Configuration", "") + ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) + ; + + editContext->Class("HDRColorGradingComponentConfig", "") + ->DataElement(Edit::UIHandlers::CheckBox, &HDRColorGradingComponentConfig::m_enabled, + "Enable HDR color grading", + "Enable HDR color grading.") + ->ClassElement(AZ::Edit::ClassElements::Group, "Color Adjustment") + ->Attribute(AZ::Edit::Attributes::AutoExpand, true) + ->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_colorGradingExposure, "Exposure", "Exposure Value") + ->Attribute(Edit::Attributes::Min, AZStd::numeric_limits::lowest()) + ->Attribute(Edit::Attributes::Max, AZStd::numeric_limits::max()) + ->Attribute(Edit::Attributes::SoftMin, -20.0f) + ->Attribute(Edit::Attributes::SoftMax, 20.0f) + ->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_colorGradingContrast, "Contrast", "Contrast Value") + ->Attribute(Edit::Attributes::Min, -100.0f) + ->Attribute(Edit::Attributes::Max, 100.0f) + ->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_colorGradingPreSaturation, "Pre Saturation", "Pre Saturation Value") + ->Attribute(Edit::Attributes::Min, -100.0f) + ->Attribute(Edit::Attributes::Max, 100.0f) + ->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_colorGradingFilterIntensity, "Filter Intensity", "Filter Intensity Value") + ->Attribute(Edit::Attributes::Min, AZStd::numeric_limits::lowest()) + ->Attribute(Edit::Attributes::Max, AZStd::numeric_limits::max()) + ->Attribute(Edit::Attributes::SoftMin, -1.0f) + ->Attribute(Edit::Attributes::SoftMax, 1.0f) + ->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_colorGradingFilterMultiply, "Filter Multiply", "Filter Multiply Value") + ->Attribute(Edit::Attributes::Min, 0.0f) + ->Attribute(Edit::Attributes::Max, 1.0f) + ->DataElement(AZ::Edit::UIHandlers::Color, &HDRColorGradingComponentConfig::m_colorFilterSwatch, "Color Filter Swatch", "Color Filter Swatch Value") + + ->ClassElement(AZ::Edit::ClassElements::Group, "White Balance") + ->Attribute(AZ::Edit::Attributes::AutoExpand, true) + ->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_whiteBalanceKelvin, "Temperature", "Temperature in Kelvin") + ->Attribute(Edit::Attributes::Min, 1000.0f) + ->Attribute(Edit::Attributes::Max, 40000.0f) + ->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_whiteBalanceTint, "Tint", "Tint Value") + ->Attribute(Edit::Attributes::Min, -100.0f) + ->Attribute(Edit::Attributes::Max, 100.0f) + + ->ClassElement(AZ::Edit::ClassElements::Group, "Split Toning") + ->Attribute(AZ::Edit::Attributes::AutoExpand, true) + ->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_splitToneWeight, "Split Tone Weight", "Modulates the split toning effect.") + ->Attribute(Edit::Attributes::Min, 0.0f) + ->Attribute(Edit::Attributes::Max, 1.0f) + ->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_splitToneBalance, "Split Tone Balance", "Split Tone Balance Value") + ->Attribute(Edit::Attributes::Min, 0.0f) + ->Attribute(Edit::Attributes::Max, 1.0f) + ->DataElement(AZ::Edit::UIHandlers::Color, &HDRColorGradingComponentConfig::m_splitToneShadowsColor, "Split Tone Shadows Color", "Split Tone Shadows Color") + ->DataElement(AZ::Edit::UIHandlers::Color, &HDRColorGradingComponentConfig::m_splitToneHighlightsColor, "Split Tone Highlights Color", "Split Tone Highlights Color") + + ->ClassElement(AZ::Edit::ClassElements::Group, "Channel Mixing") + ->Attribute(AZ::Edit::Attributes::AutoExpand, true) + ->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_channelMixingRed, "Channel Mixing Red", "Channel Mixing Red Value") + ->Attribute(Edit::Attributes::Min, 0.0f) + ->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_channelMixingGreen, "Channel Mixing Green", "Channel Mixing Green Value") + ->Attribute(Edit::Attributes::Min, 0.0f) + ->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_channelMixingBlue, "Channel Mixing Blue", "Channel Mixing Blue Value") + ->Attribute(Edit::Attributes::Min, 0.0f) + + ->ClassElement(AZ::Edit::ClassElements::Group, "Shadow Midtones Highlights") + ->Attribute(AZ::Edit::Attributes::AutoExpand, true) + ->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_smhWeight, "SMH Weight", "Modulates the SMH effect.") + ->Attribute(Edit::Attributes::Min, 0.0f) + ->Attribute(Edit::Attributes::Max, 1.0f) + ->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_smhShadowsStart, "SMH Shadows Start", "SMH Shadows Start Value") + ->Attribute(Edit::Attributes::Min, 0.0f) + ->Attribute(Edit::Attributes::Max, 1.0f) + ->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_smhShadowsEnd, "SMH Shadows End", "SMH Shadows End Value") + ->Attribute(Edit::Attributes::Min, 0.0f) + ->Attribute(Edit::Attributes::Max, 1.0f) + ->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_smhHighlightsStart, "SMH Highlights Start", "SMH Highlights Start Value") + ->Attribute(Edit::Attributes::Min, 0.0f) + ->Attribute(Edit::Attributes::Max, 1.0f) + ->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_smhHighlightsEnd, "SMH Highlights End", "SMH Highlights End Value") + ->Attribute(Edit::Attributes::Min, 0.0f) + ->Attribute(Edit::Attributes::Max, 1.0f) + ->DataElement(AZ::Edit::UIHandlers::Color, &HDRColorGradingComponentConfig::m_smhShadowsColor, "SMH Shadows Color", "SMH Shadows Color") + ->DataElement(AZ::Edit::UIHandlers::Color, &HDRColorGradingComponentConfig::m_smhMidtonesColor, "SMH Midtones Color", "SMH Midtones Color") + ->DataElement(AZ::Edit::UIHandlers::Color, &HDRColorGradingComponentConfig::m_smhHighlightsColor, "SMH Highlights Color", "SMH Highlights Color") + + ->ClassElement(AZ::Edit::ClassElements::Group, "Final Adjustment") + ->Attribute(AZ::Edit::Attributes::AutoExpand, true) + ->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_colorGradingHueShift, "Hue Shift", "Hue Shift Value") + ->Attribute(Edit::Attributes::Min, 0.0f) + ->Attribute(Edit::Attributes::Max, 1.0f) + ->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_colorGradingPostSaturation, "Post Saturation", "Post Saturation Value") + ->Attribute(Edit::Attributes::Min, -100.0f) + ->Attribute(Edit::Attributes::Max, 100.0f) + ; + } + } + } + + EditorHDRColorGradingComponent::EditorHDRColorGradingComponent(const HDRColorGradingComponentConfig& config) + : BaseClass(config) + { + } + + u32 EditorHDRColorGradingComponent::OnConfigurationChanged() + { + m_controller.OnConfigChanged(); + return Edit::PropertyRefreshLevels::AttributesAndValues; + } + } // namespace Render +} // namespace AZ diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/EditorHDRColorGradingComponent.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/EditorHDRColorGradingComponent.h new file mode 100644 index 0000000000..8eea568e3a --- /dev/null +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/EditorHDRColorGradingComponent.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include + +namespace AZ +{ + namespace Render + { + class EditorHDRColorGradingComponent final + : public AzToolsFramework::Components:: + EditorComponentAdapter + { + public: + using BaseClass = AzToolsFramework::Components::EditorComponentAdapter; + AZ_EDITOR_COMPONENT(AZ::Render::EditorHDRColorGradingComponent, "{C1FAB0B1-5847-4533-B08E-7314AC807B8E}", BaseClass); + + static void Reflect(AZ::ReflectContext* context); + + EditorHDRColorGradingComponent() = default; + EditorHDRColorGradingComponent(const HDRColorGradingComponentConfig& config); + + //! EditorRenderComponentAdapter overrides... + AZ::u32 OnConfigurationChanged() override; + }; + } // namespace Render +} // namespace AZ diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/HDRColorGradingComponent.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/HDRColorGradingComponent.cpp new file mode 100644 index 0000000000..d91a91a09f --- /dev/null +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/HDRColorGradingComponent.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include + +namespace AZ +{ + namespace Render + { + HDRColorGradingComponent::HDRColorGradingComponent(const HDRColorGradingComponentConfig& config) + : BaseClass(config) + { + } + + void HDRColorGradingComponent::Reflect(AZ::ReflectContext* context) + { + BaseClass::Reflect(context); + + if (auto serializeContext = azrtti_cast(context)) + { + serializeContext->Class(); + } + } + } // namespace Render +} // namespace AZ diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/HDRColorGradingComponent.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/HDRColorGradingComponent.h new file mode 100644 index 0000000000..6c4bd1418f --- /dev/null +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/HDRColorGradingComponent.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include +#include +#include + +namespace AZ +{ + namespace Render + { + class HDRColorGradingComponent final + : public AzFramework::Components::ComponentAdapter + { + public: + using BaseClass = AzFramework::Components::ComponentAdapter; + AZ_COMPONENT(AZ::Render::HDRColorGradingComponent, "{51968E0F-4DF0-4851-8405-388CBB15B573}", BaseClass); + + HDRColorGradingComponent() = default; + HDRColorGradingComponent(const HDRColorGradingComponentConfig& config); + + static void Reflect(AZ::ReflectContext* context); + }; + } // namespace Render +} // namespace AZ diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/HDRColorGradingComponentConfig.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/HDRColorGradingComponentConfig.cpp new file mode 100644 index 0000000000..b63fa647a0 --- /dev/null +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/HDRColorGradingComponentConfig.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include +#include + +namespace AZ +{ + namespace Render + { + void HDRColorGradingComponentConfig::Reflect(ReflectContext* context) + { + if (auto serializeContext = azrtti_cast(context)) + { + serializeContext->Class()->Version(0) + + // Auto-gen serialize context code... +#define SERIALIZE_CLASS HDRColorGradingComponentConfig +#include +#include +#include +#undef SERIALIZE_CLASS + ; + } + } + + void HDRColorGradingComponentConfig::CopySettingsTo (HDRColorGradingSettingsInterface* settings) + { + if (!settings) + { + return; + } + +#define COPY_TARGET settings +#include +#include +#include +#undef COPY_TARGET + } + } // namespace Render +} // namespace AZ diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/HDRColorGradingComponentController.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/HDRColorGradingComponentController.cpp new file mode 100644 index 0000000000..c0f70ab145 --- /dev/null +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/HDRColorGradingComponentController.cpp @@ -0,0 +1,146 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include + +#include + +#include + +namespace AZ +{ + namespace Render + { + void HDRColorGradingComponentController::Reflect(ReflectContext* context) + { + HDRColorGradingComponentConfig::Reflect(context); + + if (auto* serializeContext = azrtti_cast(context)) + { + serializeContext->Class() + ->Version(0) + ->Field("Configuration", &HDRColorGradingComponentController::m_configuration); + } + + if (auto* behaviorContext = azrtti_cast(context)) + { + behaviorContext->EBus("HDRColorGradingRequestBus") + ->Attribute(AZ::Script::Attributes::Module, "render") + ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) + + // Auto-gen behavior context... +#define PARAM_EVENT_BUS HDRColorGradingRequestBus::Events +#include +#include +#include +#undef PARAM_EVENT_BUS + + ; + } + } + + void HDRColorGradingComponentController::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) + { + provided.push_back(AZ_CRC_CE("HDRColorGradingService")); + } + + void HDRColorGradingComponentController::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) + { + incompatible.push_back(AZ_CRC_CE("HDRColorGradingService")); + } + + void HDRColorGradingComponentController::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) + { + required.push_back(AZ_CRC_CE("PostFXLayerService")); + } + + HDRColorGradingComponentController::HDRColorGradingComponentController(const HDRColorGradingComponentConfig& config) + : m_configuration(config) + { + } + + void HDRColorGradingComponentController::Activate(EntityId entityId) + { + m_entityId = entityId; + + PostProcessFeatureProcessorInterface* fp = + RPI::Scene::GetFeatureProcessorForEntity(m_entityId); + if (fp) + { + m_postProcessInterface = fp->GetOrCreateSettingsInterface(m_entityId); + if (m_postProcessInterface) + { + m_settingsInterface = m_postProcessInterface->GetOrCreateHDRColorGradingSettingsInterface(); + OnConfigChanged(); + } + } + HDRColorGradingRequestBus::Handler::BusConnect(m_entityId); + } + + void HDRColorGradingComponentController::Deactivate() + { + HDRColorGradingRequestBus::Handler::BusDisconnect(m_entityId); + + if (m_postProcessInterface) + { + m_postProcessInterface->RemoveHDRColorGradingSettingsInterface(); + } + + m_postProcessInterface = nullptr; + m_settingsInterface = nullptr; + m_entityId.SetInvalid(); + } + + void HDRColorGradingComponentController::SetConfiguration(const HDRColorGradingComponentConfig& config) + { + m_configuration = config; + OnConfigChanged(); + } + + const HDRColorGradingComponentConfig& HDRColorGradingComponentController::GetConfiguration() const + { + return m_configuration; + } + + void HDRColorGradingComponentController::OnConfigChanged() + { + if (m_settingsInterface) + { + m_configuration.CopySettingsTo(m_settingsInterface); + m_settingsInterface->OnConfigChanged(); + } + } + + // Auto-gen getter/setter function definitions... + // The setter functions will set the values on the Atom settings class, then get the value back + // from the settings class to set the local configuration. This is in case the settings class + // applies some custom logic that results in the set value being different from the input +#define AZ_GFX_COMMON_PARAM(ValueType, Name, MemberName, DefaultValue) \ + ValueType HDRColorGradingComponentController::Get##Name() const \ + { \ + return m_configuration.MemberName; \ + } \ + void HDRColorGradingComponentController::Set##Name(ValueType val) \ + { \ + if (m_settingsInterface) \ + { \ + m_settingsInterface->Set##Name(val); \ + m_settingsInterface->OnConfigChanged(); \ + m_configuration.MemberName = m_settingsInterface->Get##Name(); \ + } \ + else \ + { \ + m_configuration.MemberName = val; \ + } \ + } + +#include +#include +#include + } // namespace Render +} // namespace AZ diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/HDRColorGradingComponentController.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/HDRColorGradingComponentController.h new file mode 100644 index 0000000000..d5743dfbf6 --- /dev/null +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/HDRColorGradingComponentController.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include +#include + +#include +#include +#include + +namespace AZ +{ + namespace Render + { + class HDRColorGradingComponentController final + : public HDRColorGradingRequestBus::Handler + { + public: + friend class EditorHDRColorGradingComponent; + + AZ_TYPE_INFO(AZ::Render::HDRColorGradingComponentController, "{CA1D635C-64E9-42C7-A8E0-36C6B825B15D}"); + static void Reflect(AZ::ReflectContext* context); + static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); + static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); + static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required); + + HDRColorGradingComponentController() = default; + HDRColorGradingComponentController(const HDRColorGradingComponentConfig& config); + + void Activate(EntityId entityId); + void Deactivate(); + void SetConfiguration(const HDRColorGradingComponentConfig& config); + const HDRColorGradingComponentConfig& GetConfiguration() const; + + // Auto-gen function override declarations (functions definitions in .cpp)... +#include +#include +#include + + private: + AZ_DISABLE_COPY(HDRColorGradingComponentController); + + void OnConfigChanged(); + + PostProcessSettingsInterface* m_postProcessInterface = nullptr; + HDRColorGradingSettingsInterface* m_settingsInterface = nullptr; + HDRColorGradingComponentConfig m_configuration; + EntityId m_entityId; + }; + } // namespace Render +} // namespace AZ diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/atomlyintegration_commonfeatures_editor_files.cmake b/Gems/AtomLyIntegration/CommonFeatures/Code/atomlyintegration_commonfeatures_editor_files.cmake index 099cb378f5..174eb30b31 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/atomlyintegration_commonfeatures_editor_files.cmake +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/atomlyintegration_commonfeatures_editor_files.cmake @@ -63,6 +63,8 @@ set(FILES Source/PostProcess/EditorPostFxLayerComponent.h Source/PostProcess/Bloom/EditorBloomComponent.cpp Source/PostProcess/Bloom/EditorBloomComponent.h + Source/PostProcess/ColorGrading/EditorHDRColorGradingComponent.cpp + Source/PostProcess/ColorGrading/EditorHDRColorGradingComponent.h Source/PostProcess/DepthOfField/EditorDepthOfFieldComponent.cpp Source/PostProcess/DepthOfField/EditorDepthOfFieldComponent.h Source/PostProcess/DisplayMapper/EditorDisplayMapperComponent.cpp diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/atomlyintegration_commonfeatures_files.cmake b/Gems/AtomLyIntegration/CommonFeatures/Code/atomlyintegration_commonfeatures_files.cmake index e353795d04..63f5aedf33 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/atomlyintegration_commonfeatures_files.cmake +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/atomlyintegration_commonfeatures_files.cmake @@ -83,6 +83,11 @@ set(FILES Source/PostProcess/Bloom/BloomComponentConfig.cpp Source/PostProcess/Bloom/BloomComponentController.cpp Source/PostProcess/Bloom/BloomComponentController.h + Source/PostProcess/ColorGrading/HDRColorGradingComponent.cpp + Source/PostProcess/ColorGrading/HDRColorGradingComponent.h + Source/PostProcess/ColorGrading/HDRColorGradingComponentConfig.cpp + Source/PostProcess/ColorGrading/HDRColorGradingComponentController.cpp + Source/PostProcess/ColorGrading/HDRColorGradingComponentController.h Source/PostProcess/DepthOfField/DepthOfFieldComponent.cpp Source/PostProcess/DepthOfField/DepthOfFieldComponent.h Source/PostProcess/DepthOfField/DepthOfFieldComponentConfig.cpp diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/atomlyintegration_commonfeatures_public_files.cmake b/Gems/AtomLyIntegration/CommonFeatures/Code/atomlyintegration_commonfeatures_public_files.cmake index 68bbe52415..133856c900 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/atomlyintegration_commonfeatures_public_files.cmake +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/atomlyintegration_commonfeatures_public_files.cmake @@ -39,6 +39,8 @@ set(FILES Include/AtomLyIntegration/CommonFeatures/PostProcess/ExposureControl/ExposureControlBus.h Include/AtomLyIntegration/CommonFeatures/PostProcess/ExposureControl/ExposureControlComponentConfig.h Include/AtomLyIntegration/CommonFeatures/PostProcess/ExposureControl/ExposureControlComponentConstants.h + Include/AtomLyIntegration/CommonFeatures/PostProcess/ColorGrading/HDRColorGradingBus.h + Include/AtomLyIntegration/CommonFeatures/PostProcess/ColorGrading/HDRColorGradingComponentConfig.h Include/AtomLyIntegration/CommonFeatures/PostProcess/Ssao/SsaoBus.h Include/AtomLyIntegration/CommonFeatures/PostProcess/Ssao/SsaoComponentConfiguration.h Include/AtomLyIntegration/CommonFeatures/PostProcess/LookModification/LookModificationBus.h From e5cc029c76cb76f0f07facc5ae3bff840cda3a07 Mon Sep 17 00:00:00 2001 From: dmcdiar Date: Tue, 21 Sep 2021 14:40:26 -0700 Subject: [PATCH 6/9] Converted ReflectionProbe Srg indices to ShaderInputNameIndex Signed-off-by: dmcdiar --- .../Source/ReflectionProbe/ReflectionProbe.h | 14 +++--- .../ReflectionProbeFeatureProcessor.cpp | 47 ------------------- 2 files changed, 7 insertions(+), 54 deletions(-) diff --git a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.h b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.h index 4f6a3337be..5b56b70ec8 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.h +++ b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.h @@ -55,13 +55,13 @@ namespace AZ RHI::DrawListTag m_renderOuterDrawListTag; RHI::DrawListTag m_renderInnerDrawListTag; - RHI::ShaderInputConstantIndex m_modelToWorldStencilConstantIndex; - RHI::ShaderInputConstantIndex m_modelToWorldRenderConstantIndex; - RHI::ShaderInputConstantIndex m_modelToWorldInverseRenderConstantIndex; - RHI::ShaderInputConstantIndex m_outerObbHalfLengthsRenderConstantIndex; - RHI::ShaderInputConstantIndex m_innerObbHalfLengthsRenderConstantIndex; - RHI::ShaderInputConstantIndex m_useParallaxCorrectionRenderConstantIndex; - RHI::ShaderInputImageIndex m_reflectionCubeMapRenderImageIndex; + RHI::ShaderInputNameIndex m_modelToWorldStencilConstantIndex = "m_modelToWorld"; + RHI::ShaderInputNameIndex m_modelToWorldRenderConstantIndex = "m_modelToWorld"; + RHI::ShaderInputNameIndex m_modelToWorldInverseRenderConstantIndex = "m_modelToWorldInverse"; + RHI::ShaderInputNameIndex m_outerObbHalfLengthsRenderConstantIndex = "m_outerObbHalfLengths"; + RHI::ShaderInputNameIndex m_innerObbHalfLengthsRenderConstantIndex = "m_innerObbHalfLengths"; + RHI::ShaderInputNameIndex m_useParallaxCorrectionRenderConstantIndex = "m_useParallaxCorrection"; + RHI::ShaderInputNameIndex m_reflectionCubeMapRenderImageIndex = "m_reflectionCubeMap"; }; // ReflectionProbe manages all aspects of a single probe, including rendering, visualization, and cubemap generation diff --git a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbeFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbeFeatureProcessor.cpp index e47a132481..9fecbc19fc 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbeFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbeFeatureProcessor.cpp @@ -77,53 +77,6 @@ namespace AZ m_reflectionRenderData.m_renderInnerSrgLayout, m_reflectionRenderData.m_renderInnerDrawListTag); - // create ShaderResourceGroups here so we can get the layout and cache the indices - // Note: the SRGs are not needed beyond this method since each probe creates its own SRGs, we are just interested in the indices - - // cache probe stencil shader indices - Data::Instance stencilSrg = RPI::ShaderResourceGroup::Create( - m_reflectionRenderData.m_stencilShader->GetAsset(), - m_reflectionRenderData.m_stencilShader->GetSupervariantIndex(), - m_reflectionRenderData.m_stencilSrgLayout->GetName()); - AZ_Error("ReflectionProbeFeatureProcessor", stencilSrg.get(), "Failed to create stencil back face shader resource group"); - - const RHI::ShaderResourceGroupLayout* stencilSrgLayout = stencilSrg->GetLayout(); - Name modelToWorldConstantName = Name("m_modelToWorld"); - m_reflectionRenderData.m_modelToWorldStencilConstantIndex = stencilSrgLayout->FindShaderInputConstantIndex(modelToWorldConstantName); - AZ_Error("ReflectionProbeFeatureProcessor", m_reflectionRenderData.m_modelToWorldStencilConstantIndex.IsValid(), "Failed to find stencil shader input constant [%s]", modelToWorldConstantName.GetCStr()); - - // cache probe render shader indices - // Note: the outer and inner render shaders use the same Srg - Data::Instance renderReflectionSrg = RPI::ShaderResourceGroup::Create( - m_reflectionRenderData.m_renderOuterShader->GetAsset(), - m_reflectionRenderData.m_renderOuterShader->GetSupervariantIndex(), - m_reflectionRenderData.m_renderOuterSrgLayout->GetName()); - AZ_Error("ReflectionProbeFeatureProcessor", renderReflectionSrg.get(), "Failed to create render reflection shader resource group"); - - const RHI::ShaderResourceGroupLayout* renderReflectionSrgLayout = renderReflectionSrg->GetLayout(); - m_reflectionRenderData.m_modelToWorldRenderConstantIndex = renderReflectionSrgLayout->FindShaderInputConstantIndex(modelToWorldConstantName); - AZ_Error("ReflectionProbeFeatureProcessor", m_reflectionRenderData.m_modelToWorldRenderConstantIndex.IsValid(), "Failed to find render shader input constant [%s]", modelToWorldConstantName.GetCStr()); - - Name modelToWorldInverseConstantName = Name("m_modelToWorldInverse"); - m_reflectionRenderData.m_modelToWorldInverseRenderConstantIndex = renderReflectionSrgLayout->FindShaderInputConstantIndex(modelToWorldInverseConstantName); - AZ_Error("ReflectionProbeFeatureProcessor", m_reflectionRenderData.m_modelToWorldRenderConstantIndex.IsValid(), "Failed to find render shader input constant [%s]", modelToWorldInverseConstantName.GetCStr()); - - Name outerObbHalfLengthsConstantName = Name("m_outerObbHalfLengths"); - m_reflectionRenderData.m_outerObbHalfLengthsRenderConstantIndex = renderReflectionSrgLayout->FindShaderInputConstantIndex(outerObbHalfLengthsConstantName); - AZ_Error("ReflectionProbeFeatureProcessor", m_reflectionRenderData.m_outerObbHalfLengthsRenderConstantIndex.IsValid(), "Failed to find render shader input constant [%s]", outerObbHalfLengthsConstantName.GetCStr()); - - Name innerObbHalfLengthsConstantName = Name("m_innerObbHalfLengths"); - m_reflectionRenderData.m_innerObbHalfLengthsRenderConstantIndex = renderReflectionSrgLayout->FindShaderInputConstantIndex(innerObbHalfLengthsConstantName); - AZ_Error("ReflectionProbeFeatureProcessor", m_reflectionRenderData.m_innerObbHalfLengthsRenderConstantIndex.IsValid(), "Failed to find render shader input constant [%s]", innerObbHalfLengthsConstantName.GetCStr()); - - Name useParallaxCorrectionConstantName = Name("m_useParallaxCorrection"); - m_reflectionRenderData.m_useParallaxCorrectionRenderConstantIndex = renderReflectionSrgLayout->FindShaderInputConstantIndex(useParallaxCorrectionConstantName); - AZ_Error("ReflectionProbeFeatureProcessor", m_reflectionRenderData.m_useParallaxCorrectionRenderConstantIndex.IsValid(), "Failed to find render shader input constant [%s]", useParallaxCorrectionConstantName.GetCStr()); - - Name reflectionCubeMapImageName = Name("m_reflectionCubeMap"); - m_reflectionRenderData.m_reflectionCubeMapRenderImageIndex = renderReflectionSrgLayout->FindShaderInputImageIndex(reflectionCubeMapImageName); - AZ_Error("ReflectionProbeFeatureProcessor", m_reflectionRenderData.m_reflectionCubeMapRenderImageIndex.IsValid(), "Failed to find render shader input image [%s]", reflectionCubeMapImageName.GetCStr()); - EnableSceneNotification(); } From 50fabb1bf7b3b5c2609890144d7691edd1c4a533 Mon Sep 17 00:00:00 2001 From: mrieggeramzn <61609885+mrieggeramzn@users.noreply.github.com> Date: Tue, 21 Sep 2021 15:06:55 -0700 Subject: [PATCH 7/9] Atom/mriegger/fixupname (#4187) * Removing atom from the Decal (atom) name * Decal component can take advantage of non-uniform scale option * Using the base class nonuniform scale property rather than firing an event * removing pragma optimize off * Python tests need the updated name Signed-off-by: mrieggeramzn --- .../Gem/PythonTests/Atom/TestSuite_Main.py | 28 +++++++++---------- ...ydra_AtomEditorComponents_AddedToEntity.py | 2 +- .../hydra_AtomEditorComponents_DecalAdded.py | 2 +- .../Source/Decals/EditorDecalComponent.cpp | 24 +++++++++++----- .../Code/Source/Decals/EditorDecalComponent.h | 6 +++- 5 files changed, 38 insertions(+), 24 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py index 0bc66f2614..4c5716d365 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py @@ -38,24 +38,24 @@ class TestAtomEditorComponentsMain(object): 7. Exposure Control 8. Directional Light 9. DepthOfField - 10. Decal (Atom) + 10. Decal """ cfg_args = [level] expected_lines = [ - # Decal (Atom) Component - "Decal (Atom) Entity successfully created", - "Decal (Atom)_test: Component added to the entity: True", - "Decal (Atom)_test: Component removed after UNDO: True", - "Decal (Atom)_test: Component added after REDO: True", - "Decal (Atom)_test: Entered game mode: True", - "Decal (Atom)_test: Exit game mode: True", - "Decal (Atom) Controller|Configuration|Material: SUCCESS", - "Decal (Atom)_test: Entity is hidden: True", - "Decal (Atom)_test: Entity is shown: True", - "Decal (Atom)_test: Entity deleted: True", - "Decal (Atom)_test: UNDO entity deletion works: True", - "Decal (Atom)_test: REDO entity deletion works: True", + # Decal Component + "Decal Entity successfully created", + "Decal_test: Component added to the entity: True", + "Decal_test: Component removed after UNDO: True", + "Decal_test: Component added after REDO: True", + "Decal_test: Entered game mode: True", + "Decal_test: Exit game mode: True", + "Decal Controller|Configuration|Material: SUCCESS", + "Decal_test: Entity is hidden: True", + "Decal_test: Entity is shown: True", + "Decal_test: Entity deleted: True", + "Decal_test: UNDO entity deletion works: True", + "Decal_test: REDO entity deletion works: True", # DepthOfField Component "DepthOfField Entity successfully created", "DepthOfField_test: Component added to the entity: True", diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_AddedToEntity.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_AddedToEntity.py index a2e950e1dc..602e7564b3 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_AddedToEntity.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_AddedToEntity.py @@ -184,7 +184,7 @@ def run(): material_asset = asset.AssetCatalogRequestBus( bus.Broadcast, "GetAssetIdByPath", material_asset_path, math.Uuid(), False) ComponentTests( - "Decal (Atom)", lambda entity_obj: verify_set_property( + "Decal", lambda entity_obj: verify_set_property( entity_obj, "Controller|Configuration|Material", material_asset)) # Directional Light Component diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DecalAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DecalAdded.py index d68e1f5844..fa02b75fe2 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DecalAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DecalAdded.py @@ -73,7 +73,7 @@ def AtomEditorComponents_Decal_AddedToEntity(): # Test steps begin. # 1. Create a Decal entity with no components. - decal_name = "Decal (Atom)" + decal_name = "Decal" decal_entity = EditorEntity.create_editor_entity_at(math.Vector3(512.0, 512.0, 34.0), decal_name) Report.critical_result(Tests.decal_creation, decal_entity.exists()) diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Decals/EditorDecalComponent.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Decals/EditorDecalComponent.cpp index c10e7e2e30..c5d61dd54a 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Decals/EditorDecalComponent.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Decals/EditorDecalComponent.cpp @@ -32,7 +32,7 @@ namespace AZ if (AZ::EditContext* editContext = serializeContext->GetEditContext()) { editContext->Class( - "Decal (Atom)", "The Decal component allows an entity to project a texture or material onto a mesh") + "Decal", "The Decal component allows an entity to project a texture or material onto a mesh") ->ClassElement(AZ::Edit::ClassElements::EditorData, "") ->Attribute(AZ::Edit::Attributes::Category, "Atom") ->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/Decal.svg") @@ -97,13 +97,25 @@ namespace AZ BaseClass::Deactivate(); } - AZ::Transform EditorDecalComponent::GetTransform() const + AZ::Transform EditorDecalComponent::GetWorldTransform() const { AZ::Transform transform = AZ::Transform::CreateIdentity(); AZ::TransformBus::EventResult(transform, GetEntityId(), &AZ::TransformBus::Events::GetWorldTM); return transform; } + AZ::Matrix3x4 EditorDecalComponent::GetWorldTransformWithNonUniformScale() const + { + const AZ::Transform worldTransform = GetWorldTransform(); + const AZ::Matrix3x3 rotationMat = AZ::Matrix3x3::CreateFromQuaternion(worldTransform.GetRotation()); + + const AZ::Vector3 nonUniformScale = m_controller.m_cachedNonUniformScale * worldTransform.GetUniformScale(); + const AZ::Matrix3x3 nonUniformScaleMat = AZ::Matrix3x3::CreateScale(nonUniformScale); + const AZ::Matrix3x3 rotationAndScale = rotationMat * nonUniformScaleMat; + + return AZ::Matrix3x4::CreateFromMatrix3x3AndTranslation(rotationAndScale, worldTransform.GetTranslation()); + } + void EditorDecalComponent::DisplayEntityViewport( [[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) @@ -113,11 +125,9 @@ namespace AZ return; } - AZ::Transform transform = GetTransform(); - - debugDisplay.SetColor(AZ::Colors::Red); - debugDisplay.PushMatrix(transform); + const AZ::Matrix3x4 transform = GetWorldTransformWithNonUniformScale(); + debugDisplay.PushPremultipliedMatrix(transform); debugDisplay.DrawWireBox(-AZ::Vector3::CreateOne(), AZ::Vector3::CreateOne()); AZ::Vector3 x1 = AZ::Vector3(-1, 0, 1); @@ -136,7 +146,7 @@ namespace AZ // Two diagonal edges debugDisplay.DrawLine(p0, p2); debugDisplay.DrawLine(p1, p3); - debugDisplay.PopMatrix(); + debugDisplay.PopPremultipliedMatrix(); } AZ::Aabb EditorDecalComponent::GetEditorSelectionBoundsViewport([[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo) diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Decals/EditorDecalComponent.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Decals/EditorDecalComponent.h index f0748dfef5..1ca88d23fc 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Decals/EditorDecalComponent.h +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Decals/EditorDecalComponent.h @@ -56,7 +56,11 @@ namespace AZ private: - AZ::Transform GetTransform() const; + // Returns the component transform which includes uniform-scale, rotation and translation + AZ::Transform GetWorldTransform() const; + + // Returns the full transform, including both the uniform scale and non-uniform scale along with rotation and translation + AZ::Matrix3x4 GetWorldTransformWithNonUniformScale() const; //! EditorRenderComponentAdapter overrides ... u32 OnConfigurationChanged() override; From 39a4e054925c2dc26c71319f5aa0abc6a6160636 Mon Sep 17 00:00:00 2001 From: Mike Chang <62353586+amzn-changml@users.noreply.github.com> Date: Tue, 21 Sep 2021 15:24:14 -0700 Subject: [PATCH 8/9] Change installer domain to o3debinaries.org (#4244) * Change installer domain to o3debinaries.org * Removed 3p license parameter Signed-off-by: Mike Chang --- scripts/build/Platform/Windows/build_config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build/Platform/Windows/build_config.json b/scripts/build/Platform/Windows/build_config.json index 02bd01038a..3848e6f980 100644 --- a/scripts/build/Platform/Windows/build_config.json +++ b/scripts/build/Platform/Windows/build_config.json @@ -360,7 +360,7 @@ "CONFIGURATION": "profile", "OUTPUT_DIRECTORY": "build\\windows_vs2019", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE -DLY_DISABLE_TEST_MODULES=TRUE -DLY_VERSION_ENGINE_NAME=o3de-sdk -DLY_INSTALLER_WIX_ROOT=\"!WIX! \"", - "EXTRA_CMAKE_OPTIONS": "-DLY_INSTALLER_AUTO_GEN_TAG=ON -DLY_INSTALLER_DOWNLOAD_URL=https://dkb1uj4hs9ikv.cloudfront.net -DLY_INSTALLER_LICENSE_URL=https://www.o3debinaries.org/license -DLY_INSTALLER_3RD_PARTY_LICENSE_URL=https://dkb1uj4hs9ikv.cloudfront.net/SPDX-Licenses.txt", + "EXTRA_CMAKE_OPTIONS": "-DLY_INSTALLER_AUTO_GEN_TAG=ON -DLY_INSTALLER_DOWNLOAD_URL=https://www.o3debinaries.org -DLY_INSTALLER_LICENSE_URL=https://www.o3debinaries.org/license", "CPACK_BUCKET": "spectra-prism-staging-us-west-2", "CMAKE_LY_PROJECTS": "", "CMAKE_TARGET": "ALL_BUILD", From df42377fc6933a04dca38db3160af7e78e8ebb61 Mon Sep 17 00:00:00 2001 From: dmcdiar Date: Tue, 21 Sep 2021 17:10:32 -0700 Subject: [PATCH 9/9] Minor changes to forward pass IBL specular Signed-off-by: dmcdiar --- .../Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ibl.azsli | 2 +- .../Feature/Common/Code/Source/Mesh/MeshFeatureProcessor.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ibl.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ibl.azsli index b1cfb47be6..d33a307dfe 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ibl.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ibl.azsli @@ -60,7 +60,7 @@ float3 GetIblSpecular( // compute blend amount based on world position in the reflection probe volume float blendAmount = ComputeLerpBetweenInnerOuterOBBs( - ObjectSrg::m_reflectionProbeData.m_modelToWorldInverse, + ObjectSrg::GetReflectionProbeWorldMatrixInverse(), ObjectSrg::m_reflectionProbeData.m_innerObbHalfLengths, ObjectSrg::m_reflectionProbeData.m_outerObbHalfLengths, position); diff --git a/Gems/Atom/Feature/Common/Code/Source/Mesh/MeshFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/Mesh/MeshFeatureProcessor.cpp index ba3bdc0bb4..bd0d12106b 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Mesh/MeshFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/Mesh/MeshFeatureProcessor.cpp @@ -1144,7 +1144,7 @@ namespace AZ if (!reflectionProbes.empty() && reflectionProbes[0]) { m_shaderResourceGroup->SetConstant(modelToWorldConstantIndex, reflectionProbes[0]->GetTransform()); - m_shaderResourceGroup->SetConstant(modelToWorldInverseConstantIndex, reflectionProbes[0]->GetTransform().GetInverse()); + m_shaderResourceGroup->SetConstant(modelToWorldInverseConstantIndex, Matrix3x4::CreateFromTransform(reflectionProbes[0]->GetTransform()).GetInverseFull()); m_shaderResourceGroup->SetConstant(outerObbHalfLengthsConstantIndex, reflectionProbes[0]->GetOuterObbWs().GetHalfLengths()); m_shaderResourceGroup->SetConstant(innerObbHalfLengthsConstantIndex, reflectionProbes[0]->GetInnerObbWs().GetHalfLengths()); m_shaderResourceGroup->SetConstant(useReflectionProbeConstantIndex, true);