Visual Effect Graphで点群表示 | Point Cacheファイルの作り方

UnityVisual Effect Graph(VFX Graph)で点群(ポイントクラウド)を読み込もう!

結構つまづいたところがあったのでまとめてみました。

  • この記事で扱う点群はレーザースキャン、3Dスキャナー等で取られた静的な点群データですReal Sense等を使った動的な点群ではありません。
  • 主にpcacheファイルの作り方をまとめた記事です。もう作れてる、持ってる人は記事の最後のVFX Graph設定の項目までとんじゃってください。

◆ 大きな流れ

ざっくり以下の流れになります。

  1. 点群データをVFX Graph用のPoint Cacheファイルに変換する
  2. VFX GraphでPoint Cacheを読み込み

その前に―

Point Cacheファイルとは?

座標とそれに紐づく色情報等を持ったVFX Graph用のフォーマットです。
拡張子は.pcache。

アスキーデータとバイナリデータと両方扱えます。
(巨大なデータな場合はバイナリで作った方が読み込みも描画も軽快になると思います。多分。ここではアスキーデータの作り方を説明していきます)

いくつかサンプルデータを覗いてみたところ以下のような構成となっていました。

PointCacheFormat

3つのファイルのヘッダーです。
座標 / 色 / ベクトル / 法線等が持てるようです。

end_header以下はpropertyにあるデータが続いているのですが、
なんと点群データと同じフォーマット。

なので点群データのヘッダーを書き換えることでPointCacheファイルが完成。
VFX Graphで読めてしまいます。

しかしPointCacheファイル作る上でいくつか注意点があったので以下に詳しく記していきます。

環境

  • Windows10
  • Unity 2019.1.0f2
  • Visual Effect Graph 5.8.2 (preview)
  • 点群データ:渋谷駅地下3Dデータ©3D City Experience Lab. https://3dcel.com/opendata/
    28,624,242点の約1.5GBのデータ

◆ 1. 点群データをPointCacheファイルに変換

点群データ編集にはCloudCompareを使用します。
変換したい点群ファイルを読み込むと―

・アスキーファイルの場合

以下の画面が表示されます。

CloudCompareAsciiFile
今回は座標とカラーのみを使うのでスカラーの行は[Ignore]とし破棄。
(不要なデータは破棄してデータを軽くします)

・Plyファイルを読み込ませた場合

以下の画面が出ます。

CloudComparePlyFile
この場合も同様に、不要なNxNyNzのデータは[None]にし破棄します。

データが読み込まれると次に以下の画面が出ます。

CloudCompareGlobalShiftScale

点群の配置位置とスケールを調整する画面ですが、点群の中心座標を確認してから調整したいのでここでは[No]とします。

上記の例ではxが-11,986となっているので後ほど座標をシフトして絶対座標0,0,0の位置へ持ってきます(11kmも遥か遠くにあるのは不便なので直します)

また、点の座標が65,536以上になっているとVFX Graphでノードを接続した際にノードの一部が変色します。
VFXGraphNodeErr65536
エディタのバグ?ノードの所々が緑っぽくなった。一応処理は通ってるようですが、あやしいので65,536未満にしておくのが良さそうな気配

話を戻して―
ファイルが開かれると以下の画面になります。

CloudCompareEdit

点群を選択し、左下の[Box dimensions]と[Box center]を確認します。

Box dimensions:点群全体のサイズ(幅/奥行き/高さ)
Box center:点群の中心の絶対座標

dimensionsのXの値は約409という事で(Unityでは409m)スケールは間違ってなさそうなのでこのままで良さそうです。

centerの方は原点から大きく外れた位置(Unityでは11km遠方)になっているので、調整します。

Menu > Edit > Edit global shift and scale で、下記画像右側のウィンドウが開かれます。

CloudCompareGlobalShiftAndScale

このShiftの欄にBox centerの値をそのまま入れます。
(上記の例ではZの値は調整は不要そうでしたので0のままです)
スケールがおかしかった場合はここでスケールも調整します。

入力したら[Yes]で閉じ、
最後にデータを書き出します。
点群データを選択した状態で左上の保存アイコンをクリックです。

CloudCompareAsciiSave

ASCII cloudを選択し、ファイル名にこの時点でPointCloud用の拡張子「.pcache」を付けてしまいます。

[保存]を押すと次の画面が表示されます。

CloudCompareAsciiSaveOption

coordinates precision
データの精度です。小数点以下の桁数なので必要に応じて設定しますが、データ容量削減のためここでは4としました。

Save colors as float value (0-1)
これは必須です。
PointCacheはRGBを 0-255 ではなく 0-1 で扱います。
点群は0-255で保存されている事が多いので、このチェックを入れ0-1に変換します。

データサイズの確認

UnityのPointCacheはどうやらファイルサイズが1,048,576KBを超えると読み込めないようです。

PointCacheMaxSize
↑Sample_010405が読み込めていない例

なのでまずファイルを書き出した時点でサイズを確認しておきます。
オーバーしていた場合はファイルを分割するか点群を間引きましょう。

ヘッダーの編集

データが用意できたら次にpcache用のヘッダーを追加します。
容量によってはメモ帳では開けないので、Visual StudioEmEditorを使います。

2000万行の場合Visual Studioでは5分かかりましたがEmEditorでは7秒で開けました。巨大なファイルを扱う場合はEmEditorおすすめです。

PointCacheのヘッダーのフォーマットは以下の通りです。

pcache
format ascii 1.0

comment Exported from CloudCompare

elements 20000000
property float position.x

property float position.y

property float position.z

property float color.x

property float color.y

property float color.z

end_header

elements
ここは点の総数(行数)なので適宜書き換えてください。

property float position
Unity用にyzを入れ替えておく必要があります。
CloudCompareからはZアップで書き出されているので以下の様にYアップにします。

PointCacheEdit
(もしくはCloudCompareで点群を読み込む時点でZとYを入れ替えておいても良いです)

以上でPointCacheデータの完成です!

◆ 2. VFX Graphでpcacheを読み込む

ここからは簡単です。

VFXGraphCreateNode
余白で右クリックから[Create Node]

VFXGraphCreatePointCacheNode
[Point Cache]を選択。

VFXGraphPointCacheNode
出来たPoint Cacheノードに作成したpcacheファイルを指定し、
こんな具合に接続し、完成です!

表示されない場合

  • InitializeBoundsSizeを十分大きな値にしましょう。
    Boundsのボックスが視界に入っていないと描画されません。
  • Quad OutputSizeを大きくしてから見回してみましょう。
    小さすぎて見つからないだけの場合もあります。
  • シンプルなpcacheファイルを作ってテストしましょう。
    表示されるのを確認してから本番用pcacheに差し替えるのが間違いなさそう。
    私は初めこんなデータ作ってテストしてました。
pcache

format ascii 1.0

comment Test

elements 8

property float position.x

property float position.y

property float position.z

property float color.x

property float color.y

property float color.z

end_header

-0.5 0.3 -0.2 0.2 1 1

0.3 -0.5 0.2 1 0.2 1

0.5 0.4 -0.1 1 0.4 1

-0.1 0.5 0.5 1 0.2 1

-0.4 -0.5 0.2 1 1 1

-0.3 0.4 0.5 0.2 0.2 0.1

-0.5 0.4 0.2 1 1 1

0.5 -0.3 -0.3 1 1 1

以上!

以上ですおつかれさまでした!
あとはお好みで点群VFXしちゃいましょう!