Webで使うために GLTF / GLB ファイルをDraco圧縮する

近年、JSを使ってWebでCG表現を行う手法は大きな発展をしています。

ブラウザ上で AR や VR などを用いたWebアプリを開発できるようになってきました。

しかし、問題となるのが3Dモデルのファイルサイズです。

GLTFなどの3DモデルはWeb上で扱うには非常にサイズが大きく、ダウンロードに大きな時間がかかってしまいます。

そこでGoogleが開発してGLTFが拡張機能として採用したDracoというオープンソースの3Dデータ圧縮方式を用いて圧縮することで、ファイルサイズを縮小します。

実は前日にGLTFを圧縮しようとしていたのですが、勘違いで昨日書いた記事の方法ではGLTFをdraco圧縮できないことに2時間くらい作業した後で気づきました。

日曜日の深夜の時間を無駄遣いしたとなれば、精神的に平日の4時間くらいを無駄にした気分です。
昨日書いた記事 .objや.plyファイルはdraco圧縮できるのですが、.gltfや.glbはできないのです。
https://codelabo.com/posts/20200830183755

Node.jsのインストール

Node.jsのサイトにアクセスして、インストーラをダウンロードします。

https://nodejs.org/ja/

特に必要性が無ければLTSと書かれた推奨版をダウンロードしましょう(現時点でバージョンv12.18.3)。

Next連打でインストール完了です。

コマンドプロンプトを開いて、

node -v

と入力して

v12.18.3

の様に表示されたら成功です。

GLTFファイルを圧縮する

使用するツールはgltf-pipelineです。
公式のGithubページに使い方が記載されてます。

https://github.com/CesiumGS/gltf-pipeline

Node.jsを使ってインストールします。

npm install -g gltf-pipeline

使い方としては

gltf-pipeline -i model.gltf -o modelDraco.gltf -d

もしくは

gltf-pipeline -i model.glb -o modelDraco.glb -d

の様に使います。 model.glb(.gltf)が圧縮前の入力ファイル。modelDraco.glb(.gltf)が圧縮した出力ファイルです。

どのくらい圧縮できるの?

普通のVroidから出力したファイルで試してみる

例として以下のglbファイルを圧縮してみました。
https://github.com/yosipy/GLTF-File-Size-Test/blob/master/export_p16848_m02_b103/glb/no0.glb

頂点数が16848個で、スキニングにも対応しているデータなのでそれなりに大きいです。

      static media      2020 08 31 235550

圧縮後のファイルがこちら
https://github.com/yosipy/GLTF-File-Size-Test/blob/master/export_p16848_m02_b103/draco/no0.glb

圧縮コマンド

gltf-pipeline -i glb/no0.glb -o draco/no0.glb -d

10.8MBから5.38MBまで減りました!

圧縮前の.glbを.gltfに変換したものが同じ10.8MBであることを考えれば、頂点などの配列のみでなくテクスチャもかなり圧縮されていると思われます。 (頂点などの配列データが入ったno0_data.binは2.91MBしかないため)

圧縮前の.glbを.gltfに変換したもの
https://github.com/yosipy/GLTF-File-Size-Test/tree/master/export_p16848_m02_b103/gltf

頂点がどのくらい圧縮されているか確認するために画像をすべて1px x 1pxにします。

https://github.com/yosipy/GLTF-File-Size-Test/tree/master/texture_1px_(exportp16848m02_b103)

このgltfフォルダの中の画像はすべて1x1pxにしています。

1つあたり120KBなので無視します。

それを以下のコマンドでdraco圧縮しつつ、.gltfから.glbに変換します。

gltf-pipeline -i gltf/no0.gltf -o draco/no0.glb -d

結果として、3.00MBから2.3MBとなりました。

公式の.objを使った例では圧縮前のbunny_norm.objは4.7MB、圧縮後は64KBくらいのインパクトある感じの圧縮でしたので、想定よりもサイズが大きかったのは事実です。
https://codelabo.com/posts/20200830183755

OBJ形式と違ってGLTFはかなり広い表現ができる仕様なので、さすがにこのあたりが限界ですか(でも、もうちょっと小さくなる気がしてしまう。。。)

Draco圧縮レベルをMAXの10にしてもほとんど変化しませんでした。

それでもこれだけのデータが2MBちょっとにまでなるのはすごいです。テクスチャを入れて3~4MBくらいに落とせれば、実用的にWebで使っていけると思います。

まとめ

今回はGLTFファイルをdraco圧縮しました。

OBJに比べると圧縮率は低めみたいな感じがするので、スキニングの無い(ボーンの無い)モデルなどはOBJやPLYファイルにした方がいいかもしれません。 (設定不足なだけかもしれませんが)

もう少しパラメータをいじって、ファイルサイズを小さくする考察をしてみたいです。