Ito実際にQuestで動作するapkファイルもアップロードしてあるので、インストールして実際に試すことも可能です。そもそも点群データとは点群データとは、LiDARなどのセンサーによって撮影された、空間上の点の情報をまとめた3Dデータです。ptsなどが代表的な拡張子です。B)の6パラメータが基本の構成要素で、それに加え、スカラー情報と呼ばれる反射率や法線ベクトルなどの情報を含むこともあります。平面(ポリゴン)とテクスチャで構成されるメッシュデータと比べ、それぞれが独立した点の情報だけで構成されており、センサーから取得できる生データに近いので、多くの場合精度に優れているという特徴があります。公開されているデータを描画していきます。静岡県PCDBそれぞれの地点で、こんな感じでlasという拡張子のデータをダウンロードすることができます。今回は、家にこもってばかりでそろそろ自然に触れたい!ということで、日本三大名瀑に選ばれることもあるという、白糸の滝のデータをダウンロードします。点群データの下処理さて、VRで点群表示するために、まずは点群データをUnityで読みやすい形式に変換する必要があります。そのためには、CloudCompareというソフトを使います。CloudCompareをCUIから使うCloudCompareは点群データの処理に特化したオープンソースのフリーソフトです。www.danielgm.netおもむろにアプリをインストールし、先ほどダウンロードしたlasデータを読み込むと、こんな感じに可視化してくれます。川の流れに沿って両岸が立体化されている様子がわかりますね。CloudCompare、上記のようにGUIでも操作できるのですが、今回は・パラメータなどを変えて試行錯誤しやすい・重いファイルを扱うときに、GUIだとアプリが落ちてしまいやすいという理由から、ターミナルでCUIとして使う方法で使っていきます。(下記はMacOSの場合。環境によって違うと思うので各自で探してください。点群を距離に応じて間引き(SubSample)。保存する際の小数点の精度(m)。今回は0.001m(1mm)まで残すようにしている。ファイル名を指定して保存subsample.sh今回は、公式ドキュメントを見ながらこんな感じのシェルスクリプトを書きました。・ASCデータで保存という一連の処理をまとめて記述したものです。大事なのはSubSampleで、かんたんにいうと「閾値以上に距離が近い点たちをマージして全体の点の数を減らす」という処理なのですが、この閾値を大きくすると、ファイル容量や読み込みスピードがかなり軽くなる一方で出来上がりの見た目がスカスカでショボくなってしまうので、試行錯誤する際はまずSubSampleのパラメータを変えてみるのがいいと思います。今回、Unityエディタ上で見たときは、0.1くらいが見栄えのバランスなどちょうどよかったのですが、VRで見たときにややフレーム落ちが気になったので、0.2を最終的な値として使っています。点群データを変換してみるということで、このスクリプトを実施すると、上記のようなログが出力されます。各ファイルに、600万点の点群が記載されており、SubSampleしたことで85万点くらいに削減されていることが分かります。ファイルサイズ的にも、約600MBから27.2MBまで減っていますね。あたらしく生成されたファイルの中身は以下のようになっています。B]の順で85万行ずらっと並んでいるという、非常にシンプルなファイル形式です。Bufferを利用し初期化以外は極力GPUで実行できるように実装しています。}}PtsReader.cs点群読み込み用のクラスです。Vector3>のListとして返します。27.2MBの読み込みで15秒くらい時間がかかってしまうので、非同期で返すようにしています。(ちなみにFetchよりParseのほうにボトルネックがあるようです。良い解決策を思いつく方はコメントいただけますと嬉しいです。https://github.com/jujunjun110/PointCloudVR}PointCloudLoaderこちらのクラスでは、読み込んだ点群データを扱います。colbufferという名前でメモリ領域にVector3の配列の形でデータを書き込んでいます。CPUが点群データに触るのは、ここの1回だけで、それ以降は基本的にShader(GPU)の側でよしなに描画されることになります。バッファへの書き込みが完了したあとは、OnRenderObjectメソッドで、GameObjectやMeshRendererを使わない形でGPUに直接レンダリング命令を出しています。ここでMeshTopology.Pointsを渡すことで、Unityデフォルトのメッシュ描画モードではなく、頂点描画モードでのレンダリングが実行されます。(詳細)またここで頂点の個数を渡すことで、Shader側で頂点に一つ一つ順番にアクセスする処理が可能になっています。ピクセルごとに異なるスクリーン座標が渡されてくる。同じ四角形の中では必ず同じ座標(四角形の中心)が渡されてくる。}}PointCloud.shader最後に、メモリ領域に読み込んだ頂点・色のバッファを円の形で表示するShaderです。1);のような形でバッファに格納したデータを取得しています。shaderに値を渡す際に、POSITIONセマンティクスとTEXCOORDセマンティクス(何でも良い)の2つの変数でスクリーンポジションを渡すことにより、各点を円の形にクリッピングしています。(詳細はコード内のコメント参照)Unityで実行!上記のコードを実行した結果が以下です!いい感じに点群が表示されていますね。いい景色!インスペクタから、点群のサイズを変更することもできます。点群そのもののサイズ(正方形1辺の長さ)と、それを円でクロップする半径を別々に変数にしているので、点群サイズと半径を近づけると、点の形状が四角形に近づいていくのも確認できます。VRで実行する最後に、VRで実行してみましょう。シーンにコピーすることで、すぐに試すことができます。これは本当の話なんですが、僕はあまりにいい景色すぎて、初めてうまく動いた際に思わずデバッグを止めて魅入ってしまいました...!これまでの経験上、木や石などランダムでボコボコした形のものは、メッシュ化してもあまり綺麗にならず、それほど没入感が出ないなという印象だったのですが、点群データを使うとレーザーによる精密性の高い座標・色情報と、点群表現によるちょうどいい抽象化によって、息を呑むくらい美しい体験になっていると感じました。Questをお持ちの方には、ぜひ体験してほしいです!さらに点群ならではの演出を!最後に、さらに発展的な可能性について。点群データの一つの特徴として、一つひとつの点が独立して存在しているデータ形式のため、メッシュなどに比べて自由な演出がしやすいという要素があります。上記の映像は、点群の座標を計算するところの下記のたった1行を追加したものです。0.5;つまり、それぞれの点群との水平距離に応じて、各頂点を上下に動かしているだけなのですが、それだけで、同じシーンがとても不思議でユニークなものになっているのが感じられると思います。点群は、シンプルで軽量な表現だからこそ、演出の可能性は無限大だと感じました。・点群データを使った演出表現の可能性について書いてきました。この記事を書きながらあらためて、独立した点の集まりというシンプルなフォーマットゆえの、取り扱いの簡単さや演出の可能性の広さを感じました。今後VR・AR機器の演算能力が上がり、さらに大量の点群の描画も可能になれば、よりリアル寄りの表現も可能になるでしょうし、実際の場所に人が集まることのコストが非常に大きくなるアフターコロナ時代に、重要性が上がってくるフォーマットなのではないかと思いました。MESONでは、これからも点群を活用した表現や価値提供を研究していきたいと思います。特商法表記クリエイターへのお問い合わせフィードバッククリエイターの。