Tech Sketch Bucket of Technical Chips by TIS Inc.

Three.jsで3Dスキャンデータを活用する

Pocket

以前の記事で3DScanしたデータをExportして利用をしたい。
3Dモデルの利用方法は幅広くありそうですが、今回はThree.jsを用いてWebGLを利用してブラウザ上で表示できるようにしてみます。


全体的な流れ

以下のような流れで表示します。

  1. KScan3DからモデルデータのExport
  2. Blenderでply形式のモデルをJSONModelに変換
  3. Three.jsを用いて画面に表示する

3Dスキャンを試してみたよ1 で作成した椅子のモデルを若干修正して見栄えをよくしたものを利用します。
capture.png

3Dスキャンされたデータ

今回の記事で利用したバージョンは以下です。

KScan3DからモデルデータをExport

KScan3DからデータをExportします(要ライセンス$299)。KScan3Dのドキュメントによると これらのフォーマット で出力できますが、以下の理由でplyでExportしました。

  • VertexColorの出力に対応している
  • BlenderにImport可能なのでフォーマットの変換が可能

この2点の理由を満たすことで、表示される3Dモデルに3Dスキャン結果の色が反映され、かつThree.jsで利用しやすい形に変換するためにblenderで変換をすることが出来ます。
またExport時にはSettingのMeshExport内の RecenterとFlip Verticalにチェック を入れておきます。
入れないと表示時にモデルが妙な位置に表示されたり、逆さに表示されたりします。

Export時にはモデルデータの容量に気を配る必要があります。
何も考えずに最高品質でExportなどをすると、最終的にユーザがブラウザで取得しなければならない3Dモデルの容量が100MB以上になることもありえます。
ブラウザで取り扱える程度のデータ量にしてあげましょう。

今回の記事で利用するモデルは36590頂点、72261面で、ply形式で1454kb、最終的にブラウザにダウンロードされるJSONModelに変換した時点で3387kbです。
この程度であれば昨今のネットワーク環境であれば大丈夫であろうと期待してみます。

BlenderでExportされたモデルをJSONModelに変換

Three.jsでは一部のモデルデータは直接扱えるようですが、どんなファイルも簡単にでるというほど楽には出来ませんでした。そこで、この記事の中ではThree.jsで取扱いやすい JSON Model Format に変換したうえで画面表示に利用します。

BlenderとAddonのインストール

blenderをインストールしてThree.jsに付属する Importer/ExporterのAddon を追加します。
Addonの追加手順は@ITの 多彩な表現力のWebGLを扱いやすくする「Three.js」 を参考にしてください。

plyのImportとJSONModelでのExport

特筆するほどのことは無いですが、blenderでplyのImportをして、three.jsでexportすればOKです。
export時にはVertex、Faces、Colors、Materialsにチェックが入っていれば多分大丈夫です。
以下の画面キャプチャが出力時の設定です。

blender_export.jpg

Exportした情報は整形されているJSONなので適当なテキストエディタで中身が確認できます。
点、色、面の数などがなんとなく読み取れます。

Three.jsで読み込む

ここまでで作成したデータを読み込みます。
実際に動作するページへのリンクは こちら。

表示のためのエッセンスだけ抜粋して見ます。

Rendererの種類

Three.jsではWebGLによるレンダリングとCanvasによるレンダリングが可能です。
おおむね、同じものが表示できる場合に性能は圧倒的にWebGLによるレンダリング、マルチブラウザ対応ではCanvasによるレンダリングのほうがよい感じです。

ただし、同じものが正しくレンダリングできない場合があります。今回の3DScanデータはVertexColorでモデルの色を保持していますが、CanvasRendererではVertexColorを有効にする設定は無視されると ドキュメント 上記載されています。

そのため、今回のモデルデータの表示にはWebGLを利用します。IEはWebGLに対応していないためChromeかFirefoxで動作のページを開いてください。
ちなみに、強引にCanvasRendererを用いて描画することも出来ます。以下のようながっかりな状態になります。

canvas_renderer.jpg

CanvasRendererで描画した結果

ちなみに、表示ががっかりなだけではなく、画面の更新速度も2-3FPSしか達成できないため椅子を回したりする操作も大変です。

正しくWebGLレンダラーを用いれば以下のように描画されます。
webgl_renderer.jpg

WebGLRendererで描画した結果

こちらは期待通りに動作します。

モデルの読み込み

モデルの読み込みは以下のようなコードで実施しました。

モデルをJSONLoaderで読み込んで読み込み完了後からanimate()が実行されるようにしています。
今回はここまでの手順でモデルをJSONModelに変換しているので問題なく表示できています。

表示可能なモデルに変換するために

Kscan3Dを利用して作成した3DScan結果とほぼ同一の状態をブラウザ上で表示することが出来ました。

しかし、KScan3DやThree.jsの制限でハマリポイントがいくつかあったので紹介します。

  • KScan3Dの制限
    • テクスチャ出力できない
      通常3Dモデルで色や質感を再現するにはテクスチャが利用されますが、今回はVertexColorを用いました。
      これはKScan3DのExport時の制限で、複数の方向から撮影した3DScanデータをExportする際にはTextureを出力することが出来ません。
    • Exportされたデータがバイナリデータ
      Three.jsのexample/jsの中にはOBJMTLLoader.jsやSTLLoader.jsなど一般的な3Dモデルデータを読み込めそうなスクリプトが配置されていますがKScan3DでExportしたものをそのまま読み出せないようです。
      KScan3Dからstl形式でExportしたデータについて確認してみましたが、内部はバイナリデータで出力されているようです。
      一方、Three.jsのExampleに含まれるstlのデータを表示するサンプルではstl形式のデータはテキストデータでした。
      このようにファイルの内部の構造などのせいかコンバートを適切に実施する必要があります。
      そのため今回はThree.jsが確実に読み込めるJSONModelに変換した上で読み込んでいます。
      コンバートには記事内でも利用したBlenderや MeshLab を利用することができます。
    • ファイルサイズ
      ここまででも一度触れていますが、ファイルサイズを意識した変換が非常に重要です。
      何も考えないと読み込ませただけでブラウザがクラッシュするファイルサイズになります。
      かといって、ファイルサイズを下げるために3DScanしたデータを安易に間引きしてExportさせるとモデルデータが見るに耐えない状態になります。
      Finalize時に頂点数を指定するなどのパラメータ調整をしたデータを作成し、Exportする必要があるでしょう。
  • Three.jsの制限
    • ブラウザの制限
      どうしようもないことですが現在のところIEではWebGLを利用できません。
      ChromeやFirefoxで閲覧してください。
    • ハードウェアの制限
      またChromeやFirefoxでもGPUが無い場合は表示できません。
    • なぜか動かないことがある
      時々今まで動いてたのに、動かなくなった!ということがあります。理由は分かりませんが初期化に失敗していて、ブラウザごと再起動すれば復帰します。

まとめ

というわけで、3DScanしたデータをブラウザで表示することが出来ました。

3Dスキャンしたデータはファイルサイズやフォーマットの制約などがあるため、今回の記事のようにファイルサイズの削減やフォーマットの変換などを実施しなければなりませんが、実際に存在するものを3DデータとしてWebに持ち込めるのは非常に面白いと思います。

エンジニア採用中!私たちと一緒に働いてみませんか?