Master the largest single exam topic โ all 6 composition arcs, LIVERPS resolution order, layer stack, opinion strength, and scene composition debugging.
Why composition is USD's superpower: Universal Scene Description allows studios to compose entire production scenes from multiple layers and files โ asset layers, shot overrides, department contributions โ all without a single destructive edit. Every modern studio pipeline (from feature film to game development) depends on composition arcs to keep assets shareable, overridable, and non-destructive. Mastering this topic is the key to passing NCP-OUSD and to working effectively with USD in production.
Core Concepts at a Glance
Four foundational ideas underpin all of USD composition.
Ordered list of layers; opinions resolved from strongest (top) to weakest (bottom). SubLayers build the stack. Every layer contributes opinions to the same composed result.
The 6 mechanisms to bring scene data together: subLayers, references, payloads, inherits, specializes, variants. Each has different semantics and strength.
The resolution order acronym: Local โ Inherits โ Variants โ References โ Payloads โ SubLayers. Strongest first, weakest last.
Stronger (higher in LIVERPS) wins. Only one value survives per attribute per time code. Local opinions always win; subLayer opinions always lose.
Deep-Dive: Composition Concepts
Detailed explanations, Python examples, and reference tables for all 6 arcs.
A layer is a single file (a .usda, .usdc, or .usdz) or an in-memory object containing opinions about prims and their attributes. Layers are the atomic unit of USD composition.
The layer stack is formed by a layer's subLayerPaths list. The first entry is strongest; entries later in the list are progressively weaker โ like a stack of transparency sheets where the top sheet's ink shows through to the bottom.
stage.SetEditTarget(layer).stage.MuteLayer(identifier) excludes a layer from composition without removing it from disk.subLayerPaths are relative to the layer that contains them.# Build a layer stack: stronger.usda overrides weaker.usda
stage = Usd.Stage.CreateNew("root.usda")
root_layer = stage.GetRootLayer()
root_layer.subLayerPaths = ["stronger.usda", "weaker.usda"]
# Set edit target to the stronger layer
stronger = Sdf.Layer.FindOrOpen("stronger.usda")
stage.SetEditTarget(stronger)
# Mute a layer (excludes from composition, non-destructive)
stage.MuteLayer("weaker.usda")
SubLayers aggregates layers additively at the stage level. Every prim and attribute opinion from every sublayer contributes to the same composed result.
References bring external asset data under a target prim path in the referencing layer. This is the primary mechanism for asset assembly โ bringing a character, prop, or environment into a shot.
prim.SetInstanceable(True)from pxr import Usd, Sdf
stage = Usd.Stage.CreateNew("shot.usda")
xform = stage.DefinePrim("/World/Hero", "Xform")
# Add external reference
refs = xform.GetReferences()
refs.AddReference("assets/hero.usda", primPath="/Hero")
# Add internal reference
refs.AddReference("", primPath="/SourcePrim")
# Enable instancing for repeated assets
xform.SetInstanceable(True)
Payloads are like references but load-on-demand. Unloaded payloads appear as lightweight proxy prims โ you can traverse the scene graph and see the prim exists without paying the cost of loading all its data.
load=Usd.Stage.LoadNonefrom pxr import Usd
# Open stage with all payloads unloaded
stage = Usd.Stage.Open("scene.usda", load=Usd.Stage.LoadNone)
# Add a payload to a prim
prim = stage.GetPrimAtPath("/World/BigAsset")
prim.GetPayloads().AddPayload("heavyAsset.usda")
# Load and unload individually
stage.Load("/World/BigAsset")
stage.Unload("/World/BigAsset")
# Batch load/unload
stage.LoadAndUnload(
toLoad=["/World/AssetA", "/World/AssetB"],
toUnload=["/World/OldAsset"]
)
Inherits propagates opinions from a class prim (abstract โ never rendered directly) to all prims that inherit from it. Changes to the class propagate instantly to all inheritors.
class specifier (not def)from pxr import Usd, Sdf
stage = Usd.Stage.CreateNew("chars.usda")
# Define an abstract class prim
base = stage.CreateClassPrim("/BaseCharacter")
base.CreateAttribute("material:binding", Sdf.ValueTypeNames.String).Set("default_mtl")
# Inherit from the class
hero = stage.DefinePrim("/World/Hero", "Xform")
hero.GetInherits().AddInherit(Sdf.Path("/BaseCharacter"))
# Hero's local opinion overrides the inherited one
hero.CreateAttribute("material:binding", Sdf.ValueTypeNames.String).Set("hero_mtl")
Specializes is similar to inherits but weaker. A specialized prim's opinions fall below referenced and inherited opinions in LIVERPS. This allows a "base" look to persist while references and overrides take precedence.
from pxr import Usd, Sdf
stage = Usd.Stage.CreateNew("variants.usda")
# Define base class
base = stage.CreateClassPrim("/CharBase")
# Specialize from the base
char = stage.DefinePrim("/World/Character", "Xform")
char.GetSpecializes().AddSpecialize(Sdf.Path("/CharBase"))
# References and Inherits will override the specialized opinions
A VariantSet is a named group of mutually exclusive alternatives โ like "shadingVariant" containing "metal", "wood", "plastic". Only one variant is active at a time; the selection is stored as metadata, not as a new file.
from pxr import Usd, Sdf
stage = Usd.Stage.CreateNew("asset.usda")
prim = stage.DefinePrim("/Asset", "Mesh")
# Create a variant set and variants
vsets = prim.GetVariantSets()
vset = vsets.AddVariantSet("shadingVariant")
# Add variants
vset.AddVariant("metal")
vset.AddVariant("wood")
vset.AddVariant("plastic")
# Set active selection
vset.SetVariantSelection("metal")
# Author opinions inside a variant
vset.SetVariantSelection("metal")
with vset.GetVariantEditContext():
prim.CreateAttribute("roughness", Sdf.ValueTypeNames.Float).Set(0.2)
vset.SetVariantSelection("wood")
with vset.GetVariantEditContext():
prim.CreateAttribute("roughness", Sdf.ValueTypeNames.Float).Set(0.8)
When multiple arcs contribute opinions to the same attribute, USD uses LIVERPS to determine which opinion wins. Stronger arcs (listed first) always override weaker arcs (listed last).
| Letter | Arc | Strength | Notes |
|---|---|---|---|
| L | Local | Strongest (1) | Opinions authored directly on the prim in the current layer |
| I | Inherits | 2nd | From class prims via inherits arc โ beats references |
| V | Variants | 3rd | Active variant's opinions โ weaker than inherits |
| R | References | 4th | From referenced external files โ most common arc |
| P | Payloads | 5th | From payload files โ weaker than references |
| S | SubLayers | Weakest (6) | From the layer stack โ lowest priority of all arcs |
When a composed value surprises you, use these tools to inspect what's happening:
prim.GetPrimStack() โ list all contributing Sdf.PrimSpec objects in strength orderattr.GetPropertyStack() โ all contributing opinions for a specific attributeattr.GetResolveInfo() โ find exactly which layer "won" for an attribute valueUsdUtils.FlattenLayerStack(stage) โ flatten to see the final composed resultusdview --inspect โ visual composition graph explorerfrom pxr import Usd, UsdUtils
stage = Usd.Stage.Open("scene.usda")
prim = stage.GetPrimAtPath("/World/Hero")
# See all specs contributing to this prim (strongest first)
for spec in prim.GetPrimStack():
print(spec.layer.identifier, spec.path)
# Check which layer won for a specific attribute
attr = prim.GetAttribute("roughness")
resolve_info = attr.GetResolveInfo()
print("Winning layer:", resolve_info.GetSource())
# See all opinions for the attribute
for spec in attr.GetPropertyStack():
print(spec.layer.identifier, "->", spec.default)
# Flatten the composed result
flat_layer = UsdUtils.FlattenLayerStack(stage)
flat_layer.Export("flat_result.usda")
Memory Hooks
Six memorable mental models to lock in the key concepts for exam day.
Local โ Inherits โ Variants โ References โ Payloads โ SubLayers. Strongest first. Local always wins. SubLayers always lose. Memorize this order cold โ it will appear directly on the exam.
References load immediately when the stage opens. Payloads load on demand โ call stage.Load() explicitly. Use payloads for heavy assets not always needed. Both bring external data, but their load behavior is the key difference.
Inherits is 2nd in LIVERPS. Specializes comes after References โ it is the weakest non-subLayer arc. Use Inherits for shared defaults that should propagate down. Use Specializes for a "keep base look but let references override" pattern.
SubLayers merges entire layers at the stage level โ every prim in every sublayer contributes. References brings one asset's prim tree under a specific target path. SubLayers is about stacking; References is about assembly.
Variants store alternative opinions without file duplication. The active variant selection is just metadata โ switch from "metal" to "wood" without touching the asset file at all. The variant edit context is how you write variant-specific opinions.
When a value surprises you, call prim.GetPrimStack() to see every contributing spec in strength order. Use attr.GetPropertyStack() for a specific attribute, and attr.GetResolveInfo() to find the exact winning layer.
Knowledge Quiz
10 questions ยท one at a time ยท instant feedback
1. What is the correct LIVERPS resolution order from strongest to weakest?
2. Which composition arc loads data on demand and can be controlled with stage.Load()?
3. Which prim specifier is used to define the target of an inherits arc?
4. A VariantSet named "lodVariant" has variants "hi", "mid", "lo". Which Python call sets the active variant to "hi"?
5. Which arc is WEAKEST in the LIVERPS resolution order?
6. What does stage.MuteLayer(identifier) do?
7. An asset needs swappable shading looks (metal, wood, plastic) without duplicating geometry files. Which arc is best suited?
8. What is the key difference between References and Inherits?
9. Which Python method reveals which layer's opinion wins for a specific attribute?
10. When opening a stage with Usd.Stage.LoadNone, what happens to payload prims?
Flashcards
Click any card to flip. 8 cards covering the essential concepts.
stage.Load('/prim') to load. Unloaded payloads appear as lightweight proxies. Prefer payloads for heavy assets not always in camera.
class prim to multiple prims. The inheriting prim's local opinions win over inherited ones. Stronger than References in LIVERPS. Used for shared rig defaults, material propagation across many assets.
with vset.GetVariantEditContext(): prim.CreateAttribute(...)Sdf.PrimSpec objects contributing opinions to this prim, in strength order (strongest first). Essential for debugging unexpected composition results. Pair with attr.GetPropertyStack() for attribute-level detail.
stage.SetEditTarget(layer). Only one layer is the edit target at a time. New prims and attribute sets go to this layer โ not necessarily the root layer.
Study Advisor
Targeted guidance for mastering the largest exam topic.
Composition is 23% of the exam โ the single largest topic. Expect 14โ16 questions. LIVERPS order is almost certainly tested directly. Know when to use each arc and how they differ from each other. Focus especially on: Payload vs Reference (lazy vs eager), Inherits vs Specializes (strength order), and the Python API for each arc.
NVIDIA Learn OpenUSD Module 3 "Composition Basics" and Module 5 "Creating Composition Arcs" are the primary study materials. Supplement with the USD Glossary for precise definitions of each arc.
Create a multi-layer scene from scratch: write a root.usda that subLayers an asset.usda and a shot_override.usda. Add references to external assets, switch variant selections in Python, and use usdview --inspect to visualize the composition graph. Nothing cements LIVERPS like seeing it work live.
โ Confusing SubLayers (stage-level, additive) with References (prim-level, targeted)
โ Forgetting Inherits beats References in LIVERPS (I comes before R)
โ Thinking Payloads are stronger than References โ they are not (P comes after R)
โ Not knowing that Specializes is weaker than References (Specializes comes after References)
โ Forgetting that class prims (not def) are required for inherits targets
Composition feeds directly into Debugging & Troubleshooting (11%) โ most debugging scenarios involve unexpected composition results from arc conflicts. Content Aggregation (10%) heavily uses references and instancing, which builds on the composition fundamentals covered here. Master composition first, and these topics become much easier.
Resources
Official links for study, registration, and reference.
NVIDIA NCP-OUSD exam overview, objectives, and registration info
NVIDIA's official tutorial covering layer stacks and the fundamentals of USD composition
NVIDIA's official tutorial with hands-on Python examples for all 6 composition arcs
Authoritative definitions for every USD term including each composition arc, LIVERPS, and opinion strength
Official Certiverse registration โ $200 fee ยท 60โ70 questions ยท 120 minutes ยท 2-year credential
FlashGenius gives you adaptive flashcards, timed quizzes, and progress tracking across all NCP-OUSD topics. Start free โ no credit card required.
Start Free Trial โ