Streaming is available in most browsers,
and in the WWDC app.
Understand USD fundamentals
Discover the fundamentals of Pixar's Universal Scene Description (USD) and learn how it can help you build great 3D assets and workflows. We'll introduce you to the core concepts behind USD and explore how you can integrate the format into your content creation pipeline. We'll also show you how to harness the power of USD by using composition to create flexible and versatile assets.
- ASWF USD Working Group
- Creating a 3D application with Hydra rendering
- Have a question? Ask with tag wwdc2022-10129
- Introduction to Universal Scene Description (USD)
- Search the forums for tag wwdc2022-10129
- USDZ schemas for AR
♪ instrumental hip hop music ♪ ♪ Hello, and welcome to WWDC. My name is Kacey. You may have come across Universal Scene Description, or USD, already. You may have interacted with USD files in augmented reality. Or you may have converted assets from other formats to USD. But what's really inside of a USD file? USD is an important technology with unique features, so let's take a look under the hood and explore the fundamentals of USD together. We'll learn what USD is, introduce some basic USD concepts, learn how to compose scenes with USD, and get an understanding of the USD file formats. First, what is USD? USD was developed by Pixar Animation Studios to enable them to create the complex movies we love, and it is widely used across the film, entertainment, and other industries. It's extensible by design and is rapidly emerging as a collaborative, key workflow technology. It's an open source project built on decades of production experience in the film industry and is increasingly being adopted for games, simulation, AR, manufacturing, and e-commerce. There are three core aspects to USD: the scene description specification, the API, and the rendering system. Your application interacts with USD using the API. The rendering system provides support for visualizing the scenes with different renderers. Apple has multiple different rendering systems for USD. Check out the "Explore USD tools and rendering" session to learn more about it. In this session, we focus on the scene description specification which states how scene data is described, how it is organized, and how it is represented in a file format. Fundamentally, these USD files contain data describing how a scene should look. Rendering applications interpret the data, and produce an image on the screen. For example, at last year's WWDC session, we created this USD scene and rendered it in Octane. Now let's dive into the fundamental concepts and learn about the data behind the render. To keep things simple, we will use a text USD representation USD has a lot of cool features we'd love to talk about, but for the sake of time, we will focus on the essentials features that you may most commonly encounter while working with USD such as stage, prim, and layers, just to name a few. Let's start with the stage. Imagine we are attending a play in a theater. As audience members, we observe the stage to watch the actors perform, notice the environments, lighting, and the props. This is a good analogy to how a stage works in USD. A stage is a scene graph, or a data structure, that organizes graphical information in a hierarchical way, where all the scene elements come together. A stage is a composition of one or more layers, which are typically files containing scene information. In general, a stage is made up of prims, which are the primary container objects of a scene. Prims can contain other prims to create a hierarchy of scene elements. Let's check out an example. On the left, we have a sample USD layer and on the right, we see a preview visual representation of the stage. We see two prims: a sphere and a cube. Each prim has a certain type that defines what it represents on the stage. There are many different types of prims that make up a stage such as meshes, lights, and materials. For this example, the sphere prim has a type called "Sphere," and the cube prim has a type called "Cube." But this brings up a good question. How does USD know what these prim types mean? USD knows this through the use of schemas. Schemas are structured data that define the role of a prim on the stage. They provide meaning to common scene concepts like geometry, materials, and more. For this example, here is a schema definition of a sphere. It defines that every sphere has a radius and a bounding box extent. With the existing schemas, USD gives you a rich foundation of built-in types to describe your scenes. Custom schemas enable you to extend USD even further. You can provide your own schemas that represent your custom data for your own use cases and workflows. Schemas don't need to have a visual representation. They can just be data you want to have in the stage in a structured, meaningful way. For example, here, I've created a new schema called "WWDC." It defines that a prim that has a title and a year associated with it, and here is a prim called "WWDC22" that uses the schema. It has set the year to 2022 and the title is set to "Call to code." The year and the title are called the "attributes" of the prim. Prims can have many different attributes. Each attribute has a type and a value. Attributes can also have default values authored so they don't have to be explicitly defined in the prim that uses the schema. Going back to our Sphere schema, you can see how we've defined default values for the radius and extent attributes. In this layer, we have a single Sphere prim. Since the Radius attribute is not set, it derives its value from the Sphere schema: a default radius of one. We can be explicit though, and set the radius attribute. The sphere still looks the same because this value matches the default value of one that is set in the schema. Now let's add a second sphere, and set the radius to 0.5. We can see that it's indeed half the size of the other sphere. Attributes, prims, and stages can also contain metadata, which are key-value pairings of information that can provide auxiliary data for parts of a scene. Metadata is set at the level where it applies. Metadata that affects the whole stage and all prims in it is set at the stage level. Metadata that is specific to a single prim, is set on the prim. Attributes can also have metadata. For example, here is some typical stage metadata. metersPerUnit defines the scale units for the scene. upAxis defines which of the X, Y, or Z axes is considered the up direction for the camera in the scene. doc strings store useful documentation for workflow tracking purposes. Now that we have defined these basics, we can already start making use of USD. Let's see how the pancakes scene can be done using just these concepts. In our layer, we create a transform prim called "Pancakes." We then add a transform prim called "Blueberry_01" that is a child of the Pancakes prim. Within the Blueberry_01 prim, we include the Mesh prim. The Mesh prim holds the geometry for the blueberry and binds to the materials. Let's complete the rest of the asset by adding the other prims. Here is our completed pancake scene, using just these basic concepts.
These fundamentals can get you far, but in production-centric projects, we need to collaborate with many different team members and organizations. USD has a lot of features to address this need in what is called "composition." Composition enables the creation of a stage from separate units of scene description. This allows for the efficient reuse of 3D elements in a scene that enables collaboration and fast iteration. We will discuss the most common types of composition: layering, references, payloads, and variantSets. But let's do it in a fun way. Fancy a game of chess? Let's build out a chess set scene. In the scene, we will use a catalog of assets in a catalog layer, which will refer to our chess pieces. We will then arrange these pieces on the chessboard in a layout layer to get our final result, which is viewable with the ChessSet layer. We'll first need to get our chess pieces In chess, there are six main pieces: the pawn, rook, bishop, knight, queen, and king. We will use these assets, created with Object Capture, to build a complete chess set. Let's start by bringing in our pieces to our stage using a USD concept, referencing. Referencing is when a prim in a stage refers to another prim in either the same stage or a different layer without copying the data. This helps minimize duplication of data and allows for the data to be updated separately by different people and applications. Let's reference our pawn asset into our scene. In our catalog layer, we define a prim called "Pawn". So far it doesn't have any data and so our stage is still empty. Next, we add a reference to the Pawn.usda layer. This brings in the pawn asset, and we can see it in the catalog layer. But how does USD know which prim it should bring in from the file you reference? We can specify this prim with the defaultPrim metadata. The defaultPrim metadata is defined on the stage and specifies which prim should be referred to when using this scene on another stage. We recommend always authoring a defaultPrim for USD assets. Let's check our pawn asset to make sure the defaultPrim is authored. We can see the defaultPrim metadata at the stage level in our asset. Great. Alternatively, if the defaultPrim is not authored or you wish to refer to a prim that is different from the defaultPrim, you can specify the path to the prim in the referencing layer explicitly, anywhere in the hierarchy. Paths in USD are used to identify elements on a stage. The prim path is a unique identifier for a prim. For example, on this stage we see three prims. The World prim has a prim path of /World. The Pawn and Knight prims are considered children of the World prim. Thus the path to the Pawn prim would be /World/Pawn, and the path to the Knight prim would be /World/Knight. With that in mind, we can explicitly set the prim path to the Pawn prim in our reference here. For larger scenes, it can be expensive to load all the scene information at once. For this, USD allows for the deferred loading of scene description onto a stage with a type of reference called a "payload." It is recommended to use payloads when referencing large data sets, such as complex geometry, or other large scene graphs representing props or characters.
We'll convert these asset references to payloads instead, so we can choose to defer the loading of the chess pieces. If we choose not to load the payloads, our scene appears empty when initially opened. Once we enable the loading of payloads, we can see all of our pieces again. Now that we have our pieces in the scene, we can start laying them out on the chess board. We can do this on yet another layer using the USD concept of layering. With layering, layers can be stacked, similar to popular image editing software packages such as Photoshop or Affinity Photo. Prims in a layer that are above another layer are considered stronger and can add or override data in the lower layers. As you can see, the pieces are currently in their wrong places But don't worry, we can use layering to make nondestructive modifications to other layers. This is perfect for us to move our pieces to the right positions without editing our catalog layer. Let's see how this can be done We start by creating a new stage called ChessSet which will be our final scene. It contains metadata called "sublayers" at the top of the layer. Here we bring in our pieces with the catalog layer. Next, we create a new layer -- Layout.usda -- which we use to move our pieces. This layout layer will contain the positions of our chess pieces. Let's override the position of our pieces in the scene. We'll start with Pawn_01. We modify the pawn asset's position by changing its translation attributes. Let's check out how this updates our scene. Here we have our chess set again without our layout layer, so the pawn is still in its original position. Once we add our layout layer, the pawn has been moved to its expected position on the chessboard. Let's do the same for the other pieces and move them to their correct locations.
We position our other chess pieces the same way we position the pawn. Here's how we did it for Pawn_02. And then again for Pawn_03, and so on. We finished the changes to the layout layer, and now we have the chess pieces set in their correct location.
We have half of our chess set built. We use layers to bring in our assets with the catalog layer and use the overrides to place them on the board with the layout layer.
All that is left is setting up the pieces for the opponent side. One thing to note is that our opponent's pieces are a different color. Instead of making a new set of assets, we can update our chess piece assets using another USD concept, variantSets. VariantSets allow for the dynamic swapping of discrete alternatives on the stage. The variants contained in a variantSet can be different materials, geometry, or anything that can be represented in USD. Switching between different variants on a stage is nondestructive. We will setup variant sets to switch between different materials for the chess pieces. In our Pawn asset, we add a variantSet called "color" so we can switch between different colors for the pawn. Now we add two variants to our variantSet: Dark using the dark material and Light using the light material. Finally, we set the default variant to specify which one to use when we load the pawn onto the stage. Now, we are back in our catalog layer. We've set up all the pieces on the board, but they are all using the light material. That is because the default variant is set to the light material. Let's change the variant of one of the pawns to the dark material. We set the variant to Dark. We can see that one of the pawns on the opponent's side is now dark. Let's apply this change to the other pieces as well. Finally, we completed our chess set.
There's one more USD concept we can use to optimize our scene: scene graph instancing. Scene graph instancing allows us to reuse parts of scene graph on a stage many times to represent anything that contains more than one of something such as foliage, furniture, or in our case, chess pieces. Using scene graph instancing provides both memory and performance improvements in your applications. To use scene graph instancing, we can specify the instance metadata on a prim or part of a scene graph. All prims that are instanced are candidates to share the same scene graph. Let's add support for prim instancing in our scene. In our catalog file, we will add the metadata "instanceable" to the chess piece prims and set the value to true. By adding this metadata, USD will now treat these assets as potentially instanceable prims that share the same data, rather than duplicating the data for each prim. Our chess set still looks the same but it's now more performant and memory efficient. And with this, we're done with our chess set! It looks great, and we exercised a lot of USD features.
Layering, referencing, payloads and variantSets are just some of the types of composition that USD defines. There is a specific strength order in which USD composes the scene graph to ensure consistent scene representation. More information about composition and the order acronym LIVRPS can be learned in Pixar's USD documentation. In this session, we talked about what's inside of USD files. Now let's talk about the files themselves and how they might appear on disk. There are several types of USD files. USD files containing readable ASCII text had the .usda extension. We have been using these files the whole time in this session. A more compact and efficient binary representation is the crate format, which has the .usdc extension. You may also have files with the .usd extension. These could either be ASCII text or binary crate files. Lastly, USD has a packaging format which can contain multiple USD files and associated auxiliary files, like textures, in an uncompressed zip archive with the .usdz extension. Today we learned about some of USD's fundamental concepts: stage, layers, prims, schemas, attributes, and metadata. We used these concepts to build a chess set and made use of referencing, payloads, the defaultPrim, prim paths, layering, and instancing. And finally, we discussed the different USD file formats: .usda, .usdc, .usd, and .usdz. We encourage you to learn more about these concepts with Pixar's USD documentation and take full advantage of USD's capabilities in your applications. Thank you! ♪
Looking for something specific? Enter a topic above and jump straight to the good stuff.
An error occurred when submitting your query. Please check your Internet connection and try again.