Skip to content

Commit

Permalink
HnRenderPass: updated skinning transforms when GeomBindXform changes
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMostDiligent committed Nov 9, 2024
1 parent b92984e commit 050bee4
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 10 deletions.
7 changes: 4 additions & 3 deletions Hydrogent/interface/HnMesh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,10 @@ class HnMesh final : public pxr::HdMesh

struct Skinning
{
const pxr::VtMatrix4fArray* Xforms = nullptr;
size_t XformsHash = 0;
float4x4 GeomBindXform = float4x4::Identity();
const pxr::VtMatrix4fArray* Xforms = nullptr;
size_t XformsHash = 0;
float4x4 GeomBindXform = float4x4::Identity();
size_t GeomBindXformHash = 0;

explicit operator bool() const { return Xforms != nullptr; }
};
Expand Down
14 changes: 11 additions & 3 deletions Hydrogent/src/HnMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -865,9 +865,17 @@ void HnMesh::UpdateSkinningPrimvars(pxr::HdSceneDelegate&
{
pxr::VtValue GeomBindXformVal = SceneDelegate.GetExtComputationInput(CompInput.sourceComputationId, CompInput.name);

SkinningData.GeomBindXform = GeomBindXformVal.IsHolding<pxr::GfMatrix4f>() ?
ToFloat4x4(GeomBindXformVal.UncheckedGet<pxr::GfMatrix4f>()) :
float4x4::Identity();
if (GeomBindXformVal.IsHolding<pxr::GfMatrix4f>())
{
const pxr::GfMatrix4f& GeomBindXform = GeomBindXformVal.UncheckedGet<pxr::GfMatrix4f>();
SkinningData.GeomBindXform = ToFloat4x4(GeomBindXform);
SkinningData.GeomBindXformHash = pxr::TfHash{}(GeomBindXform);
}
else
{
SkinningData.GeomBindXform = float4x4::Identity();
SkinningData.GeomBindXformHash = 0;
}
}
}

Expand Down
13 changes: 9 additions & 4 deletions Hydrogent/src/HnRenderPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,7 @@ HnRenderPass::EXECUTE_RESULT HnRenderPass::Execute(HnRenderPassState& RPState, c
Uint32 JointsBufferOffset = 0;
Uint32 CurrJointsDataSize = 0;
size_t XformsHash = 0;
size_t GeomBindXformHash = 0;
Uint32 JointCount = 0;

if (AttribsBuffDesc.Usage != USAGE_DYNAMIC)
Expand Down Expand Up @@ -460,7 +461,8 @@ HnRenderPass::EXECUTE_RESULT HnRenderPass::Execute(HnRenderPassState& RPState, c
// Reset the hash to force updating the joint transforms for the next draw item.
// NB: we can't reuse the transforms at the existing offset because they may be
// overwritten by the next draw item.
XformsHash = 0;
XformsHash = 0;
GeomBindXformHash = 0;

RenderPendingDrawItems(State);
VERIFY_EXPR(m_PendingDrawItems.empty());
Expand Down Expand Up @@ -518,7 +520,7 @@ HnRenderPass::EXECUTE_RESULT HnRenderPass::Execute(HnRenderPassState& RPState, c
if (MultiDrawCount == PrimitiveArraySize)
MultiDrawCount = 0;

if (pSkinningData && pSkinningData->XformsHash != XformsHash)
if (pSkinningData && (pSkinningData->XformsHash != XformsHash || pSkinningData->GeomBindXformHash != GeomBindXformHash))
{
// Restart batch when the joint transforms change
MultiDrawCount = 0;
Expand Down Expand Up @@ -598,7 +600,9 @@ HnRenderPass::EXECUTE_RESULT HnRenderPass::Execute(HnRenderPassState& RPState, c

if (pSkinningData)
{
if (pSkinningData->XformsHash != XformsHash)
// NOTE: we currently reupload all joint transforms if geometry bind matrix changes, which is not optimal.
// A better approach would be to move the matrix to PBRPrimitiveAttribs.
if (pSkinningData->XformsHash != XformsHash || pSkinningData->GeomBindXformHash != GeomBindXformHash)
{
VERIFY(CurrJointsDataSize + JointsDataRange <= JointsBuffDesc.Size,
"There must be enough space for the new joint transforms as we flush the pending draw if there is not enough space.");
Expand All @@ -623,7 +627,8 @@ HnRenderPass::EXECUTE_RESULT HnRenderPass::Execute(HnRenderPassState& RPState, c
VERIFY_EXPR(JointsDataSize == State.USDRenderer.GetJointsDataSize(JointCount, ListItem.PSOFlags));
CurrJointsDataSize = AlignUp(JointsBufferOffset + JointsDataSize, JointsBufferOffsetAlignment);

XformsHash = pSkinningData->XformsHash;
XformsHash = pSkinningData->XformsHash;
GeomBindXformHash = pSkinningData->GeomBindXformHash;

VERIFY(MultiDrawCount == 0, "The batch must be reset when the joint transforms change.");
}
Expand Down

0 comments on commit 050bee4

Please sign in to comment.