[Omniverse] DCCツールからusd以外の3Dモデルをインポート

  • by

Omniverseに3Dモデルを渡す場合、usdファイルやコネクタを経由する以外の手段も使えます。
今回は、DCCツール側でfbxファイルをエクスポートし、これをOmniverse Createに持って行く流れの覚書になります。

Omniverse Create 2021.3.3で確認しました。

Omniverseでインポートできるファイル形式

Omniverseにインポートできるファイル形式は、usd(usda/usdc)またはusdzになります。

以下のファイルフォーマットはOmniverse上でUSD形式に変換してからインポートすることができるのを確認しました。

  • glTF(glb)
  • obj
  • fbx

上記のうち、座標位置などの数値について厳密な単位情報(m/mmなど)を持っているのは「glTF(glb)」または「fbx」ファイルのみです。
objは単位情報を持ちません。

glTFフォーマットは、メートル(m)で統一されています。
対してUSDフォーマットは、デフォルトではセンチメートル(cm)を採用しています(単位変換のオプションはUSD内部で持つことも可能)。
fbxは固定の単位を持つわけではありませんが、内部で単位を切り替えることができます。
この「単位」は、ファイルフォーマットが持つ単位である点に注意してください。
Omniverseに渡す際にその単位をUSDのcmに合わせるのは、Omniverse側の仕事になります。

usd以外のファイルのインポート方法

Contentウィンドウを表示し、対象のファイル(glTF/obj/fbx)を探します。
usd形式の場合はusdファイルをそのままシーンにドラッグ&ドロップすると、3Dモデルとして配置されます。
それ以外のファイルフォーマットの場合は、右クリックしてポップアップメニューを表示。
「Convert to USD」を選択します。

Import Optionsダイアログボックスが表示されます。

「Use meter as world unit (cm by default)」チェックボックスが単位変換っぽいですが、
これをOn/Offしても違いが分かりませんでした。
「Import」ボタンを押すと、対象のファイルと同じファイル名のフォルダが生成され、その中にコンバートされたusdが格納されます。

コンバートされたusdファイルをシーンにドラッグ&ドロップすると、3Dモデルとして配置されます。

なお、マテリアルのパラメータやテクスチャは渡されるものと渡されないものがあります。
Meshに対するマテリアル名の対応は確実に渡せるようでした。
オリジナルの3Dモデルファイルがusd以外の場合は、マテリアルパラメータはうまく読み込まれないことが多いように感じます。
基本的には、マテリアルはOmniverse上で改めて割り当てるとしたほうがよさそうです。

なお、マテリアル情報を持つ場合は、OmniPBRとして割り当てられていました。

usd以外のファイルの場合の形状サイズについて

obj/glTF/fbxをusd変換した形状をインポートするとき、いずれの場合もサイズの再調整を考慮する必要があります。
既存のシーンにドラッグでインポートしたとき、形状は参照の形になっています。

対象形状を選択し、PropertyウィンドウのTransformのScaleで倍率を変更します。

obj

Convert To USDでUSDに変換した後、
obj内の数値をmm(ミリメートル)と見た場合は、0.1倍する必要あり。
obj内の数値をm(メートル)と見た場合は、100倍する必要あり。
obj内の数値をcm(センチメートル)と見た場合は、倍率変更の必要なし。

glTF(glb)

Convert To USDでUSDに変換した後、100倍する必要あり。

fbx

Convert To USDでUSDに変換した後、一部のDCCツールからのfbx(内部的にmmで単位を持たせた場合)は0.1倍する必要あり。

単位変換については、複雑なため思考中とのことでした。
USDとその他の調整が必要なようです。

以下、フォーラムより。
https://forums.developer.nvidia.com/t/unitscalefactor-is-not-referenced-during-fbx-import/187937

Omniverseの単位や寸法について

OmniverseはUSDをベースにしているため、USDでのデフォルト単位であるcmで統一されています。

デフォルトのグリッドのサイズは100cm x 100cm(1m x 1m)です。

グリッドサイズについては、Viewport Settingsより確認できます。

PropertyウィンドウでのPositionなどの座標値は、cm単位です。

Omniverse CreateのUSDの根本の単位について

Omniverse Create 2021.3.5で確認。
2021/09/23追記。

usdでは"metersPerUnit"によりシーン単位が決定されます。
デフォルトは0.01になります。
これは、対象のusdファイルの座標値がcm単位で格納されていることになります。
1.0だとすると、usdファイルの座標値はm単位となります。

ただし、現段階のOmniverse Createでは"metersPerUnit"の対応が行われていないようです。
https://forums.developer.nvidia.com/t/3ds-max-groups-break-objects/180894/4

Pythonスクリプトの以下でこの値を確認できます。

from pxr import Usd, UsdGeom, UsdPhysics, UsdShade, Sdf, Gf, Tf
stage = omni.usd.get_context().get_stage()

# Get metersPerUnit (default : 0.01).
metersPerUnit = UsdGeom.GetStageMetersPerUnit(stage)

print(metersPerUnit)

objやfbxからConvert To USDした場合、座標値については変更されず、"metersPerUnit"の値がそれぞれのフォーマットのシーン単位によって変更が加えられるようです。

そのため、上記のTransformのScaleを変えてスケールを調整するというのはあくまで回避策で、
将来的にOmniverse Createが"metersPerUnit"の対応を行うと逆に問題になる可能性があるかもしれません。

もし、scaleを変更して整合性をcmに合わせた場合は、
以下のように"metersPerUnit"を0.01に変更する、などの調整を行った方が安全かもしれません。

from pxr import Usd, UsdGeom, UsdPhysics, UsdShade, Sdf, Gf, Tf
stage = omni.usd.get_context().get_stage()

# Set metersPerUnit.
UsdGeom.SetStageMetersPerUnit(stage, 0.01)

fbxインポート時の注意点

fbxインポート(USDにコンバート)する場合は以下を注意する必要があるようでした。

  • 寸法はfbxの内部単位の指定により正しくコンバートされない場合があるため、適宜Scaleを変更する必要がある。
  • ASCII文字列以外の形状名、マテリアル名、パス名、テクスチャファイル名を指定するとうまくいかない(これはUSDフォーマットの仕様)。
    形状名「メッシュ1」などはNG、「Mesh1」のように指定します。
  • 形状名、マテリアル名などの先頭をアルファベットやアンダーバーなどの一部の文字以外の数値を指定すると、うまくいかない(これはUSDフォーマットの仕様)。
    形状名「3d_mesh」などはNG、「_3d_mesh」のように指定します。
  • 1Meshに対して1Materialを割り当てること。
  • USD上でのパス("/root/shape1/mesh1"などの絶対指定)で同一パスになるものは存在できません(これはUSDフォーマットの仕様)。

コンバートされた形状の内容

fbxの場合は、階層構造もUSDに渡ります。

Mesh自身は位置/回転/スケールのTransformを持っておらず、
Meshの親としてXformを割り当ててそこにTransformを持たせているようでした。

マテリアル

マテリアルはLooks内に格納されていました。
fbxからusdにコンバートしてインポートした場合は、すべてOmniPBRで指定されています。

テクスチャは、このOmniPBRのAlbedo Map/Roughness Map/Metallic Map/Ambient Occlusion Map/Normal Mapなどにドラッグして持っていきました。

Color Spaceの指定

テクスチャを割り当てた場合、各Color Spaceの指定はかなり重要です。
fbxからusdにコンバートした場合はすべてautoになっているため、ここは個々にチェックしていきます。

AlbedoのColor Spaceは、autoのままでOKです。sRGBが割り当てられています。

ReflectivityのRoughness/MetallicののColor Spaceは、autoのままでOKです。
sRGBが割り当てられています。

Ambient OcclusionのColor Spaceは、autoのままでOKです。sRGBが割り当てられています。

ただし、AOについてはOmniverseでのRTX Path-Tracedではあまり意味がない/必要がないかもしれません。
(パストレーシングで間接照明も正しく回り込んでいるため)
AOは、わずかなエフェクト的な利用になりそうな気がしています。

Normal MapのColor Spaceは、rawを指定します。

Normal Mapだけ、autoではない点に注意してください。

Normal Mapの凸凹の向きについて

Normal Mapの凸凹が逆転している場合は、「Normal Map Flip V Tangent」チェックボックスのOn/Offを切り替えます。

マテリアルでUSD標準のUsdPreviewSurfaceを使ってもよいか

Omniverse上では、UsdPreviewSurfaceは使わないほうがいいと思われます。

USDの標準では、マテリアルはUsdPreviewSurfaceが割り当てられます。
OmniPBRやOmniSurfaceはNVIDIA社のMDLを使った拡張になります。
そのため、おそらく現状はOmniPBRやOmniSurfaceはOmniverse以外では使えません。
他のDCCツールでUSDエクスポート対応していても、
マテリアルではUsdPreviewSurfaceのみを使っていると思います(Omniverse対応をうたっていない限り)。

しかし、UsdPreviewSurfaceの場合は以下の問題があります。

  • 透過の場合の屈折表現ができない (Transmission/Glass系のパラメータを持たないため)
  • Normal Mapでrawが指定できないため、凸凹が正しく表現できていない。そのため、境界部が見えたりする。

内部的な構造はもっと複雑な問題(UVを使ったタイリング指定など)があります。
これらよりOmniverse上のマテリアルでは基本的にはOmniPBRを使う、
ガラスのような透過と屈折が入る場合はOmniGlassを使う、としたほうがいいと思われます。

Omniverse Create 2021.3以降は、OmniSurfaceを使うと
非透過の場合とガラスのような透過、Transmissionでの透過時の減衰、SSSなど、
より高い表現が1つのShaderで指定できるようになります。

取り急ぎになりますが、現在のOmniverse Create 2021.3.3で
usdでないfbxなどで形状をインポートする場合の覚書でした。
バージョンアップすると仕様が変わるかもしれないため、あくまで参考としてご参照くださいませ。