はじめに
この記事は株式会社アプリボットの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
と入力します
なにか読み込ませてみる
ということで、弊社が公開しているアニメーション用フリーモデルをUSDに変換して利用します
なにやらおかしいです...
原因を特定する
原因はすぐ判明しました
が原因を追求するためにまずはインポーターを見ていきましょう
画像のようにFBXのインポート時のInspectorとはだいぶかけ離れた見た目をしていますが、
よく見てみると怖いものはありません
しいていうならモデル、モーション、テクスチャのタブが統合されたメニューになっただけといった風貌です
見慣れたオプションに着目しすると
- Recalculate mesh normals
とあるではないですか、シェーディングがおかしいのなら間違いなくこれでしょう
チェックをいれて再インポートをかけます
やりました
なんで起きた?
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
とりあえずusdzフォーマットで読み込みなおしたい
どうやら現時点では書き出しオプションがないようです
それと便利ではあるがテクスチャのみ修正したい場合にusdz内のテクスチャを毎回弄りにいくのか?
と、言われるとちょっと違う気がしてきました
であれば別の手を考えます
相対パス保存フローでいこう
USDは参照のあるファイルをUSD自身を基点とした相対パスで保存できます
ですのでMayaでモデルをUSD出力するときにMaterialsの設定でテクスチャパスをRelative保存します
Mayaのシーンではこのような相対パスでシーンを保存していました
よし!
ということで、ちゃんと相対パス保存されたかusdのStageを一度Mayaでロードしてみます
Maya2025であれば、LookDevXでUSDのマテリアルグラフをBifrostのグラフライクに見ることができるので確認します
他にもStageツリー内のTextureFileノードのアトリビュートを直接見るか、
.usdをASCIIで保存すればUSD内のデータをそのまま目視で確認することもできます
想定していた相対パスではないですね
これは困ります
これはMayaでUSDを作成する場合に、USDの相対パス管理をMaya基準で行ったのが原因でした
Mayaの相対パスの解決ではProjetのルートに設定したフォルダを基準に相対パスを解決しますが、
通常USDは.usd
ファイルを起点にパス解決が行われます
なのでLookdevXのグラフ編集を行いPathが解決できるようにします
今回は簡易にUnity側にも.usdファイルの親フォルダにsourceimagesを作成し、そこにテクスチャを配置しておきます
Mayaでは2025をインストールしたばかりだとUSDをBinaryで保存してしまいます
プリファレンスでASCIIフォーマットに設定しておきます
USD LayerEditorでUSDに編集結果を反映
ただこれではマテリアルがきていないようでテクスチャを確認できませんでした
ここも簡単に修正できますが、その前に
USDのデータ構造を理解する
USDはポリモーフィズムにデータの読み書きができるように、実にシンプルな構造でデータが保存されています
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グラフで見れば接続情報がわかります
シェーダー情報を追加する
現在USDのAPIで扱えるシェーダーエフェクトは
- MaterialXというライブラリを利用したサーフェスシェーダー
- USDのデータをプレビューするために標準的に同封されている
UsdPreviewSurface
(MaterialXを利用したもの) - SdrShaderNodeスキーマでglslfxファイルなどを読み込んで構成したもの
これらを使わないと異なるアプリケーション間で情報を共通利用できません
元データを確認すると弊社のフリーモデルはrampshaderを主に利用しておりますが、すこし組み方が独特です
しかもこの規格はLookDevX(つまりMaterialX)で作成されたものではなくMaya専用のものになりますので自動変換がかかる場合にうまく解決できなくなっていました
※よくわかりませんが、なぜかテクスチャから直接surfaceが出ているというものになっています
というわけでUnity側のUSDでも最初から変換を用意してくれているUsdPreviewSurface
を明示的に利用して保存しなおします
Mayaでサーフェスシェーダーをつなげる
USD内のマテリアルを編集する場合、アウトライナーのUSDStageツリー内にあるマテリアルのコンテキストメニューから、Show in LookdevXでグラフビューを起動します
LoodevXでマテリアルが表示されているので、ダブルクリックしてグラフを表示したらタブキーを押下、
USD > USD Preview Surfaceを押してグラフノードを作成します
本来USDでマテリアル内にグラフノードを使う場合は明示的にそのスキーマを利用するパラメーターを追加する必要があるのですが、そこはMayaが保存時にオートで行ってくれます
次にテクスチャノードのrgbとaをUsdPreviewSurfaceの各inputにつなぎます
UsdPreviewSurfaceのinputを見てなんとなく察した方は多いかもしれませんが、PreviewSurfaceのシェーダーはBxDFを利用したPBRシェーダーです
すべてのマテリアルで編集をおこなったらUSDファイルに保存を行います
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をサブレイヤーとしてロードします
そこで読み込まれているモデルの階層を Edit As Maya Data でMayaで編集可能な状態にしたら
いつものMayaでアニメーションを編集するかのようにアニメーション付をおこないます
アニメーション付ができたらUSDに変更を保存するため Merge Maya Edits to USD でアニメーションを書き込みます
そうするとUnityでAnimationCLipがインポートされて利用可能になります
課題もある
ただ、現段階 ではこの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