Display purposes not being properly updated in 22.03+

Hey everyone,

Josh from Weta Digital here :slightly_smiling_face:

We are currently in the middle of updating the Hydra render delegate of our real time renderer from 21.08 to 23.08, and one thing that sticked out is how display purposes are not properly respected anymore following the API updates that happened in 21.11/22.03.

Adding support for tracking of the task render tags version in the HdRenderPass was apparently not enough.

From my print debugging, I can draw a couple of observations, namely:

  • Methods from HdRprim derived classes (such as HdMesh, and their own derivatives) such as _InitRepr()/_PropagateDirtyBits()/Sync()/… are not called anymore as we enable/disable display purposes.
    • This is making things… difficult for us to destroy/recreate our internal data properly.
  • A new UpdateRenderTags() virtual method has been added on HdRprim.
    • From my quick testing, it does not seem to be called on every change of state of a display purpose, but only one out of two instead, i.e. if a Prim is assigned the “render” purpose and we start the delegate with said purpose already activated, the method will be called as we disable it, but not as we enable it (and the opposite is also true if the purpose was not enabled as we started the renderer).

I can see that hdStorm seems to be making use of UpdateRenderTags() to keep track of tags counts in its HdRenderParam class. Would this be the way to go for a real time renderer?

In our case, we are not using the disabling of purposes to hide the data as we destroy it instead (through Finalize() to call on our own Cleanup() function easily), since we cannot afford to hold a duplicate of our scenes in memory at all time in production.

What would be the proper way to handle this issue?

Thanks,

Joshua

1 Like

Hey Joshua,

The behavior you’re describing definitely sounds broken! Our internal testing hasn’t shown a regression, so if you have a simple example case you could post to a github issue we can take a look at it.

Note that the design of purpose in hydra is to:
(1) Create a prim the first time its purpose is included in a draw call.
(2) Only update prims (via Sync) when their purpose is included in a draw call.
(3) Never delete prims based on purpose.

This works well for some workflows and not others. Our long term roadmap is to shift some of the rendering context (like which purposes to draw) from task data to a “renderSettings” prim (e.g. one sourced from UsdRenderSettings); this is present in usdrecord already, but not for interactive workflows. Once we roll that out to interactive workflows, we could use a pruning scene index filter to customize/optimize purpose handling for different applications.

Thanks for bringing this issue up!
Tom

Hi,

We just ran in to this issue on our side trying to hide skeleton meshes by flagging them as guide when dealing with bad content.
Did anyone find a workaround for this?

Regarding the comment above, the workaround we ended up using was to “touch” the USD prim in a different way (apart from setting the display pupose property) to trigger a Hydra update.

Specifically, we have a function _touchPrim() that sets the SkeletonBindingAPI and then removes it, with conditional checks in place to avoid any actual modification of the USD prim.