4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

UnityでUSDを使ってみたい

Last updated at Posted at 2024-12-13

はじめに

この記事は株式会社アプリボットのAdvent Calendar14日目の記事です

はじめまして、株式会社アプリボットのアセット制作支援組織、YojiGen所属TAのholyです

この記事では主に今話題のOpenUSD (Universal Scene Description)の利用が可能なUnityパッケージについて軽く触れたいと思っています

Open USDとは?

USDとは、Universal Scene Descriptionの略称です
※本記事では以降略称USDを用います

USDは映画等で有名なPixar Animation Studiosが開発した、
次世代のアセットパイプラインとワークフローを実現するためのフレームワークです

このフレームワークを用いることで、プロダクションワークフロー上今までは難しかったシーンの同時編集が可能になることや、FBXなど既存ファイルフォーマットでは取り扱いが難しかった拡張情報をかなり高い自由度で埋め込めるようになります

またUSDで利用可能なファイルフォーマット.usdは、.fbx.obj等と同様に異なるアプリケーションをまたいでモデルやマテリアル、アニメーションを行き来させることができるだけでなく、異なるアプリケーションで同じファイルを編集できるようになります

さらに知りたいと言う方は公式のドキュメントUSD とは (2022 年改定版)をご覧いただければさらに詳しく知ることができます

いままではC++によるSDKのビルドを行わないと拡張ができなかったのですが、
昨今はpythonでバインドされたパッケージがpipでインストールできるようになったり、
参入のしやすさも格段に増してきています

USDの最新情は是非以下の世界的なUSDの標準化運動を行うコミュニティーを追いかけてみてください

簡易的な紹介

USDは同時編集が可能

同時編集とはワークフロー内で多職種が同時多発的に同じファイルを編集することを指します
なぜこれが可能なのかというと、それはUSDの特徴であるレイヤー管理にあります

USDのレイヤー管理

USDで提供さているAPIには文字列でオブジェクトやメタデータの情報を管理する仕組みがあります

USDではオブジェクトやメタデータの最終合成処理を Stage と呼ばれるシーングラフでおこなっているのですが、
このシーングラフ内の編集を Layer という単位で個別に分割管理できるようになっています

Layer のイメージ詳細はこちらが非常にわかりやすいため是非訪れていただくと詳細に理解できるかと思います

上記から抜粋してシンプルな部分のみを解釈するなら、
MayaのシーンやUnityのシーンやFBXのシーン=これはシーングラフ= Stage です

Layer はそれらシーングラフに反映するグラフ要素の編集状態の保存機能です

また Layer はRootLayer(大抵はそのusdのメインStageです)の下にネストして SubLayer を持つことができるためシーングラフ内に異なるシーングラフをネストできます

このため Layerを利用したシーン編集 はUnityのプレハブ編集やMayaのリファレンス編集に近しいと思います

そういった編集をFBXでは行うことができませんが、USDでは可能になるというのが強みです

レイヤー管理と作業者ごとの作業構造例

AnimationStage (subLayer=animation.usd)
┗ skelAnimation(prim) => アニメーターはここだけいじる
┗ ModelStage (subLayer=model.usd)
  ┗ geometry(prim) => モデラーはここだけいじる

// プレハブにおきかえると
AnimationPrefab
┗ PlayablePrefab (PlayableDirector)
    ┗ Playable(animationCLip)  => アニメーターはここだけいじる
┗ ModelPrefab
    ┗ SkinnedMeshRender や Transform   => モデラーはここだけいじる

※prim こちらは後ほど軽く触れます

上記のような構造で作業が可能です
それぞれの担当者がこのレイヤー単位(usd単位)で編集を行うことで作業分担が効率化できます

USD自体はここまでにして、さっそくUnityで扱っていきます

UnityのUSDパッケージ

Unreal EngineではすでにUSDを取り扱うためのプラグインが公式より公開されています
ではUnityではどうかというと、もちろん利用することが可能です!

ただし!

まだUnityではUnity2023以降のバージョンかつ、
Preバージョンということで正式なリリースにはなっていないのが現状です
※ 2024年現在

とはいえUnity6でも使えるということで、さっそくパッケージ導入方法を見ていきましょう

この記事で取り扱うアプリケーションのバージョン情報

Unity 6 (6000.0.24f1)
Maya 2025.3

Maya2023などからUSDPluginが利用できますが、マテリアルを操作できるのはLookDevX正式導入後のMaya2025からになります

Unity USD パッケージについて

ではさっそくパッケージのインストールを行っていきたいですが、その前になにをインストールすればよいのか見ていきます

2024年現在、UnityのUSDパッケージは3種類あります

  • USD Core
  • USD Importer
  • USD Exporter

Unity USD Coreによると、ImporterやExporterはCoreに依存しているためImporterかExporterのパッケージをインストールすれば自動的にCoreがインストールされるようです

USD Importerのインストール

今回はMayaで作成したUSDファイルをUnityで読み込ませて見ようと思いますので、
公式の手順にしたがいImporterをいれていきます

上部メニューからWindow>Package ManagerでPackageManagerを起動します

PackageManagerの+ボタンからinstall package by nameを押下して、
出てきたダイアログにcom.unity.importer.usdと入力します
image.png

インストールが完了しました
image.png

なにか読み込ませてみる

ということで、弊社が公開しているアニメーション用フリーモデルをUSDに変換して利用します

MayaでUSD化を行います
image.png

Unityのプロジェクト内に保存します
image.png

なにやらおかしいです...

原因を特定する

原因はすぐ判明しました
が原因を追求するためにまずはインポーターを見ていきましょう

image.png

画像のようにFBXのインポート時のInspectorとはだいぶかけ離れた見た目をしていますが、
よく見てみると怖いものはありません

しいていうならモデル、モーション、テクスチャのタブが統合されたメニューになっただけといった風貌です

見慣れたオプションに着目しすると

  • Recalculate mesh normals

とあるではないですか、シェーディングがおかしいのなら間違いなくこれでしょう
チェックをいれて再インポートをかけます

image.png

やりました

なんで起きた?

USDのドキュメントに目を通すと標準では 座標系を右手座標のものとして 情報を保存しているとありました
Mayaはタンジェントスペースをいじらないかぎりは右手座標系なので特に変換を掛ける必要はありませんが、
Unityはワールドスペースが左手座標系になるため変換が必要そうでした

ということで基本的にUnityではRecalculate mesh normalsのチェックを有効にしましょう

ただしUSDは手軽に拡張が可能なので左手座標の情報を拡張して保存しておき、
UnityのFBXSDKを用いるかのようにUSD Coreを用いてインポーターを作成しておけば、
好きなようにインポートも可能なようです(今回は触れません)

もう一つ問題があります

テクスチャを読み込みたい

そういえばテクスチャがきてません

FBXを扱っていればfbmでないかぎり、MayaでUnity側との相対的なテクスチャパスが一致していないとインポート時にテクスチャがマテリアルに反映されていないのは必然です

USDではどうかというと、もちろん相対パスの保存が可能です
それに加えてfbmと異なりusdzというフォーマットを用いることでなんとサブアセットにテクスチャ込でインポートすることも可能です

USDのファイルフォーマット

USDで扱えるファイルフォーマットは4種類あります

  • .usd
    • この形式でもASCIIとBinary保存の2種類を選択できます
  • .usda
    • 明示的にASCIIデータであるフォーマットです
  • .usdc
    • 明示的にBinaryデータであるフォーマットです
  • .usdz
    • fbmのようにusd内にテクスチャなどのリソースをそのまま保存できます

テクスチャを持ってきたいぞ

Mayaではテクスチャをsourceimagesに保存しておいて相対パス保存しておけば共同作業時便利になります

とはいえ、じゃあUnity側もsourceimagesを参照しにいけるかというとUnityではプロジェクトのAssets以下に読み込める状態でなければ参照することができません

私が過去構築したパイプラインでは大抵sourceimagesにあるテクスチャをモデルのFBXと一緒に、Unity側で構築したフォルダ階層へ一緒に出力またはコピーをおこないUnity側で解決を行っていました

fbmを使えば埋め込みが可能でしたが、fbmは同じ階層に結局リソースが展開され不便になります

ところが、UnityのUSD Importerではusdzフォーマットであればなんと、読み込んだusdファイルの サブアセットとして埋め込みリソースを読み込む ことができます

https://docs.unity3d.com/Packages/com.unity.importer.usd@1.0/manual/Importing.html
image.png

とりあえずusdzフォーマットで読み込みなおしたい

さっそくMayaでusdzを書き出したいですが...
image.png

どうやら現時点では書き出しオプションがないようです

それと便利ではあるがテクスチャのみ修正したい場合にusdz内のテクスチャを毎回弄りにいくのか?
と、言われるとちょっと違う気がしてきました

であれば別の手を考えます

相対パス保存フローでいこう

USDは参照のあるファイルをUSD自身を基点とした相対パスで保存できます
image.png
ですのでMayaでモデルをUSD出力するときにMaterialsの設定でテクスチャパスをRelative保存します

Mayaのシーンではこのような相対パスでシーンを保存していました
image.png

よし!
ということで、ちゃんと相対パス保存されたかusdのStageを一度Mayaでロードしてみます

Maya2025であれば、LookDevXでUSDのマテリアルグラフをBifrostのグラフライクに見ることができるので確認します

image.png
んーおかしいですね

他にもStageツリー内のTextureFileノードのアトリビュートを直接見るか、
.usdをASCIIで保存すればUSD内のデータをそのまま目視で確認することもできます
image.png

想定していた相対パスではないですね
これは困ります

これはMayaでUSDを作成する場合に、USDの相対パス管理をMaya基準で行ったのが原因でした

Mayaの相対パスの解決ではProjetのルートに設定したフォルダを基準に相対パスを解決しますが、
通常USDは.usdファイルを起点にパス解決が行われます

なのでLookdevXのグラフ編集を行いPathが解決できるようにします
image.png

今回は簡易にUnity側にも.usdファイルの親フォルダにsourceimagesを作成し、そこにテクスチャを配置しておきます

Mayaでは2025をインストールしたばかりだとUSDをBinaryで保存してしまいます
プリファレンスでASCIIフォーマットに設定しておきます
image.png

USD LayerEditorでUSDに編集結果を反映

Unity側
image.png

ただこれではマテリアルがきていないようでテクスチャを確認できませんでした
ここも簡単に修正できますが、その前に

USDのデータ構造を理解する

USDはポリモーフィズムにデータの読み書きができるように、実にシンプルな構造でデータが保存されています

構造は以下の画像のような感じです
image.png

USDのファイル内ではAPIで公開されたクラス情報などがコード認識可能な形に埋め込まれています

def に続くあとの文字列がオブジェクトの宣言部分です
ここで宣言できるのはUSDのデータコンテナであるPrimとして定義されたオブジェクトの型です

Primとは(引用)

PrimはUSD の主要なコンテナ オブジェクトです。Prim は他の Prim を含めることができ (順序付けも可能)、Stageに 「名前空間階層」を作成できます。また、Prim は意味のあるデータを保持するプロパティを含めることができ (順序付けも可能) ます 。Prim と、それに関連付けられた計算されたインデックスは、 Stage がメモリ内に保持する唯一の永続的なシーングラフ オブジェクトであり、Prim を操作するための API はUsdPrimクラスによって提供されます。Prim には常に、ステージでの Prim の一般的な役割を決定する解決済みのSpecifierがあり、Prim には、Prim に含まれるデータの種類を指示するスキーマtypeName がある場合があります。Prim は、シーン レベルのインスタンス化、ロード/アンロード動作、および非アクティブ化を適用する粒度も提供します。

たとえばdef MaterialとあればMaterialのPrimということになります

ちなみにMaterialPrim内の情報をMaya内で確認するならLookDevXグラフで見れば接続情報がわかります
image.png

image.png

シェーダー情報を追加する

現在USDのAPIで扱えるシェーダーエフェクトは

  • MaterialXというライブラリを利用したサーフェスシェーダー
  • USDのデータをプレビューするために標準的に同封されているUsdPreviewSurface(MaterialXを利用したもの)
  • SdrShaderNodeスキーマでglslfxファイルなどを読み込んで構成したもの

これらを使わないと異なるアプリケーション間で情報を共通利用できません

元データを確認すると弊社のフリーモデルはrampshaderを主に利用しておりますが、すこし組み方が独特です
しかもこの規格はLookDevX(つまりMaterialX)で作成されたものではなくMaya専用のものになりますので自動変換がかかる場合にうまく解決できなくなっていました

※よくわかりませんが、なぜかテクスチャから直接surfaceが出ているというものになっています

というわけでUnity側のUSDでも最初から変換を用意してくれているUsdPreviewSurfaceを明示的に利用して保存しなおします

Mayaでサーフェスシェーダーをつなげる

USD内のマテリアルを編集する場合、アウトライナーのUSDStageツリー内にあるマテリアルのコンテキストメニューから、Show in LookdevXでグラフビューを起動します

image.png

LoodevXでマテリアルが表示されているので、ダブルクリックしてグラフを表示したらタブキーを押下、
USD > USD Preview Surfaceを押してグラフノードを作成します
image.png

本来USDでマテリアル内にグラフノードを使う場合は明示的にそのスキーマを利用するパラメーターを追加する必要があるのですが、そこはMayaが保存時にオートで行ってくれます

次にテクスチャノードのrgbとaをUsdPreviewSurfaceの各inputにつなぎます

image.png

UsdPreviewSurfaceのinputを見てなんとなく察した方は多いかもしれませんが、PreviewSurfaceのシェーダーはBxDFを利用したPBRシェーダーです

すべてのマテリアルで編集をおこなったらUSDファイルに保存を行います

Unity側でも変更が反映されているのが確認できます
image.png

Maya側の描画です
image.png

opacityの描画はデプスソートを行わないと前後関係がおかしくなりますが、そのあたりはそれぞれのアプリケーションで行いますので今回は無視します

あとはメッシュを編集するなりしてもUSDに保存をおこなうだけでUnity側に即反映されます
ただ2024年現在のパッケージではUnity内の編集と保存までは行えないようでした

これが行えると双方向で編集が可能になりますね

アニメーションはどうなる?

冒頭の構造を再び確認します

AnimationStage (subLayer=animation.usd)
┗ skelAnimation(prim) => アニメーターはここだけいじる
┗ ModelStage (subLayer=model.usd)
  ┗ geometry(prim) => モデラーはここだけいじる

いまはModelStageのみをUnityに保存して解説していました
アニメーションもusdで上記のように編集と保存ができます

fereria氏のドキュメントにもありますがModelStage自体に編集をおこなってしまうとモデルの構成とアニメーション編集が同時にかきこまれてしまいアニメーションの編集のみを管理しずらくなります
モデルのStageとアニメーションのStageはレイヤーでわけましょう

上記を実現するためにアニメーション用のusdを作成し、その下にモデルのUSDをサブレイヤーとしてロードします
image.png

そこで読み込まれているモデルの階層を Edit As Maya Data でMayaで編集可能な状態にしたら
image.png

いつものMayaでアニメーションを編集するかのようにアニメーション付をおこないます

アニメーション付ができたらUSDに変更を保存するため Merge Maya Edits to USD でアニメーションを書き込みます
image.png

そうするとUnityでAnimationCLipがインポートされて利用可能になります
image.png

課題もある

ただ、現段階 ではこのMaya用のデータに変換するというフローからアニメーションをつけるときにコントローラーをつけたままのシーンでアニメーション作業する、というフローはなかなか組みにくいように思います

例えばFBXではコンストレイント情報を書き出しておけばUnityでのインポート時に再現できました
しかしUSDではこの項目がまだ存在しないようです

USDのAPIドキュメントを軽く見る感じConstraintのワードはありませんでした
またMayaのUSDのExportオプションでconstraintの項目がありますが書き出されたconstraintノードはXFormになっておりなんのスキーマもありませんでした

コンストレイントがMaya仕様のDependencyノードになるためこのあたりの互換性を成立させる拡張、つまりはUSD側に専用のスキーマを用意して、それぞれアプリケーションで変換機能を追加する必要があると推測しています

すごく大変そうなのでUSDとそれを扱えるアプリケーションごとにも標準搭載される日を切に願います(他力本願)

でも相当な需要だと思うので近い内にきそうですよね

まとめ

USDをUnityを使った開発で利用するためにはまだいくつかUSD自体とUnityのパッケージの更新を待つ必要があるようですが、モデル編集のたびにFBXやテクスチャを再出力するといったいままでの弊社フローにおいては、そのあたり簡略化できるので移行したときのメリットが十分あるように感じます

しかしアニメーション周りはまだまだ改善される余地があるように感じます

Mayaのシーンが最終的なレンダリング結果になりえる環境ではない場合シーングラフの解釈を標準のUSDAPIにまかせっきりでは行けなさそうでそれなりに工夫が必要そうです

ただ世界的に標準化する動きのなかにはゲーム業界も含まれている以上、その点は今後なんらかのアプローチがでてきて一般化されていくと期待しています

ありがとうございました

15日目はref3000さんによる、[GAS] スプレッドシートに限定公開のDrive画像を埋め込むです!
こちらもお見逃しなく!

関連リンク集

■ MaterialX DeveloperGuide

■ USDドキュメント

■ Unity USD Core

■ USD とは (2022 年改定版)

■ Alliance for OpenUSD

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?