@herbst , I’ll give some context on how we got to the current behavior (which was not the original behavior!), at the end, but wanted first to contribute one more pattern that’s somewhat in-between Jan’s and Thomas’s that serves us well in our pipeline. And yeah, it’s both a blessing and a curse that there’s often no “One True Way” to do things in USD…
The following pattern attempts to satisfy two goals:
- Keep the entire definition in one file/layer
- Allow for maximal sharing of common scene description between all variants, and preserve a “meaningful” presentation of the asset even when no variant is selected.
Here it is:
def Xform "Branch" (
references = </Branch_base>
variantSets = ["sizes"]
variants = {
string sizes = "small"
}
)
{
variantSet "sizes" = {
"small" {
custom double length = 0.5
}
"large" {
custom double length = 2
}
}
}
# Typically, MODEL_base will contain a complete description of the "undifferentiated" asset...
# In our pipeline, that often corresponds to a "default" variant
over "Branch_base"
{
custom double length = 1
}
It’s perhaps a bit easier of a pattern for DCC’s to follow than Thomas’s pattern, though I haven’t actually seen it in any
We follow this pattern for our shading layers and their variants, produced by an in-house tool. Though, now that USD supports convenient namespace editing, it would be pretty straightforward to deploy as a “chaser” post-processing script on top of e.g. stock Maya export, I think.
LIVERPS History
@herbst , you are not alone in your expectation of how variants should work, including some Pixarians as they came into USD - after all, variants are “more specific” opinions than local, so shouldn’t they be stronger? In fact that was the original behavior reached by the Presto designers back in 2004/05. However, as we worked with it in the pipeline over the next six or so years, we learned two things:
- It can be incredibly inconvenient. Imagine I have a layerStack, in which a weak layer defines a variantSet with a bunch of variants. Now in a stronger layer in that stack, I simply want to universally override a value that happens to be specified in that weaker variantSet. In the “simple” and very efficient composition engine that ships with USD today, we essentially first “flatten” the layerStack before interpreting the composition arcs. That would mean that the stronger layer’s local/direct opinion would lose to the weaker variant opinions, so to override such an opinion, you’d need to add a new one to each variant in the stronger layer… assuming you knew which variantSet was providing it. This obviously wouldn’t stand, so…
- The Presto algorithm became not-simple, with arcs (possibly even only variantSets, though I’m not sure) being interpreted layer-by-layer within a stack. As we needed to add and modify core composition behaviors, these special rules had to become more and more complex, and by 2010/11, the composition system was kind of buckling under its own complexity and becoming unmaintainable.
The creation of the modern Pcp composition engine was the single-biggest precursor that gave us confidence we could create an open-sourceable scene description system, and IIRC, @blevin discovered in his prototyping that making that change to the relative strength of variant and local opinions was (one of) the big unlock that made the current, recursive, encapsulated composition algorithm possible. Luckily for us, the pattern I described above (and our other tooling) just so happened to not, at that point in our pipeline’s evolution, rely on the old behavior. So we were able to roll out the new behavior without much of a blip.