🥰

【WebGL / three.js】DRACO&Basis圧縮でWebに最適なレベルまで3Dモデルを圧縮する

2022/05/02に公開

はじめに

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