🐈

【WebGL/WebAR】テクスチャをWebPに変換するモデル圧縮術

2022/12/08に公開

こちらは、【STYLY主催】XR Advent Calendar 2022の記事となります!

はじめに

仕事柄、「フォトグラメトリでスキャンしたモデルを、WebARで表示したい」といった要件が多いです。
フォトグラメトリでスキャンしたデータというのは、基本的に容量が重いです。
WebARの有名なプラットフォームである8thwallによると、WebARに使うモデルの大きさは10MB以内が望ましいとのことで、10MBというのは結構なハードルです。。
実案件では結局10MBを超えてしまうことが多いのですが、それでも少しでも容量は削減したいでしょう。

モデルを削減する上で、基本的な考え方は二つで、

  • メッシュ/ポリゴンを削減する
  • テクスチャを軽くする

のどちらかです。
前者はDRACO圧縮、後者はBasis圧縮という手段があるのですが、詳細は以前私が書いた下記の記事をご確認ください。

https://zenn.dev/tanabee8/articles/fc40a20deebcbd

今回は、テクスチャを軽くする方向性についてもう少し簡単な方法はないか検討してみたいと思います。
結論を言えば、「glbのテクスチャをwebpに変えちゃおうぜ」 というお話です。

WebPとglb/glTF

WebPは、Web制作をされる方にとってはお馴染みの画像形式だと思います。
詳細は下記に詳しいです。要は「jpgとかpngより軽いやつなんだ〜」と思っておけばOKです。

https://developers.google.com/speed/webp

そして、WebPをglb/glTFで使っていいのか?という疑問がありますが、
glTF2.0でEXT_texture_webpという拡張機能で使用可能ならしく、
とりあえず仕様OKのようです。
いま流通しているglTFの多くはほとんど2.0のはず(例えばBlenderもglbをexportしたらglTF2.0で出力されます)なので、あまり意識せず利用できると思います。

https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Vendor/EXT_texture_webp/README.md

また、three.jsのGLTFLoaderはこの拡張機能をサポートしているので、まあとにかく大丈夫ってことです!

さらに、「ブラウザ側は大丈夫か」と心配になるのですが、
WebPはモダンブラウザでサポートされているので問題ないかと思います。

強いて言えば、Mobile safariはiOS14以上というところがもしかしたら引っかかるかも?
とはいえこの執筆時点でiOS16ですし、iOS13以下をサポートするような案件は少ないと思われます。

ということで、次は実践です。

テクスチャをWebPへ変換してみた

モデルの例として、私がフォトグラメトリを行ったこちらのモデルでテストしてみようと思います。
現時点で6MBあります。(この時点でそんなに重くないじゃねーか!というのは一旦置いてください。。)

glbからglTFへ変換

glbはバイナリデータなので、このままではテクスチャをいじれません。
なのでglTFへ変換します。
色々方法がありますが、私が以下のツールが好きです。
https://www.npmjs.com/package/gltf-import-export
これをnpmでグローバルインストールして、コマンドラインで使用します。

gltf-import-export f1.glb

すると以下のファイルに分解されました。テクスチャとgltfがでてきましたね。

テクスチャをWebPへ変換

変換手段は色々ありますが、オンライン上ならsquooshが一番シンプルで使いやすいと思います。
コマンドラインであればcwebpなど。
今回はsquooshを使用します。


こんな感じでWebPへ圧縮して、4.6MB→1.6MBになりました。

余談ですが、今回上記テクスチャが4kサイズでした。品質的に許されるのであれば、このタイミングで2kに縮小することによっても、画像の容量を軽くできると思います。
画像サイズはこの工程で小さくしてもモデルが壊れることはありません。もちろん画質はその分落ちてしまうので、案件毎の相談事項になりそうです。ちなみにサイズは2の冪乗サイズが望ましいです。

glTFファイルを書き換え

次に、glTFファイルを書き換えます。
エディターで開くと、次のような箇所が見つかると思います。ここの拡張子を変更しましょう。
jpgからwebpへ変換します。以下のように。。

  "images": [
    {
      "name": "texture_0",
      "uri": "f1_img0.webp"
    },
    {
      "name": "texture_1",
      "uri": "f1_img1.webp"
    }
  ],

glTFからglbへ

ここで素材の準備ができたので、最後にglbへ戻します。

gltf-import-export f1.gltf

ここで、3MBに削減成功!50%の削減率です!
glTF Viewerで確認したものがこちら。

まとめ

今回はWebARの文脈になりましたが、一般的なWebサイト制作フローにおいてもこちらのモデル削減術は利用できると思います。
DLするデータをなるべく軽くして、ユーザー体験を向上させていきたいですね。
以上です。

Discussion