先日Three.jsをちょっぴり触る機会があったので備忘録として。
glTFってなんじゃらほいって方がいらっしゃったら
今話題の3Dファイル形式「glTF」でWebGLの表現力を高めよう!
【マイクロソフトも乗り気な「glTF」って知ってますか ~ glTF と WebGL 最新事情】西川善司です。マイクロソフトのマルチメディアコンポーネント API…
この辺をお読みいただくのが良いかと思います。僕も詳しいことはよく分かっとらんのですが
「今後の業界標準になりそう」な雰囲気だけは何となく掴めたので採用してみました。
今回、glTFに変換する前の3DデータはFBX形式でした。
FBXをglTF形式に変換する際は
こちらを参考にさせていただきました。
モデル自体にアニメーションはありませんでしたが
・元が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