From b3d7de1e78c447d44f3cb3702a1b084e6c319aaf Mon Sep 17 00:00:00 2001 From: mrieggeramzn Date: Fri, 1 Oct 2021 13:03:52 -0700 Subject: [PATCH] Improvements. You can now call SetDecalMaterial() with any permutation and it works as expected Signed-off-by: mrieggeramzn --- .../ShaderLib/Atom/Features/PBR/Decals.azsli | 2 + .../DecalTextureArrayFeatureProcessor.cpp | 45 ++++++++++++++----- .../DecalTextureArrayFeatureProcessor.h | 1 + .../Decals/DecalComponentController.cpp | 2 +- .../Source/Decals/EditorDecalComponent.cpp | 2 +- 5 files changed, 38 insertions(+), 14 deletions(-) diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Decals.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Decals.azsli index 5e7088617b..f9ead72ce4 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Decals.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Decals.azsli @@ -70,6 +70,8 @@ void ApplyDecal(uint currDecalIndex, inout Surface surface) float4 baseMap = 0; float2 normalMap = 0; + // Each texture array handles a size permutation. + // e.g. it could be that tex array 0 handles 256x256 and tex array 1 handles 512x64, etc. switch(textureArrayIndex) { case 0: diff --git a/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.cpp index e5bf0bd9fa..0323282f5c 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.cpp @@ -301,23 +301,44 @@ namespace AZ return; } - if (material.IsValid()) + if (GetMaterialUsedByDecal(handle) == material) + return; + + const auto decalIndex = handle.GetIndex(); + + const bool isValidMaterialBeingUsedCurrently = m_decalData.GetData(decalIndex).m_textureArrayIndex != DecalData::UnusedIndex; + if (isValidMaterialBeingUsedCurrently) { - AZ_Assert(m_decalData.GetData(handle.GetIndex()).m_textureArrayIndex == DecalData::UnusedIndex, "Setting Material on a decal more than once is not currently supported."); + RemoveMaterialFromDecal(decalIndex); + } - const auto iter = m_materialToTextureArrayLookupTable.find(material); - if (iter != m_materialToTextureArrayLookupTable.end()) - { - // This material is already loaded and registered with this feature processor - iter->second.m_useCount++; - SetDecalTextureLocation(handle, iter->second.m_location); - return; - } + if (!material.IsValid()) + return; - // Material not loaded so queue it up for loading. - QueueMaterialLoadForDecal(material, handle); + const auto iter = m_materialToTextureArrayLookupTable.find(material); + if (iter != m_materialToTextureArrayLookupTable.end()) + { + // This material is already loaded and registered with this feature processor + iter->second.m_useCount++; + SetDecalTextureLocation(handle, iter->second.m_location); return; } + + // Material not loaded so queue it up for loading. + QueueMaterialLoadForDecal(material, handle); + } + + void DecalTextureArrayFeatureProcessor::RemoveMaterialFromDecal(const uint16_t decalIndex) + { + DecalLocation decalLocation; + decalLocation.textureArrayIndex = m_decalData.GetData(decalIndex).m_textureArrayIndex; + decalLocation.textureIndex = m_decalData.GetData(decalIndex).m_textureIndex; + RemoveDecalFromTextureArrays(decalLocation); + + m_decalData.GetData(decalIndex).m_textureArrayIndex = DecalData::UnusedIndex; + m_decalData.GetData(decalIndex).m_textureIndex = DecalData::UnusedIndex; + + m_deviceBufferNeedsUpdate = true; } void DecalTextureArrayFeatureProcessor::CacheShaderIndices() diff --git a/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.h index 13a6682629..fd535bbe64 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.h @@ -114,6 +114,7 @@ namespace AZ AZStd::optional AddMaterialToTextureArrays(const AZ::RPI::MaterialAsset* materialAsset); int FindTextureArrayWithSize(const RHI::Size& size) const; + void RemoveMaterialFromDecal(const uint16_t decalIndex); void SetDecalTextureLocation(const DecalHandle& handle, const DecalLocation location); void QueueMaterialLoadForDecal(const AZ::Data::AssetId material, const DecalHandle handle); bool RemoveDecalFromTextureArrays(const DecalLocation decalLocation); diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Decals/DecalComponentController.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Decals/DecalComponentController.cpp index 5d16164d92..dd8266c1ca 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Decals/DecalComponentController.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Decals/DecalComponentController.cpp @@ -230,7 +230,7 @@ namespace AZ { DecalNotificationBus::Event(m_entityId, &DecalNotifications::OnMaterialChanged, m_configuration.m_materialAsset); - if (m_featureProcessor && m_configuration.m_materialAsset.GetId().IsValid()) + if (m_featureProcessor) { m_featureProcessor->SetDecalMaterial(m_handle, m_configuration.m_materialAsset.GetId()); } diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Decals/EditorDecalComponent.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Decals/EditorDecalComponent.cpp index c5d61dd54a..f8865e8d34 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Decals/EditorDecalComponent.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Decals/EditorDecalComponent.cpp @@ -192,7 +192,7 @@ namespace AZ u32 EditorDecalComponent::OnConfigurationChanged() { - BaseClass::OnConfigurationChanged(); + m_controller.ConfigurationChanged(); return Edit::PropertyRefreshLevels::AttributesAndValues; }