USD to glTF: How usd2gltf Translates Materials

Converting 3D assets from Universal Scene Description (USD) to glTF requires translating complex shading networks into a standard, runtime-efficient format. The open-source usd2gltf tool achieves this by parsing USD's shading primitives—primarily based on the UsdPreviewSurface specification—and mapping their parameters, channel configurations, and texture transformations directly into glTF 2.0 PBR (Physically Based Rendering) materials and relevant Khronos extensions.

Parsing the USD Shading Network

In USD, materials are represented as directed acyclic graphs managed by the UsdShade API. A UsdShadeMaterial serves as a container that exposes terminal outputs for surfaces, displacement, and volumes.

The usd2gltf converter traverses this graph by locating the primary surface output and identifying the connected shading node. In standard pipelines, this node is an instance of UsdPreviewSurface, USD’s baseline standard for interchange. The tool reads the input attributes defined on the shader, resolving both constant values and upstream connections to nodes like UsdUVTexture and UsdTransform2d.

Mapping PBR Parameters

Once the graph is parsed, usd2gltf maps the properties of UsdPreviewSurface directly to glTF’s core pbrMetallicRoughness model:

  • Base Color: The USD diffuseColor input maps to glTF's baseColorFactor (if constant) or baseColorTexture.
  • Metallic and Roughness: The scalar values metallic and roughness are assigned to metallicFactor and roughnessFactor.
  • Emissive: The USD emissiveColor maps directly to glTF’s emissiveFactor and emissiveTexture.
  • Normals: Normal map inputs connected to the normal input are converted to the glTF normalTexture.

If an input has both a texture and an authored scale factor, usd2gltf multiplies the factors accordingly to match glTF’s standard evaluation rules.

Texture Channel Repacking

One of the primary technical challenges in translating material graphs between USD and glTF is texture layout. glTF strictly defines packed texture layouts to minimize GPU texture lookups:

  • Metallic-Roughness: glTF requires roughness in the green channel and metalness in the blue channel of a single texture (metallicRoughnessTexture).
  • Occlusion: Ambient occlusion typically resides in the red channel of an occlusionTexture (frequently shared with metallic-roughness as an ORM texture).

USD, conversely, often routes individual monochrome textures or separate color channels via UsdUVTexture outputs (e.g., extracting the r component). To resolve this, usd2gltf samples the upstream image data, extracts the relevant channels for ambient occlusion, roughness, and metalness, and repacks them into a unified image file adhering to glTF’s channel conventions.

Texture Transforms and UV Sets

When texture coordinates in USD are modified using a UsdTransform2d node (such as tiling, offset, or rotation), usd2gltf translates these operations into the KHR_texture_transform glTF extension. The scale, translation, and rotation attributes from USD are mapped directly into the extension's scale, offset, and rotation fields. Additionally, the tool verifies UV index assignments, mapping USD’s st or custom UV primvars to glTF's TEXCOORD_0 or TEXCOORD_1 attributes.

Handling Alpha, Opacity, and Advanced Features

The converter evaluates the USD opacity input alongside opacityThreshold to determine the glTF alphaMode:

  • If opacityThreshold is greater than zero, the material is configured as MASK using the threshold value as alphaCutoff.
  • If opacity is variable or less than 1.0 without a threshold, it maps to BLEND.
  • If opacity is fully opaque, it defaults to OPAQUE.

For advanced material properties supported by USD—such as clearcoat or index of refraction (IOR)—the tool translates the inputs into the corresponding Khronos extensions, such as KHR_materials_clearcoat and KHR_materials_ior, ensuring high-fidelity visual parity between the original USD asset and the exported glTF output.