Three.jsを使ってDRACO圧縮したglTF形式の3Dモデルを読み込むメモ

先日Three.jsをちょっぴり触る機会があったので備忘録として。

glTFってなんじゃらほいって方がいらっしゃったら

今話題の3Dファイル形式「glTF」でWebGLの表現力を高めよう!

【マイクロソフトも乗り気な「glTF」って知ってますか ~ glTF と WebGL 最新事情】西川善司です。マイクロソフトのマルチメディアコンポーネント API…

Microsoft ExpertZoneさんの投稿 2017年9月29日金曜日

 

この辺をお読みいただくのが良いかと思います。僕も詳しいことはよく分かっとらんのですが

「今後の業界標準になりそう」な雰囲気だけは何となく掴めたので採用してみました。

 

今回、glTFに変換する前の3DデータはFBX形式でした。

FBXをglTF形式に変換する際は

BlenderでFBX形式をglTF形式に変換してThree.jsでアニメーションさせる (1/2)

 

こちらを参考にさせていただきました。

モデル自体にアニメーションはありませんでしたが

・元がFBX
・glTFに変換したい
・その後Three.jsでゴニョゴニョする

という点が一致したので非常に分かり易かったです。

Blenderを使うのも初めてだったのですが、色々機能が豊富すぎて自分の場合は

まだまだ変換ツールとしてしか認識できておりません。

 

さて、上記サイト様を参考にBlenderからglTF形式で出力する時、.glTFと.glbを選択出来るかと思いますが

.glTFで出力すると

tamane.gltf // glTFファイル
  tamane.bin  // 頂点データ

のように2つファイルが出力されます。(テクスチャ画像のないデータの例ですが)

これでも普通にThree.jsでモデルの表示自体は出来るのですがglTFLoader.jsの

new THREE.GLTFLoaderクラスで生成されるインスタンスの

loaderメソッドの第3引数onProgressコールバック関数を用いて

lengthComputableプロパティ経由でダウンロード画面とかを作る時に、

上記の.glTFファイルを読み込んだ時点でダウンロードが完了した事になってしまい

実際はまだ.binファイルのダウンロードが終わっていないみたいな挙動になってしまいました。

それを避けるのと、ファイル管理は少ない方がやはり楽なので今回は.glb形式で出力することに。

 

本題のDRACO圧縮ですが、glTF 2.0の拡張仕様があるようなのでそちらを利用してみようと思います。

ツールはnpmのgltf-pipelineを利用するとお手軽に圧縮できます。

別にglTFではなく.drcとして出力する場合は、こちらのサイト様が分かりやすく圧縮方法を解説されています。

 

あんまり理屈ばっかり先行してもアレなので、こちらがデモになります。

コードはこんな感じですね。


フリーで使えるFBXモデルをお借りして(良い時代ですね)

・元のサイズ               770kb
・.glbに変換              1200kb
・DRACOで圧縮(glTF拡張)    190kb

とサイズダウンに成功しました。

圧縮されたから頂点数が減ったりとか、そういうのは無さそうです。

 

確かにモデルデータの容量圧縮効果は顕著なのですが、挙動を見ると、190kbとはいえ

表示されるまでに微妙なタイムラグがあります。

これは何故なのだろうと少し調べてみると、

どうやら圧縮されたモデルを解析しパースするまでに時間を要しているよう。

その辺を解決するのがWebAssembly製のデコーダーだったり、

あとはモデルデータが大きくなるとパースにかかる時間も比例するようなので

その処理をWeb Workerへ逃がしたり、など色々やりようがあるみたいです。

 

すごいですなぁ〜。

 

WebAssembly を利用することで高速で軽快な動作を実現した Unity WebGL Player 製のブラウザゲーム Tanks!

https://webgl.souhonzan.org/entry/?v=1311

Webでどこまで遊べるか試してみた
https://qiita.com/Leonardo-mbc/items/3c365836acfd71a55185