Fixed issue where skin material wouldn't render if applied to a model with several submeshes and those submeshes had different material types applied to them.

Signed-off-by: antonmic <56370189+antonmic@users.noreply.github.com>
This commit is contained in:
antonmic
2021-11-09 19:03:26 -08:00
parent 79f8edce14
commit dadf06edda
6 changed files with 147 additions and 138 deletions
@@ -67,7 +67,7 @@ namespace AZ
m_handleGlobalShaderOptionUpdate.Disconnect();
DisableSceneNotification();
AZ_Warning("MeshFeatureProcessor", m_meshData.size() == 0,
AZ_Warning("MeshFeatureProcessor", m_modelData.size() == 0,
"Deactivaing the MeshFeatureProcessor, but there are still outstanding mesh handles.\n"
);
m_transformService = nullptr;
@@ -81,7 +81,7 @@ namespace AZ
AZStd::concurrency_check_scope scopeCheck(m_meshDataChecker);
const auto iteratorRanges = m_meshData.GetParallelRanges();
const auto iteratorRanges = m_modelData.GetParallelRanges();
AZ::JobCompletion jobCompletion;
for (const auto& iteratorRange : iteratorRanges)
{
@@ -125,11 +125,11 @@ namespace AZ
m_forceRebuildDrawPackets = false;
// CullingSystem::RegisterOrUpdateCullable() is not threadsafe, so need to do those updates in a single thread
for (MeshDataInstance& meshDataInstance : m_meshData)
for (ModelDataInstance& modelDataInstance : m_modelData)
{
if (meshDataInstance.m_model && meshDataInstance.m_cullBoundsNeedsUpdate)
if (modelDataInstance.m_model && modelDataInstance.m_cullBoundsNeedsUpdate)
{
meshDataInstance.UpdateCullBounds(m_transformService);
modelDataInstance.UpdateCullBounds(m_transformService);
}
}
}
@@ -151,14 +151,14 @@ namespace AZ
AZ_PROFILE_SCOPE(AzRender, "MeshFeatureProcessor: AcquireMesh");
// don't need to check the concurrency during emplace() because the StableDynamicArray won't move the other elements during insertion
MeshHandle meshDataHandle = m_meshData.emplace();
MeshHandle meshDataHandle = m_modelData.emplace();
meshDataHandle->m_descriptor = descriptor;
meshDataHandle->m_scene = GetParentScene();
meshDataHandle->m_materialAssignments = materials;
meshDataHandle->m_objectId = m_transformService->ReserveObjectId();
meshDataHandle->m_originalModelAsset = descriptor.m_modelAsset;
meshDataHandle->m_meshLoader = AZStd::make_unique<MeshDataInstance::MeshLoader>(descriptor.m_modelAsset, &*meshDataHandle);
meshDataHandle->m_meshLoader = AZStd::make_unique<ModelDataInstance::MeshLoader>(descriptor.m_modelAsset, &*meshDataHandle);
return meshDataHandle;
}
@@ -183,7 +183,7 @@ namespace AZ
m_transformService->ReleaseObjectId(meshHandle->m_objectId);
AZStd::concurrency_check_scope scopeCheck(m_meshDataChecker);
m_meshData.erase(meshHandle);
m_modelData.erase(meshHandle);
return true;
}
@@ -215,9 +215,10 @@ namespace AZ
return {};
}
Data::Instance<RPI::ShaderResourceGroup> MeshFeatureProcessor::GetObjectSrg(const MeshHandle& meshHandle) const
AZStd::vector<Data::Instance<RPI::ShaderResourceGroup>>& MeshFeatureProcessor::GetObjectSrgs(const MeshHandle& meshHandle) const
{
return meshHandle.IsValid() ? meshHandle->m_shaderResourceGroup : nullptr;
static AZStd::vector<Data::Instance<RPI::ShaderResourceGroup>> staticEmptyList;
return meshHandle.IsValid() ? meshHandle->m_objectSrgList : staticEmptyList;
}
void MeshFeatureProcessor::QueueObjectSrgForCompile(const MeshHandle& meshHandle) const
@@ -274,9 +275,9 @@ namespace AZ
{
if (meshHandle.IsValid())
{
MeshDataInstance& meshData = *meshHandle;
meshData.m_cullBoundsNeedsUpdate = true;
meshData.m_objectSrgNeedsUpdate = true;
ModelDataInstance& modelData = *meshHandle;
modelData.m_cullBoundsNeedsUpdate = true;
modelData.m_objectSrgNeedsUpdate = true;
m_transformService->SetTransformForId(meshHandle->m_objectId, transform, nonUniformScale);
@@ -292,10 +293,10 @@ namespace AZ
{
if (meshHandle.IsValid())
{
MeshDataInstance& meshData = *meshHandle;
meshData.m_aabb = localAabb;
meshData.m_cullBoundsNeedsUpdate = true;
meshData.m_objectSrgNeedsUpdate = true;
ModelDataInstance& modelData = *meshHandle;
modelData.m_aabb = localAabb;
modelData.m_cullBoundsNeedsUpdate = true;
modelData.m_objectSrgNeedsUpdate = true;
}
};
@@ -465,7 +466,7 @@ namespace AZ
void MeshFeatureProcessor::UpdateMeshReflectionProbes()
{
// we need to rebuild the Srg for any meshes that are using the forward pass IBL specular option
for (auto& meshInstance : m_meshData)
for (auto& meshInstance : m_modelData)
{
if (meshInstance.m_descriptor.m_useForwardPassIblSpecular)
{
@@ -474,14 +475,14 @@ namespace AZ
}
}
// MeshDataInstance::MeshLoader...
MeshDataInstance::MeshLoader::MeshLoader(const Data::Asset<RPI::ModelAsset>& modelAsset, MeshDataInstance* parent)
// ModelDataInstance::MeshLoader...
ModelDataInstance::MeshLoader::MeshLoader(const Data::Asset<RPI::ModelAsset>& modelAsset, ModelDataInstance* parent)
: m_modelAsset(modelAsset)
, m_parent(parent)
{
if (!m_modelAsset.GetId().IsValid())
{
AZ_Error("MeshDataInstance::MeshLoader", false, "Invalid model asset Id.");
AZ_Error("ModelDataInstance::MeshLoader", false, "Invalid model asset Id.");
return;
}
@@ -494,19 +495,19 @@ namespace AZ
AzFramework::AssetCatalogEventBus::Handler::BusConnect();
}
MeshDataInstance::MeshLoader::~MeshLoader()
ModelDataInstance::MeshLoader::~MeshLoader()
{
AzFramework::AssetCatalogEventBus::Handler::BusDisconnect();
Data::AssetBus::Handler::BusDisconnect();
}
MeshFeatureProcessorInterface::ModelChangedEvent& MeshDataInstance::MeshLoader::GetModelChangedEvent()
MeshFeatureProcessorInterface::ModelChangedEvent& ModelDataInstance::MeshLoader::GetModelChangedEvent()
{
return m_modelChangedEvent;
}
//! AssetBus::Handler overrides...
void MeshDataInstance::MeshLoader::OnAssetReady(Data::Asset<Data::AssetData> asset)
void ModelDataInstance::MeshLoader::OnAssetReady(Data::Asset<Data::AssetData> asset)
{
Data::Asset<RPI::ModelAsset> modelAsset = asset;
@@ -527,7 +528,7 @@ namespace AZ
}
else
{
AZ_Error("MeshDataInstance", false, "Cannot clone model for '%s'. Cloth simulation results won't be individual per entity.", modelAsset->GetName().GetCStr());
AZ_Error("ModelDataInstance", false, "Cannot clone model for '%s'. Cloth simulation results won't be individual per entity.", modelAsset->GetName().GetCStr());
model = RPI::Model::FindOrCreate(modelAsset);
}
}
@@ -547,29 +548,29 @@ namespace AZ
{
//when running with null renderer, the RPI::Model::FindOrCreate(...) is expected to return nullptr, so suppress this error.
AZ_Error(
"MeshDataInstance::OnAssetReady", RHI::IsNullRenderer(), "Failed to create model instance for '%s'",
"ModelDataInstance::OnAssetReady", RHI::IsNullRenderer(), "Failed to create model instance for '%s'",
asset.GetHint().c_str());
}
}
void MeshDataInstance::MeshLoader::OnModelReloaded(Data::Asset<Data::AssetData> asset)
void ModelDataInstance::MeshLoader::OnModelReloaded(Data::Asset<Data::AssetData> asset)
{
OnAssetReady(asset);
}
void MeshDataInstance::MeshLoader::OnAssetError(Data::Asset<Data::AssetData> asset)
void ModelDataInstance::MeshLoader::OnAssetError(Data::Asset<Data::AssetData> asset)
{
// Note: m_modelAsset and asset represents same asset, but only m_modelAsset contains the file path in its hint from serialization
AZ_Error(
"MeshDataInstance::MeshLoader", false, "Failed to load asset %s. It may be missing, or not be finished processing",
"ModelDataInstance::MeshLoader", false, "Failed to load asset %s. It may be missing, or not be finished processing",
m_modelAsset.GetHint().c_str());
AzFramework::AssetSystemRequestBus::Broadcast(
&AzFramework::AssetSystem::AssetSystemRequests::EscalateAssetByUuid, m_modelAsset.GetId().m_guid);
}
void MeshDataInstance::MeshLoader::OnCatalogAssetChanged(const AZ::Data::AssetId& assetId)
void ModelDataInstance::MeshLoader::OnCatalogAssetChanged(const AZ::Data::AssetId& assetId)
{
if (assetId == m_modelAsset.GetId())
{
@@ -584,7 +585,7 @@ namespace AZ
}
}
void MeshDataInstance::MeshLoader::OnCatalogAssetAdded(const AZ::Data::AssetId& assetId)
void ModelDataInstance::MeshLoader::OnCatalogAssetAdded(const AZ::Data::AssetId& assetId)
{
if (assetId == m_modelAsset.GetId())
{
@@ -599,9 +600,9 @@ namespace AZ
}
}
// MeshDataInstance...
// ModelDataInstance...
void MeshDataInstance::DeInit()
void ModelDataInstance::DeInit()
{
m_scene->GetCullingScene()->UnregisterCullable(m_cullable);
@@ -609,11 +610,11 @@ namespace AZ
m_drawPacketListsByLod.clear();
m_materialAssignments.clear();
m_shaderResourceGroup = {};
m_objectSrgList = {};
m_model = {};
}
void MeshDataInstance::Init(Data::Instance<RPI::Model> model)
void ModelDataInstance::Init(Data::Instance<RPI::Model> model)
{
m_model = model;
const size_t modelLodCount = m_model->GetLodCount();
@@ -623,11 +624,11 @@ namespace AZ
BuildDrawPacketList(modelLodIndex);
}
if (m_shaderResourceGroup)
for(auto& objectSrg : m_objectSrgList)
{
// Set object Id once since it never changes
RHI::ShaderInputNameIndex objectIdIndex = "m_objectId";
m_shaderResourceGroup->SetConstant(objectIdIndex, m_objectId.GetIndex());
objectSrg->SetConstant(objectIdIndex, m_objectId.GetIndex());
objectIdIndex.AssertValid();
}
@@ -643,12 +644,12 @@ namespace AZ
m_objectSrgNeedsUpdate = true;
}
void MeshDataInstance::BuildDrawPacketList(size_t modelLodIndex)
void ModelDataInstance::BuildDrawPacketList(size_t modelLodIndex)
{
RPI::ModelLod& modelLod = *m_model->GetLods()[modelLodIndex];
const size_t meshCount = modelLod.GetMeshes().size();
MeshDataInstance::DrawPacketList& drawPacketListOut = m_drawPacketListsByLod[modelLodIndex];
ModelDataInstance::DrawPacketList& drawPacketListOut = m_drawPacketListsByLod[modelLodIndex];
drawPacketListOut.clear();
drawPacketListOut.reserve(meshCount);
@@ -682,27 +683,32 @@ namespace AZ
continue;
}
if (m_shaderResourceGroup && m_shaderResourceGroup->GetLayout()->GetHash() != objectSrgLayout->GetHash())
Data::Instance<RPI::ShaderResourceGroup> meshObjectSrg;
// See if the object SRG for this mesh is already in our list of object SRGs
for (auto& objectSrgIter : m_objectSrgList)
{
AZ_Warning("MeshFeatureProcessor", false, "All materials on a model must use the same per-object ShaderResourceGroup. Skipping.");
continue;
if (objectSrgIter->GetLayout()->GetHash() == objectSrgLayout->GetHash())
{
meshObjectSrg = objectSrgIter;
}
}
// The first time we find the per-surface SRG asset we create an instance and store it
// in shaderResourceGroupInOut. All of the Model's draw packets will use this same instance.
if (!m_shaderResourceGroup)
// If the object SRG for this mesh was not already in the list, create it and add it to the list
if (!meshObjectSrg)
{
auto& shaderAsset = material->GetAsset()->GetMaterialTypeAsset()->GetShaderAssetForObjectSrg();
m_shaderResourceGroup = RPI::ShaderResourceGroup::Create(shaderAsset, objectSrgLayout->GetName());
if (!m_shaderResourceGroup)
meshObjectSrg = RPI::ShaderResourceGroup::Create(shaderAsset, objectSrgLayout->GetName());
if (!meshObjectSrg)
{
AZ_Warning("MeshFeatureProcessor", false, "Failed to create a new shader resource group, skipping.");
continue;
}
m_objectSrgList.push_back(meshObjectSrg);
}
// setup the mesh draw packet
RPI::MeshDrawPacket drawPacket(modelLod, meshIndex, material, m_shaderResourceGroup, materialAssignment.m_matModUvOverrides);
RPI::MeshDrawPacket drawPacket(modelLod, meshIndex, material, meshObjectSrg, materialAssignment.m_matModUvOverrides);
// set the shader option to select forward pass IBL specular if necessary
if (!drawPacket.SetShaderOption(AZ::Name("o_meshUseForwardPassIBLSpecular"), AZ::RPI::ShaderOptionValue{ m_descriptor.m_useForwardPassIblSpecular }))
@@ -726,7 +732,7 @@ namespace AZ
}
}
void MeshDataInstance::SetRayTracingData()
void ModelDataInstance::SetRayTracingData()
{
if (!m_model)
{
@@ -993,7 +999,7 @@ namespace AZ
rayTracingFeatureProcessor->SetMesh(m_objectId, m_model->GetModelAsset()->GetId(), subMeshes);
}
void MeshDataInstance::RemoveRayTracingData()
void ModelDataInstance::RemoveRayTracingData()
{
// remove from ray tracing
RayTracingFeatureProcessor* rayTracingFeatureProcessor = m_scene->GetFeatureProcessor<RayTracingFeatureProcessor>();
@@ -1003,7 +1009,7 @@ namespace AZ
}
}
void MeshDataInstance::SetSortKey(RHI::DrawItemSortKey sortKey)
void ModelDataInstance::SetSortKey(RHI::DrawItemSortKey sortKey)
{
m_sortKey = sortKey;
for (auto& drawPacketList : m_drawPacketListsByLod)
@@ -1015,24 +1021,24 @@ namespace AZ
}
}
RHI::DrawItemSortKey MeshDataInstance::GetSortKey() const
RHI::DrawItemSortKey ModelDataInstance::GetSortKey() const
{
return m_sortKey;
}
void MeshDataInstance::SetMeshLodConfiguration(RPI::Cullable::LodConfiguration meshLodConfig)
void ModelDataInstance::SetMeshLodConfiguration(RPI::Cullable::LodConfiguration meshLodConfig)
{
m_cullable.m_lodData.m_lodConfiguration = meshLodConfig;
}
RPI::Cullable::LodConfiguration MeshDataInstance::GetMeshLodConfiguration() const
RPI::Cullable::LodConfiguration ModelDataInstance::GetMeshLodConfiguration() const
{
return m_cullable.m_lodData.m_lodConfiguration;
}
void MeshDataInstance::UpdateDrawPackets(bool forceUpdate /*= false*/)
void ModelDataInstance::UpdateDrawPackets(bool forceUpdate /*= false*/)
{
AZ_PROFILE_SCOPE(AzRender, "MeshDataInstance:: UpdateDrawPackets");
AZ_PROFILE_SCOPE(AzRender, "ModelDataInstance:: UpdateDrawPackets");
for (auto& drawPacketList : m_drawPacketListsByLod)
{
for (auto& drawPacket : drawPacketList)
@@ -1045,9 +1051,9 @@ namespace AZ
}
}
void MeshDataInstance::BuildCullable()
void ModelDataInstance::BuildCullable()
{
AZ_PROFILE_SCOPE(AzRender, "MeshDataInstance: BuildCullable");
AZ_PROFILE_SCOPE(AzRender, "ModelDataInstance: BuildCullable");
AZ_Assert(m_cullableNeedsRebuild, "This function only needs to be called if the cullable to be rebuilt");
AZ_Assert(m_model, "The model has not finished loading yet");
@@ -1122,9 +1128,9 @@ namespace AZ
m_cullBoundsNeedsUpdate = true;
}
void MeshDataInstance::UpdateCullBounds(const TransformServiceFeatureProcessor* transformService)
void ModelDataInstance::UpdateCullBounds(const TransformServiceFeatureProcessor* transformService)
{
AZ_PROFILE_SCOPE(AzRender, "MeshDataInstance: UpdateCullBounds");
AZ_PROFILE_SCOPE(AzRender, "ModelDataInstance: UpdateCullBounds");
AZ_Assert(m_cullBoundsNeedsUpdate, "This function only needs to be called if the culling bounds need to be rebuilt");
AZ_Assert(m_model, "The model has not finished loading yet");
@@ -1148,70 +1154,70 @@ namespace AZ
m_cullBoundsNeedsUpdate = false;
}
void MeshDataInstance::UpdateObjectSrg()
void ModelDataInstance::UpdateObjectSrg()
{
if (!m_shaderResourceGroup)
for (auto& objectSrg : m_objectSrgList)
{
return;
ReflectionProbeFeatureProcessor* reflectionProbeFeatureProcessor = m_scene->GetFeatureProcessor<ReflectionProbeFeatureProcessor>();
if (reflectionProbeFeatureProcessor && (m_descriptor.m_useForwardPassIblSpecular || m_hasForwardPassIblSpecularMaterial))
{
// retrieve probe constant indices
AZ::RHI::ShaderInputConstantIndex modelToWorldConstantIndex = objectSrg->FindShaderInputConstantIndex(Name("m_reflectionProbeData.m_modelToWorld"));
AZ_Error("ModelDataInstance", modelToWorldConstantIndex.IsValid(), "Failed to find ReflectionProbe constant index");
AZ::RHI::ShaderInputConstantIndex modelToWorldInverseConstantIndex = objectSrg->FindShaderInputConstantIndex(Name("m_reflectionProbeData.m_modelToWorldInverse"));
AZ_Error("ModelDataInstance", modelToWorldInverseConstantIndex.IsValid(), "Failed to find ReflectionProbe constant index");
AZ::RHI::ShaderInputConstantIndex outerObbHalfLengthsConstantIndex = objectSrg->FindShaderInputConstantIndex(Name("m_reflectionProbeData.m_outerObbHalfLengths"));
AZ_Error("ModelDataInstance", outerObbHalfLengthsConstantIndex.IsValid(), "Failed to find ReflectionProbe constant index");
AZ::RHI::ShaderInputConstantIndex innerObbHalfLengthsConstantIndex = objectSrg->FindShaderInputConstantIndex(Name("m_reflectionProbeData.m_innerObbHalfLengths"));
AZ_Error("ModelDataInstance", innerObbHalfLengthsConstantIndex.IsValid(), "Failed to find ReflectionProbe constant index");
AZ::RHI::ShaderInputConstantIndex useReflectionProbeConstantIndex = objectSrg->FindShaderInputConstantIndex(Name("m_reflectionProbeData.m_useReflectionProbe"));
AZ_Error("ModelDataInstance", useReflectionProbeConstantIndex.IsValid(), "Failed to find ReflectionProbe constant index");
AZ::RHI::ShaderInputConstantIndex useParallaxCorrectionConstantIndex = objectSrg->FindShaderInputConstantIndex(Name("m_reflectionProbeData.m_useParallaxCorrection"));
AZ_Error("ModelDataInstance", useParallaxCorrectionConstantIndex.IsValid(), "Failed to find ReflectionProbe constant index");
// retrieve probe cubemap index
Name reflectionCubeMapImageName = Name("m_reflectionProbeCubeMap");
RHI::ShaderInputImageIndex reflectionCubeMapImageIndex = objectSrg->FindShaderInputImageIndex(reflectionCubeMapImageName);
AZ_Error("ModelDataInstance", reflectionCubeMapImageIndex.IsValid(), "Failed to find shader image index [%s]", reflectionCubeMapImageName.GetCStr());
// retrieve the list of probes that contain the centerpoint of the mesh
TransformServiceFeatureProcessor* transformServiceFeatureProcessor = m_scene->GetFeatureProcessor<TransformServiceFeatureProcessor>();
Transform transform = transformServiceFeatureProcessor->GetTransformForId(m_objectId);
ReflectionProbeFeatureProcessor::ReflectionProbeVector reflectionProbes;
reflectionProbeFeatureProcessor->FindReflectionProbes(transform.GetTranslation(), reflectionProbes);
if (!reflectionProbes.empty() && reflectionProbes[0])
{
objectSrg->SetConstant(modelToWorldConstantIndex, reflectionProbes[0]->GetTransform());
objectSrg->SetConstant(modelToWorldInverseConstantIndex, Matrix3x4::CreateFromTransform(reflectionProbes[0]->GetTransform()).GetInverseFull());
objectSrg->SetConstant(outerObbHalfLengthsConstantIndex, reflectionProbes[0]->GetOuterObbWs().GetHalfLengths());
objectSrg->SetConstant(innerObbHalfLengthsConstantIndex, reflectionProbes[0]->GetInnerObbWs().GetHalfLengths());
objectSrg->SetConstant(useReflectionProbeConstantIndex, true);
objectSrg->SetConstant(useParallaxCorrectionConstantIndex, reflectionProbes[0]->GetUseParallaxCorrection());
objectSrg->SetImage(reflectionCubeMapImageIndex, reflectionProbes[0]->GetCubeMapImage());
}
else
{
objectSrg->SetConstant(useReflectionProbeConstantIndex, false);
}
}
objectSrg->Compile();
}
ReflectionProbeFeatureProcessor* reflectionProbeFeatureProcessor = m_scene->GetFeatureProcessor<ReflectionProbeFeatureProcessor>();
if (reflectionProbeFeatureProcessor && (m_descriptor.m_useForwardPassIblSpecular || m_hasForwardPassIblSpecularMaterial))
{
// retrieve probe constant indices
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 modelToWorldInverseConstantIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name("m_reflectionProbeData.m_modelToWorldInverse"));
AZ_Error("MeshDataInstance", modelToWorldInverseConstantIndex.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 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");
AZ::RHI::ShaderInputConstantIndex useParallaxCorrectionConstantIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name("m_reflectionProbeData.m_useParallaxCorrection"));
AZ_Error("MeshDataInstance", useParallaxCorrectionConstantIndex.IsValid(), "Failed to find ReflectionProbe constant index");
// retrieve probe cubemap index
Name reflectionCubeMapImageName = Name("m_reflectionProbeCubeMap");
RHI::ShaderInputImageIndex reflectionCubeMapImageIndex = m_shaderResourceGroup->FindShaderInputImageIndex(reflectionCubeMapImageName);
AZ_Error("MeshDataInstance", reflectionCubeMapImageIndex.IsValid(), "Failed to find shader image index [%s]", reflectionCubeMapImageName.GetCStr());
// retrieve the list of probes that contain the centerpoint of the mesh
TransformServiceFeatureProcessor* transformServiceFeatureProcessor = m_scene->GetFeatureProcessor<TransformServiceFeatureProcessor>();
Transform transform = transformServiceFeatureProcessor->GetTransformForId(m_objectId);
ReflectionProbeFeatureProcessor::ReflectionProbeVector reflectionProbes;
reflectionProbeFeatureProcessor->FindReflectionProbes(transform.GetTranslation(), reflectionProbes);
if (!reflectionProbes.empty() && reflectionProbes[0])
{
m_shaderResourceGroup->SetConstant(modelToWorldConstantIndex, reflectionProbes[0]->GetTransform());
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);
m_shaderResourceGroup->SetConstant(useParallaxCorrectionConstantIndex, reflectionProbes[0]->GetUseParallaxCorrection());
m_shaderResourceGroup->SetImage(reflectionCubeMapImageIndex, reflectionProbes[0]->GetCubeMapImage());
}
else
{
m_shaderResourceGroup->SetConstant(useReflectionProbeConstantIndex, false);
}
}
m_shaderResourceGroup->Compile();
m_objectSrgNeedsUpdate = false;
// Set m_objectSrgNeedsUpdate to false if there are object SRGs in the list
m_objectSrgNeedsUpdate = m_objectSrgNeedsUpdate && (m_objectSrgList.size() == 0);
}
bool MeshDataInstance::MaterialRequiresForwardPassIblSpecular(Data::Instance<RPI::Material> material) const
bool ModelDataInstance::MaterialRequiresForwardPassIblSpecular(Data::Instance<RPI::Material> material) const
{
// look for a shader that has the o_materialUseForwardPassIBLSpecular option set
// Note: this should be changed to have the material automatically set the forwardPassIBLSpecular
@@ -1237,7 +1243,7 @@ namespace AZ
return false;
}
void MeshDataInstance::SetVisible(bool isVisible)
void ModelDataInstance::SetVisible(bool isVisible)
{
m_visible = isVisible;
m_cullable.m_isHidden = !isVisible;