We have USD files containing meshes with over 100,000 points. This causes usdview to render slowly, especially when accessed over a shared network drive, and we’re unable to achieve a steady 30fps playback.
We’ve observed that after usdview renders a frame once, subsequent renders of the same frame are much faster. Profiling shows that the main bottleneck is in HdStMesh::_UpdateRepr
, particularly in HdSceneIndexAdapterSceneDelegate::GetMeshTopology
. Since there are no dirties on the second render, it is about 5x faster than the initial one. Similarly, HdStVBOMemoryManager::_StripedBufferArrayRange::CopyData
takes significantly longer on the first render.
Based on these findings, to ensure artists can view the USD file at 30fps, we decided to call stageView.renderSinglePass
for every frame when opening a stage in usdview. This approach works, but introduces a new issue: the process takes too long. For files with more than 10,000 time samples (we use value clips), it takes over 15 minutes to render the entire stage, forcing users to wait.
I considered rendering multiple frames concurrently, since even HdRenderIndex
uses a lot of parallel computation in the SyncAll
function, usdview doesn’t seem to fully utilize CPU or GPU resources. When I tried to add concurrency in UsdImagingGLEngine
, I found that Hydra is not thread-safe when marking dirty states or retrieving render parameters.
So, is there any way to render multiple frames concurrently, or any other approach to cache topology and so on before playback? We don’t need to edit the stage—just review it—so I hope this makes things easier. Any suggestions are appreciated. Thank you!
Note:
I also tried fetching all time-varying attributes before playback, but as mentioned above, the main bottleneck seems to be in Hydra, so this didn’t help much.