ゲーム開発
Unity
UnrealEngine
C++
ゲーム数学
ゲームAI
サウンド
アニメーション
GBDK
制作日記
3DCG
Houdini
Blender
USD
グラフィックス
テクノロジ
ツール開発
フロントエンド関連
サーバサイド関連
ソフトウェア設計
ハードウェア関連
おすすめ技術書
音楽
DTM
楽器・機材
ピアノ
その他
都会のエレキベア
ラーメン日記
四コマ漫画
おすすめアイテム
おもしろコラム
  • ゲーム開発
    • Unity
    • UnrealEngine
    • C++
    • ゲーム数学
    • ゲームAI
    • サウンド
    • アニメーション
    • GBDK
    • 制作日記
  • 3DCG
    • Houdini
    • Blender
    • USD
    • グラフィックス
  • テクノロジ
    • ツール開発
    • フロントエンド関連
    • サーバサイド関連
    • ソフトウェア設計
    • ハードウェア関連
    • おすすめ技術書
  • 音楽
    • DTM
    • 楽器・機材
    • ピアノ
  • その他
    • 都会のエレキベア
    • ラーメン日記
    • 四コマ漫画
    • おすすめアイテム
    • おもしろコラム
  1. ホーム
  2. 20251225_01_open_usd_basic

【OpenUSD】USD入門 その1:概要とデータ構造についてまとめる

USDPythonPixar
2025-12-25

ぷらずも
ぷらずも
みなさんこんにちは! ぷらずもです!
エレキベア
エレキベア
こんにちクマ~~
ぷらずも
ぷらずも
今回触っていくのはUSD! Pixarが開発した3Dシーン用のファイルフォーマットです。
20251225_01_01

エレキベア
エレキベア
USDクマか・・・ 名前はよく聞くクマが正直よく分からんクマね
ぷらずも
ぷらずも
映像業界では既にデファクトスタンダードになっていたり、ゲーム業界でも活用事例がいくつも出始めています。 かなり将来性のある技術で設計思想も参考になるので、ぜひ触っていきましょう!
エレキベア
エレキベア
楽しみクマ~~~

USD関連の参考資料

ぷらずも
ぷらずも
はじめに、今回情報を集めるにあたり参考にさせていただいた資料・ページを紹介させていただきます。

Pixar公式ドキュメント

ぷらずも
ぷらずも
まずはUSDの公式ドキュメントです。 コンセプト紹介からチュートリアルまで記載されているので、基本的にはこちらを見て進めるとよさそうです。
20251225_01_01
▲Pixar公式のUSDページ

20251225_01_04
▲Pixar公式の解説動画

20251225_01_02
▲OpenUSDのGitHubリポジトリ

エレキベア
エレキベア
解説動画もいくつか公開されているのクマね

その他有用なページ

ぷらずも
ぷらずも
そして日本語の解説記事に関しても、fereriaさん、手島さんをはじめ様々な方が情報を公開してくださっています。 どれも有用な情報なので、ぜひチェックしておきましょう。
エレキベア
エレキベア
先人達が情報公開してくれて本当にありがたいクマね

USDの概要

USDとは

ぷらずも
ぷらずも
はじめにUSDとは何なのか?についてですが、 簡単にまとめると以下のようになります。
✔ USDとは
  • Pixarが開発した、3Dシーンを3Dソフトウェア間でやり取りするファイルフォーマット
  • Universal Scene Desctiption の略
  • 以下のような特徴がある
    • データを 汎用的なシーングラフ構造として扱う ことが出来る
    • 複数ファイルの合成・分割が可能 で、拡張性・共同編集に優れている
    • OSSとして公開 されており、独自の拡張が行える
    • Hydra という共通描画基盤を持つ
エレキベア
エレキベア
3DのファイルフォーマットということはFBXと似たようなものなのクマ?
ぷらずも
ぷらずも
FBXを使用しても3Dデータをやり取りすることは出来ていたんだけど、 OSSでないからデータの拡張は限定的だし、複数ツール間でやり取りできる情報が限られる複数人で同時編集しづらい という状況ではあったんだ。
ぷらずも
ぷらずも
そんな問題を解消するため、USDはシーングラフ構造で情報を持てるし、Reference含む複数合成ファイルの合成・分割が可能 になっています。 そして OSSとして公開 されているため、汎用的に独自拡張も可能になっているのも大きな特徴です。
エレキベア
エレキベア
なるほどクマ どちらかというと 汎用的に扱える mb・blendファイル みたいなイメージに近いクマね

USDのメリット

ぷらずも
ぷらずも
以上のメリットをまとめると以下のようになります!
1. 汎用的な3Dシーンファイルフォーマット
  • OSSとして公開されており、複数DCCツール間で汎用的に扱える
  • シーングラフ構造を持てるため、大規模で複雑なシーンの扱いが可能
  • 汎用シェーダやレンダラーも用意されており、ある程度の見た目を含めたやり取りも可能
2. 複数ファイルの合成・分割が可能
  • 他ファイルのReferenceや継承といったことが行えるため、複数人による共同編集に向いている
  • 合成ルールも細かく定義されており、依存関係の制御が行いやすい
3. 独自の拡張が可能
  • OSSとして公開されているため、内部構造も設計することが出来る
  • メタデータなどを持たせることもでき、用途に合わせてデータを入れてやり取りすることも可能
4. Hydraという共通描画基盤
  • Hydraというグラフィックスインターフェースを抽象化した基盤が用意されている
  • RenderMan、Arnold、Karma、Redshift、V-rayといったレンダラーを使用することが出来る
エレキベア
エレキベア
大規模な開発運用に耐えうるために生まれたのクマね 拡張も可能で、今後より汎用フォーマットとして広がっていきそうクマね
ぷらずも
ぷらずも
独自拡張についてもかなり自由度があり、2025年のCEDECセッションでは、UI開発に活用した事例も紹介されていました。

【CEDEC2025】HoudiniによるUI作成について
▲UIアセット開発に応用した事例

エレキベア
エレキベア
独自拡張したデータのコンバータも用意して活用した事例クマね これを見るとかなり自由度が高く感じるクマね

USDのデメリット・注意点

ぷらずも
ぷらずも
そんなメリットがあるUSDですが、いくつか注意点もあります。
1. 名前空間による参照になる
  • GUIDSがなく名前空間ベースの参照になるため、名前空間変更時には自動変更されない
  • GUIDを入れるメリット・デメリットを検討した結果、構成の柔軟性によるメリットを選択し採用しなかったとのこと
2. リギングシステムを搭載していない
  • スケルトン、ウェイトは入っているが、それ以外のリグシステムは搭載していない
3. 3Dソフトウェア側でのUSD対応が必要
  • USD対応されていないツールでは使用できない
  • 主要なツールは大体対応されてきているが、それでも不安定な部分もある
ぷらずも
ぷらずも
特に3Dソフトウェア側での対応については、サポートが明記されていても不安定な挙動が見られる ことがあります。 また映像業界から生まれたということもあり、ゲーム業界でメインで使用される事例はあまり見られていない状態ですね・・・。
エレキベア
エレキベア
むむ・・・とはいえサポート状況が更に安定すれば変わってくるかもしれないクマね

USDのデータ構造

シンプルなUSDファイルの例

ぷらずも
ぷらずも
次はUSDのデータ構造や仕組みについて少し紹介します。 シンプルなUSDファイルの例を挙げると、以下のようなものがあります。
#usda 1.0

def Xform "hello"
{
    def Sphere "world"
    {
        float3[] extent = [(-2, -2, -2), (2, 2, 2)]
        color3f[] primvars:displayColor = [(0, 0, 1)]
        double radius = 2
    }
}

▲USDファイルの例
ぷらずも
ぷらずも
.usda というのがUSDのアスキー形式の拡張子で、.usd (.usdc) 拡張子の場合はバイナリ形式として扱われます。 バイナリの方が高速ですが、学習など行う際にはアスキーで出力すると理解しやすいです。
エレキベア
エレキベア
こうしてみるとJSONやPythonみたいなのと似ているクマね
ぷらずも
ぷらずも
出力したUSDはusdviewという専用ビューワや各種DCCツールで確認することが出来ます。
20251225_01_09
▲USD専用のビューワも用意されている

USDの用語や概念

ぷらずも
ぷらずも
USDのデータ構造の用語や概念については以下のページにまとまっています。
ぷらずも
ぷらずも
しかし名前順になっていたりとよく分かりづらかったりするので、ここからは主要な概念だけまとめようと思います。

基本となるオブジェクトモデル

ぷらずも
ぷらずも
まずはオブジェクトモデルについてですが、主に以下のような構成となっています。 USDファイルがレイヤーに該当し、その中にPrim、Propertyの構造が記載される形です。
✔ USDのオブジェクトモデル
  • Layer
    • Prim・Property等の構造を記述したUSDファイル
    • usdファイルがレイヤーに該当する
  • Prim
    • def/overで定義され、名前空間(PrimPath)を構成する要素
    • Primまでのフルパスを指定することで参照される
  • Property
    • Primが持てるプロパティの総称
    • Attribute
      • Primが持つタイムサンプル可能な値データ
      • PrimVar
        • Attributeの内、命名規約と意味が標準化されたもの
    • Relationship
      • 他のPrimへの接続を表すプロパティ
      • 値は持たず、PrimPathのみを保持する
  • Stage
    • 複数Layerを合成して評価した仮想シーン
20251225_01_13
▲USDのオブジェクト構成イメージ

ぷらずも
ぷらずも
例として以下のUSDファイルを見てみます。
#usda 1.0

def Xform "hello"
{
    def Sphere "world"
    {
        float3[] extent = [(-2, -2, -2), (2, 2, 2)]
        color3f[] primvars:displayColor = [(0, 0, 1)]
        double radius = 2

        rel material:binding = </hello/mat/blue>
    }

    def Scope "mat"
    {
        def Material "blue"
        {
        }
    }
}

▲データ構造の例
ぷらずも
ぷらずも
この場合、それぞれ以下のような定義になります。
  • Layer
    • usdaファイル内の記載全体
  • Prim
    • defで定義された、「hello」「world」「Looks」の部分
      • worldまでの参照パスは /hello/world になる
  • Attribute
    • 「extent」「displayColor」「radius」の部分
    • この内 displayColor はPrimVarに該当する
エレキベア
エレキベア
USDファイルの中にはPrim、Propertyを定義して表現するのクマね

コンポジションアーク

ぷらずも
ぷらずも
次に重要な概念として、コンポジションアーク があります。 これは USDの定義をどのような優先順序で合成するか というもので、LIVERPS と呼ばれる順序で定められています。
エレキベア
エレキベア
LIVERPS・・・・・????
ぷらずも
ぷらずも
???となるのも無理はありません・・・。 これは優先順を定義した要素の頭文字から取ったもので、以下のようになっています。
✔ LIVERPS

USD定義を探す際、上から順に探していく。

  • Local
    • ローカルのLayerStackの全てのレイヤーを反復処理して定義を探す
    • 他のレイヤーをsubLayers指定することで階層含めて合成する
  • Inherits
    • Primの構造を継承する
  • VariantSets
    • バリエーションを定義して切り替える
  • R(E)locates
    • Primの命名・配置を変更することができる
  • References
    • 別レイヤーを参照して使用する
  • Payload
    • リファレンスと同じだが、ロードをOFFにした状態でステージを開くことができる
    • 常に必要にならない参照などに有効
  • Specializes
    • 基本挙動は継承と同じだが、Referenceよりも弱い
    • Referenceの空間内でInheritsするような挙動になる
エレキベア
エレキベア
なんか Relocates だけ無理やりじゃないクマ?
ぷらずも
ぷらずも
あとから追加されたようで無理やりねじ込んだ感があるよね・・・
ぷらずも
ぷらずも
これらのルールをどう活用するかというと、例えば /hello/world という名前空間の定義を探そうとした場合、上から順に合成された結果から探すことになります。
エレキベア
エレキベア
あーなるほど 要は 複数の合成手法が重なった場合にどんな優先順で探すのか? ということクマね
ぷらずも
ぷらずも
イメージが付きにくいと思うので、それぞれ簡単な例を挙げると以下のようになります。
Local
#usda 1.0
(
    subLayers = [
        @shotFX.usd@,
        @shotAnimationBake.usd@,
        @sequence.usd@
    ]
)
▲ローカルのレイヤーを基準にsubLayersを読み込む
Inherits
#usda 1.0

class Xform "_class_Tree"
{
    def Mesh "Trunk"
    {
        color3f[] primvars:displayColor = [(.8, .8, .2)]
    }

    def Mesh "Leaves"
    {
        color3f[] primvars:displayColor = [(0, 1, 0)]
    }
}

def "TreeA" (
    inherits = </_class_Tree>
)
{
    over "Leaves"
    {
        color3f[] primvars:displayColor = [(0.8, 1, 0)]
    }
}
▲_class_Treeを継承してTreeAを生成する例
VariantSets
#usda 1.0

def Xform "hello" (
    variants = {
        string shadingVariant = "green"
    }
    prepend variantSets = "shadingVariant"
)
{
    def Sphere "world"
    {
    }
    variantSet "shadingVariant" = {
        "blue" {
            over "world"
            {
                color3f[] primvars:displayColor = [(0, 0, 1)]
            }

        }
        "green" {
            over "world"
            {
                color3f[] primvars:displayColor = [(0, 1, 0)]
            }

        }
        "red" {
            over "world"
            {
                color3f[] primvars:displayColor = [(1, 0, 0)]
            }

        }
    }
}

▲VariantSetsでバリエーションを生成している例(デフォルト:green)
Relocates
#usda 1.0
(
    relocates = {
        </CharANewVersion/Clothing> : </CharACurrent/TestClothing>,
        </EnvA/Trees> : </AlternateEnv/ParkA/Trees>
    }
)
▲Primの命名・配置(名前空間)を変更する
Reference・Payload
def "Car"
{
    references = @CarAsset.usda@
    payload = @CarGeom.usda@
}
▲Referenceはロード時、Payloadは必要になったら読み込む
Specializes
#usda 1.0

def Xform "Robot"
{
    def Scope "Materials"
    {
        def Material "Metal"
        {
            # Interface inputs drive shader parameters of the encapsulated
            # network. We are not showing the connections, nor how we encode
            # that the child Shader "Surface" is the primary output for the
            # material.
            float inputs:diffuseGain = 0
            float inputs:specularRoughness = 0

            def Shader "Surface"
            {
                asset info:id = @PxrSurface@
            }
        }

        def Material "CorrodedMetal" (
            specializes = </Robot/Materials/Metal>
        )
        {
            # specialize roughness...
            float inputs:specularRoughness = 0.2

            # Adding a pattern to drive Surface bump
            def Shader "Corrosion"
            {
                asset info:id = @PxrOSL@
                vector3f outputs:disp
            }

            over "Surface"
            {
                # Override that would connect specularBump to Corrosion
                # pattern's "outputs:disp" attribute
            }
        }
    }
}
▲Metalをspecializeで定義している
#usda 1.0

def Xform "World"
{
    def Xform "Characters"
    {
        def "Rosie" (
            references = @./Robot.usd@</Robot>
        )
        {
            over "Materials"
            {
                over "Metal"
                {
                     float inputs:diffuseGain = 0.3
                     float inputs:specularRoughness = 0.1
                }
            }
        }
    }
}
▲この場合、RobotScene側でCorrodedMetalのspecularRougnessを見ると0.2になる
ぷらずも
ぷらずも
この中で特にややこしいのは、 ReferenceとPayload InheritsとSpecializes でしょうか・・・。 ReferenceとPayloadについては以下のような違いがあります。
  • Reference
    • 参照したPrimをUSDロード時に読み込む
  • Payload
    • 参照したPrimを必要になったタイミング(遅延)で読み込む

→常に読み込まれなくてよい定義などはPayloadにする

ぷらずも
ぷらずも
そしてSpecializesに関してはInheritsと基本挙動は同じですが、Referenceされた際にReference内の名前空間で定義される ような挙動になります。 中々特殊なので、困ったときに見返すとよいでしょう・・・。
エレキベア
エレキベア
まあなんとなくこんなルールがある、というのは分かったクマ 用語だけでも覚えておくクマ

おわりに

ぷらずも
ぷらずも
というわけで今回はUSDの概要についてでした! どうだったかな?
エレキベア
エレキベア
汎用的で共同編集に適したフォーマットというのはよく分かったクマ でもやっぱり実際に触ってみないとしっくりこないクマね・・・
ぷらずも
ぷらずも
やっぱ座学だけじゃなんとなくで終わっちゃうよね・・・ というわけで次は実際に実行環境を用意して、PythonからUSDを作成・操作してみようと思います!
【OpenUSD】USD入門 その2:PythonでUSDを生成・操作してみる
2025-12-29

▲次回はPythonから操作してみます

エレキベア
エレキベア
おお~~楽しみクマ~~
ぷらずも
ぷらずも
それでは次回もお楽しみに! アデューー!!
エレキベア
エレキベア
クマ~~~~

【OpenUSD】USD入門 その1:概要とデータ構造についてまとめる ~完~


USDPythonPixar
2025-12-25
記事をSNSで共有する
X
Facebook
LINE
はてなブックマーク
Pocket
LinkedIn
Reddit

著者の各種アカウント
フォローいただけると大変励みになります!
X
GitHub

関連記事
【Houdini21.0】Solaris徹底入門:USD構成を意識した基本的な作業フローについてまとめる
2025-12-31
【OpenUSD】USD入門 その2:PythonでUSDを生成・操作してみる
2025-12-29
【プロシージャル】Pythonで学ぶ波動関数崩壊アルゴリズム(Wave Function Collapse)
2025-06-22
【Python】Pythonスクリプトをexe、app化する【cx_Breeze】
2021-08-29
【Python】Pillowを使ってピクセル操作!画像フィルタをかけてみる
2021-02-17
【Python】ぷよぷよ風の文字連結パズルゲームを作る【あけおめパズル】
2021-01-03
【Python】スクショ画像を文字認識して翻訳するツールを作ってみた!【Tesseract ×Googletrans】
2020-10-13
【Python】OpenCVを使って画像編集を自動化する
2020-08-31