Asset Structure, Instancing, and Performance
This domain tests whether you can build assets that scale and behave predictably for downstream tools.
Structure conventions
- One
defaultPrimper asset layer, usually anXformnamed for the asset withkind = component. - Group with
Scope(non-transforming) or nestedXforms; useassemblyandgroupkinds so assembly tooling can reason about hierarchy. - Put heavy geometry behind payloads so consumers open lightweight scenes:
Usd.Stage.Open(..., load=Usd.Stage.LoadNone), then load per asset. classprims exist only to be inherited; they never render.
Instancing
- Native instancing marks a prim
instanceable = truealongside a reference. USD shares one prototype (/__Prototype_1) across all instances; prototype edits affect every instance. - PointInstancer places thousands of copies via
protoIndices,positions,orientations,scales, andids. - Traverse with
Usd.TraverseInstanceProxies; a plain traversal stops at the instance boundary.
Performance practice
- Prefer binary
.usdc, many small layers, and coarse payload granularity. - Avoid per-frame authoring of large arrays; mark static attributes
uniform. - Set
purpose = proxyfor hero geometry and authorextentsHintto make bounds cheap. - Never
Flatten()a stage as a speed fix - it destroys instancing and payload structure.
Worked example
For 1,000 chairs, model one chair.usd, then create /World/Chair_00 and siblings with references = @chair.usd@ and instanceable = true. Memory drops to a single prototype. Editing the seat material inside chair.usd updates all 1,000; authoring size directly on Chair_07 changes nothing visible, because the instance shares the prototype's opinions.
Traps
Instancing a prim that already carries per-instance overrides; expecting GetChildren() to descend into instances; and payloading so aggressively that a viewer renders an empty stage.