[Omniverse] PLATEAUのfbxとobjを見る/Meshの最適化

  • by

OmniverseにPLATEAUの3D都市データをインポートした際に、この場合は効率が悪い/良い、が発見できたのでまとめておきます。

結論を言うと、fbxは使わずにobjを使いました。

ここでの確認はOmniverse Create 2022.1.3を使用しています。

PLATEAUの3D都市データをobj/fbxで読み込む場合の違い

PLATEAU( https://www.mlit.go.jp/plateau/ )のオリジナルのデータはCityGMLで格納されています。
これをfbxやobjに変換したものが、「G空間情報センター」( https://www.geospatial.jp/ckan/dataset/plateau )で公開されています。
もちろん、CityGMLのデータもダウンロードできます。

ここでは、ダウンロードできるfbxとobjで同じ地域メッシュの建物をOmniverseに読み込み、どのような構成になっているか見ていきます。

533925xxのLOD1の建物(bldg)をUSDに変換してからOmniverseに読み込みました。

obj形式

13100_tokyo23-ku_2020_obj_3_op/bldg/lod1/533925*_bldg_6677.objをusdに変換して読み込みました。
2次メッシュの範囲になります。
読み込みの建物は3次メッシュごとあります(ない箇所もある)。

LOD1なのでテクスチャは貼られていません。
また、マテリアルは割り当てられていません。
objからusdに変換したときのファイルをReferenceとして参照しています。

参照した1つ1つは、
Translate (0, 0, 0)
Orient (-90, 0, 0)
Scale (100, 100, 100)
としています。

これは、PLATEAUのobjがメートル単位でZ-Upとなっているのを、
Omniverse(USD)のデフォルトのセンチメートル単位でY-Upに置き換えています。

3次メッシュごとのLOD1の建物は、1Meshで構成されています。

このときのMesh数や三角形数/頂点数を
Windows-Utilities-Statisticsで確認します。
RTX Sceneを見ました。

項目名
Mesh数 (Meshes) 31
三角形数 (Triangles for all unique meshes) 2,047,172
頂点数 (Vertices for all unique meshes) 1,225,807

これをusdファイルに保存すると、5.28KBになりました(ジオメトリのMeshは別usdに保持されているので軽い)。

このときのOmniverse Kitのメモリ使用量 : 3341 MB
GPUのメモリ使用量 : 3.2 GB

一度usdを保存し、Omniverse Createを再起動して読み込むときの読み込み時間は、1秒かからず。

fbx形式

13100_tokyo23-ku_2020_fbx_3_op/bldg/lod1/533925*_bldg_6677.fbxをusdに変換して読み込みました。
2次メッシュの範囲になります。
読み込みの建物は3次メッシュごとあります(ない箇所もある)。

建物自体はobjをusd変換してインポートした場合と同じです。

Stageで構成を見てみると、53392546_bldg_6677内は(USDでは名前の先頭は数字は指定できないので_3392546_bldg_6677となっている)
複数のMeshで構成されているのが分かります。


これは、建物1つ1つがMeshになっています。

このときのMesh数や三角形数/頂点数を
Windows-Utilities-Statisticsで確認します。
RTX Sceneを見ました。

項目名
Mesh数 (Meshes) 98,017
三角形数 (Triangles for all unique meshes) 1,982,136
頂点数 (Vertices for all unique meshes) 1,186,746

これをusdファイルに保存すると、7.22KBになりました(ジオメトリのMeshは別usdに保持されているので軽い)。

このときのOmniverse Kitのメモリ使用量 : 10055 MB
GPUのメモリ使用量 : 5.1 GB

一度usdを保存し、Omniverse Createを再起動して読み込むときの読み込み時間は、29秒。

objとfbxで比較

objとfbxで比較すると、
Mesh数は31 → 98,017、と膨大に増えてます。
三角形数は2,047,172 → 1,982,136 と少し減りました。
頂点数は1,225,807 → 1,186,746 と少し減りました。

Omniverse Kitのメモリ使用量は 3341 MB → 10055 MB
GPUのメモリ使用量は 3.2 GB → 5.1 GB

usdの読み込み時間は 1秒以下 → 29秒。

と、fbxの構成を読み込んだほうがかなりレスポンスが落ちます。
これはfbxが悪いというわけではありません。
Mesh数が増えると、たとえ1つ1つが単純な直方体でもメモリの使用量や読み込み時間で無駄が出てしまう、ということのようです。

LOD1の2次メッシュ領域1つ分でこのような感じなので、東京23区だと全体で14個あるのでかなり無駄が出るのが分かるかと思います。

ではどうすればよいのか ?

PLATEAUのfbxをusdに変換する際に、「Merge Static Meshes」チェックボックスをOnにしてusd変換します。

こうすると、以下のように1Meshにまとまりました。

これで、obj使用時と同じMesh数にできます。

LOD1時はなんでもかんでも1Meshにマージしたほうがよい ?

建物は動かないため、Staticとして3次メッシュごとに1Meshにマージしてしまう(objの場合はそうなってしまっている)、が正義とは限りません。
PLATEAUのfbx/objはあくまでCityGMLから変換されたデータである、ということを思い出しましょう。

LOD2の建物は、建物ごとに存在する場合と存在しない場合あります。
そのため、LOD1とLOD2を完全に同じStageに歯抜けな状態にならないように乗せたい場合は、
3次メッシュごとにLOD2の建物がない箇所だけをLOD1の建物を使用、とする必要があります。
この場合は、CityGMLの属性を見る必要が出てきます。

もしくは、fbxから変換したusdを使用する場合、
LOD1/LOD2の両方をいったん読み込んでMesh名が同一のものがあるかチェック(UUIDで判断できます)。

もし同一のものが存在する場合はLOD1のその建物のMeshは不要なので削除し、残ったLOD1の建物を1Meshにマージ、がスマートかもしれません。

まとめ

以上から分かることは、
Mesh数が増えたとき、マージできる場合はマージしたほうがよいというのが分かりました。
木などのような複製とTransform(移動/回転/スケール)で対処できる場合は
前回説明していた「Paint Tool」(USDではPointInstancer)を使うのが良いと思います。

建物を位置/回転/スケールで表現できる場合でも、PointInstancerを使ってスクリプトで建物群を構築するのもいいかもしれません。
OmniverseというかUSDで大量の形状を配置するというトリックは、PointInstancerをどう使うかというのにかかっているのかな、と個人的には思っています。

参照(Reference)を使って同一形状を大量に配置した場合と
PointInstancerのリソースの比較はまだできていないため、
これは後々調べる予定です。

PLATEAUはいい負荷検証になりますね。