USD for Apple Vision Pro

by Arman D.
pixar banner

If you are a visionOS developer, you've probably already worked with USD. If not, you definitely will — and that’s a good thing.

USD is becoming the new standard for the entire 3D industry. It’s already widely used in VFX and games, so if you learn it now, you’ll gain a valuable skill that will benefit you for years to come across various fields.

In this guide, I’ll cover the basics to help you understand the file structure and modify it as needed.

Tools

1) VS Code

- Install the “USD Language” extension.
- Turn off word wrap: View → Word Wrap.

2) Reality Composer Pro

VSCode Logo Reality Composer Pro Logo

How to start

1. Open Reality Composer Pro (RCP).
2. Create a new project.
3. Open the Scene.usda file in VS Code.

In this scene, you’ll find the following:

first scene in RCP

The top section may contain various metadata related to the entire scene (more on this later).

Below that, you’ll see def Xform "Root" — this is a prim.

Prims

A prim (primitive) is the primary container object in USD. Prims can contain other prims and properties that hold meaningful data. Xform is one type of prim (at this stage, it’s best to have only one root prim).

There are many types of prims, but as visionOS developers, we’re mainly interested in those supported by RCP. The key types are:
Xform, Scope, Mesh, Material, and Shader (not shown in the RCP hierarchy).

Xform

An Xform is an object that has transformations.
For example, when you create a Transform in RCP, it generates an Xform.

Creating transform in RCP Transform in USD file

In parentheses, you’ll see metadata for this prim:
active = true

This indicates whether the object is active in the scene. If you click Deactivate on this entity in RCP, you’ll see the value change in the file.

Entity deactivation

Now, let’s modify the Transform component of this entity.

You’ll notice new data appear in the file — these are properties:

xform properties

customData with quatf xformOp:orient – required for correct rotation
float3 xformOp:scale – defines the scale
float3 xformOp:translate – defines the position
uniform token[] xformOpOrder – determines the order of transformations (important in 3D)

Scope

Next, create a Scope in RCP.

Scope in RCP Scope in USD

It’s simple — a Scope is like a folder. It doesn’t have any transformations.

Primitive shapes

Let’s create a Capsule in RCP.

Capsule in RCP Capsule in USD

You’ll notice that it generates not a Mesh, but a Capsule.
USD includes prims for basic shapes:
Cube, Sphere, Cylinder, Cone, Capsule, Plane (not represented in RCP).

For any other complex shapes, USD uses Mesh.

You can create all of these in RCP and inspect the code—RCP automatically generates the corresponding Material and Shader for them.

Material & Shader

You can see new metadata like:
prepend apiSchemas = ["MaterialBindingAPI"]

Meshes and materials are often in different folders, or a single material may be used across multiple meshes. To link them, USD uses MaterialBindingAPI, which is applied to meshes to bind materials.

Inside the curly braces {}, you’ll find the binding relationship:
rel material:binding = </Root/Capsule/DefaultMaterial>

The connection between Material and Shader is slightly different, but overall intuitive. We will cover that in the next parts.

There are also Light and Camera prims in the USD spec, commonly used in other industries. However, RCP doesn’t support cameras, and if you create any Light in RCP, you’ll see it represented as an Xform. Why? Good question — ask Apple 😉

Practice

You can create different entities in RCP and explore their code. You can even take any USD files from the internet!

Tips

1. If you downloaded a .usdz file, unzip it using the Archive Utility.

unzip usda

2. If there’s an unreadable .usd or .usdc file inside, run:
> usdcat inputFile.usdc -o outputFile.usda

3. You can add files of any USD format to your existing scene:

link to other file in USD

prepend references = @viking_C.usdz@
This links the file to your scene.

You might also see over instead of the usual def. This means you’re overriding properties for the entity only in your scene, while the original file remains unchanged.

What about animation?

USD supports animation through prims like:
SkelRoot, Skeleton, SkelAnimation, BlendShape.
We will cover these in the next part as well.

This is a vast topic, and I’m still learning. If you spot mistakes or have new insights to share, feel free to reach out — I’d love to hear from you!

If you don’t want to dive into the details but need an app for Apple Vision Pro, contact us at Immerse It!

Thanks for reading! 🚀