Fix: LOD stops animation

Signed-off-by: T.J. McGrath-Daly <tj.mcgrath.daly@huawei.com>
This commit is contained in:
T.J. McGrath-Daly
2021-12-06 08:48:24 +08:00
parent ce709b99d0
commit 6643b4b53c
@@ -204,35 +204,56 @@ namespace AZ
// do the enumeration for each view, keep track of the lowest lod for each entry,
// and submit the appropriate dispatch item
//the [1][1] element of a perspective projection matrix stores cot(FovY/2) (equal to 2*nearPlaneDistance/nearPlaneHeight),
//which is used to determine the (vertical) projected size in screen space
const float yScale = viewToClip.GetElement(1, 1);
const bool isPerspective = viewToClip.GetElement(3, 3) == 0.f;
const Vector3 cameraPos = view->GetViewToWorldMatrix().GetTranslation();
const Vector3 pos = cullable.m_cullData.m_boundingSphere.GetCenter();
const float approxScreenPercentage = RPI::ModelLodUtils::ApproxScreenPercentage(
pos, cullable.m_lodData.m_lodSelectionRadius, cameraPos, yScale, isPerspective);
for (size_t lodIndex = 0; lodIndex < cullable.m_lodData.m_lods.size(); ++lodIndex)
switch (cullable.m_lodData.m_lodConfiguration.m_lodType)
{
const RPI::Cullable::LodData::Lod& lod = cullable.m_lodData.m_lods[lodIndex];
//Note that this supports overlapping lod ranges (to support cross-fading lods, for example)
if (approxScreenPercentage >= lod.m_screenCoverageMin && approxScreenPercentage <= lod.m_screenCoverageMax)
case RPI::Cullable::LodType::SpecificLod:
{
AZStd::lock_guard lock(m_dispatchItemMutex);
auto lodIndex = cullable.m_lodData.m_lodConfiguration.m_lodOverride;
m_skinningDispatches.insert(&renderProxy.m_dispatchItemsByLod[lodIndex]->GetRHIDispatchItem());
for (size_t morphTargetIndex = 0; morphTargetIndex < renderProxy.m_morphTargetDispatchItemsByLod[lodIndex].size(); morphTargetIndex++)
{
AZStd::lock_guard lock(m_dispatchItemMutex);
m_skinningDispatches.insert(&renderProxy.m_dispatchItemsByLod[lodIndex]->GetRHIDispatchItem());
for (size_t morphTargetIndex = 0; morphTargetIndex < renderProxy.m_morphTargetDispatchItemsByLod[lodIndex].size(); morphTargetIndex++)
const MorphTargetDispatchItem* dispatchItem = renderProxy.m_morphTargetDispatchItemsByLod[lodIndex][morphTargetIndex].get();
if (dispatchItem && dispatchItem->GetWeight() > AZ::Constants::FloatEpsilon)
{
const MorphTargetDispatchItem* dispatchItem = renderProxy.m_morphTargetDispatchItemsByLod[lodIndex][morphTargetIndex].get();
if (dispatchItem && dispatchItem->GetWeight() > AZ::Constants::FloatEpsilon)
m_morphTargetDispatches.insert(&dispatchItem->GetRHIDispatchItem());
}
}
}
break;
case RPI::Cullable::LodType::ScreenCoverage:
default:
//the [1][1] element of a perspective projection matrix stores cot(FovY/2) (equal to 2*nearPlaneDistance/nearPlaneHeight),
//which is used to determine the (vertical) projected size in screen space
const float yScale = viewToClip.GetElement(1, 1);
const bool isPerspective = viewToClip.GetElement(3, 3) == 0.f;
const Vector3 cameraPos = view->GetViewToWorldMatrix().GetTranslation();
const Vector3 pos = cullable.m_cullData.m_boundingSphere.GetCenter();
const float approxScreenPercentage = RPI::ModelLodUtils::ApproxScreenPercentage(
pos, cullable.m_lodData.m_lodSelectionRadius, cameraPos, yScale, isPerspective);
for (size_t lodIndex = 0; lodIndex < cullable.m_lodData.m_lods.size(); ++lodIndex)
{
const RPI::Cullable::LodData::Lod& lod = cullable.m_lodData.m_lods[lodIndex];
//Note that this supports overlapping lod ranges (to support cross-fading lods, for example)
if (approxScreenPercentage >= lod.m_screenCoverageMin && approxScreenPercentage <= lod.m_screenCoverageMax)
{
AZStd::lock_guard lock(m_dispatchItemMutex);
m_skinningDispatches.insert(&renderProxy.m_dispatchItemsByLod[lodIndex]->GetRHIDispatchItem());
for (size_t morphTargetIndex = 0; morphTargetIndex < renderProxy.m_morphTargetDispatchItemsByLod[lodIndex].size(); morphTargetIndex++)
{
m_morphTargetDispatches.insert(&dispatchItem->GetRHIDispatchItem());
const MorphTargetDispatchItem* dispatchItem = renderProxy.m_morphTargetDispatchItemsByLod[lodIndex][morphTargetIndex].get();
if (dispatchItem && dispatchItem->GetWeight() > AZ::Constants::FloatEpsilon)
{
m_morphTargetDispatches.insert(&dispatchItem->GetRHIDispatchItem());
}
}
}
}
break;
}
}
}