【WebGL / three.js】DRACO&Basis圧縮でWebに最適なレベルまで3Dモデルを圧縮する
はじめに
Webに3Dモデルを表示したい場合、やはり少しでも容量を軽くしたいですよね。
手元の3Dモデルの形式が何であるかによりますが、
基本的には.glb形式がWebで使う一般的なデータ形式となります。
例えばもし.objでモデルを持っているならobj2gltf、.fbxならFBX2glTFあたりで変換すると便利です。
gltfをglbに変換する場合はmakeglbを使うといいと思います。
実はglb(gltf)に変換するだけで結構容量が圧縮されます。
でも問題はここからです。
ここまで変換してもまだ重い、もしくはBlenderから直接glb出力したけどめっちゃ重い!!
ということも結構ありますよね〜
そういう場合の対処法が、
DRACO圧縮とBasis圧縮です。
本記事では、上記の圧縮を行い、three.jsを使用してWebに表示するまでを解説します。
ちなみに今回使用する圧縮なのですが、Windows環境のみで可能でmacOS環境だとできませんでした。
あらかじめご了承ください。。
※「できたよ〜」って人いたら教えてください
DRACO圧縮 / Basis圧縮の概要
DRACO
DRACOは使っている方も多いと思います。
Googleが開発した圧縮ライブラリで、メッシュや点群データを圧縮できます。
といいつつ私も「これ使ったら軽くなるすげ〜〜」くらいの能天気な知識しかないので、詳細は下記記事に任せます。
クロノス、Google Draco技術を使用したglTFジオメトリ圧縮エクステンションを発表
DRACO圧縮をするには、
gltf-pipelineあたりが有名です。
ただ、今回は使用しないので詳細は解説しません!
Basis
次はBasisです。
これは私は最近知りました。皆様ご存知でしょうか?
Basisとは、正式にはBasis Universal Texture Formatと呼び、簡単にいうと3Dモデルのテスクチャを圧縮する新しい形式のようです。
例によって詳細は下記記事をご覧ください。
Google and Binomial Contribute Basis Universal Texture Format to Khronos’ glTF 3D Transmission Open Standard
難しいことはさておき、
メッシュを圧縮するのはDRACO、テクスチャを圧縮するのはBasisと捉えるといいと思います。
次からは実践編です。
実際に圧縮してみる
今回は、3d-tiles-validatorというリポジトリを使用します。
このリポジトリはもともとCesiumGSの3d-tiles-validatorをforkしていくつか機能を追加したもので、3d-tiles形式のファイルを作成するためのものであるのですが、今回はglbを圧縮するために使います。
冒頭にも述べましたが、macOSでは動作しませんのでWindowsでご使用ください。
basisuを実行可能パスに通す
圧縮にあたり、basisu v1.15が必要となります。
このURLからzipファイルをダウンロードします。
その中にbasisu.exeファイルが入っているので、適当なフォルダに入れてpathを通してください。
コマンドプロンプトで「basisu」とタイプし、オプションが出れば成功です。
Windowsのpathの通し方は下記記事に詳しいです。
【Windows 11対応】Path環境変数を設定/編集して、独自のコマンドを実行可能にする
圧縮コマンド実行
次に、3d-tiles-validatorのフォルダへ移動し、toolsフォルダへ移動します。
cd tools
そしてnpm installします。
npm install
これで準備完了です。
いよいよモデルを圧縮していきます。
今回サンプルで使用するモデルは、私がiPhoneで撮影したフォトグラメトリのファイルを使用したいと思います。
容量は44.6MB。重いですね。
※わかりづらいですが緑道をスキャンしてます
このファイルを先ほどのtoolsフォルダに入れ、下記コマンドを実行すると圧縮が始まります。
(sample.glbと命名しています。)
node bin/3d-tiles-tools.js compressGlb -i sample.glb -o sample_out.glb --options --basis
私の環境だと2分くらいかかりましたが、これでDRACO&Basis圧縮できました。
なんと8.2MB!めっちゃ軽いですね。これならWebで使えます!!!!
three.jsで表示してみる
three.jsで表示するために、いくつかloaderが必要となります。
結論から言うと、コード全容は以下です。
※three.js v137
import * as THREE from 'three';
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
import { KTX2Loader } from "three/examples/jsm/loaders/KTX2Loader";
const renderer = new THREE.WebGLRenderer();
const DRACOLoader = new DRACOLoader();
const KTX2Loader = new KTX2Loader();
DRACOLoader.setDecoderPath( 'https://unpkg.com/three@0.137.0/examples/js/libs/draco/' );
KTX2Loader.setTranscoderPath( 'https://unpkg.com/three@0.137.0/examples/js/libs/basis/' );
const GLTFLoader = new GLTFLoader()
.setDRACOLoader(DRACOLoader)
.setKTX2Loader(KTX2Loader.detectSupport( renderer ))
DRACO圧縮したのでDRACOLoader
、Basis圧縮したのでKTX2Loader
というものが必要となります。
それらをGLTFLoader
に設定しloaderの完成です。
あとはこのGLTFLoader
を使って煮るなり焼くなりお好きにどうぞ。
まとめ
Webのみならず、WebXR系でもモデルの圧縮は至上命題だと思います。
そんなときにDRACO圧縮のみならずBasis圧縮もぜひぜひご活用ください!
Discussion