Three.jsのDRACO Loderを使うと、DRACO圧縮されたファイルの解凍とLoadを同時に行ってくれるらしいです。
Dracoはオープンソースの3Dデータの圧縮方式
で、Zip圧縮よりも高い圧縮率を実現している圧縮形式です。ファイルを圧縮した状態で保存することができるので、Webサイトのアクセス速度などにも影響してくるのでしょうか?
Doraco Loder関連のエラー
今回はまったエラーは以下の2つです。
Draco Loderを適用していない場合のエラー
app.ts:55 Error: THREE.GLTFLoader: No DRACOLoader instance provided.
at new GLTFDracoMeshCompressionExtension (GLTFLoader.js:1742:10)
at GLTFLoader.parse (GLTFLoader.js:329:37)
at Object.eval [as onLoad] (GLTFLoader.js:167:11)
at eval (three.module.js:42311:38)
ネットから落としてきたGLTF形式のファイルをいつものようにGLTFLoderで表示しようとしたときにこのエラーがでました。
単純に
Doraco圧縮されていたファイルであったにもかかわらず、通常のGLTFLoderでロード
しようとしたのがまずかったようです。
webpackを適切に設定していない場合エラー
draco/draco_decoder.wasm:1
draco/draco_wasm_wrapper.js:1
Failed to load resource: the server responded with a status of 404 (Not Found)
Uncaught (in promise) Error: fetch for "http://127.0.0.1:5501/dist/draco/draco_wasm_wrapper.js" responded with 404: Not Found
at eval (three.module.js:42248:12)
次に、DRACOLoderをコード内にインポートしてコードに組み込み、
webpackでbuildした時
にこれらのようなエラーが出ました。
Not Foundなので「draco_wasm_wrapper.js」などが見つけられないといった内容のエラーです。Webpackでビルドした後の配布用ディレクトリである「/dist」などに「draco_wasm_wrapper.js」を含むディレクトリを上手く配置してやる設定をWebpackのコンフィギュレーションファイルで行わなければいけません。
TypeScriptでのDRACOLoder記述
TypeScriptでDracoLoderを使用する場合の記述について、抜粋したものを示します。
typescript:
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader';
let scene: THREE.Scene; // シーン定義
/* glbファイルの読み込み */
const loader: GLTFLoader = new GLTFLoader();
const dracoLoader: DRACOLoader = new DRACOLoader();
dracoLoader.setDecoderPath('draco/');
loader.setDRACOLoader(dracoLoader);
loader.load ('/assets/models/gltf/model_name.gltf', function(gltf){
gltf.scene.scale.set(2, 2, 2); // モデルスケール変更
gltf.scene.position.set(0, 0, 0); // モデル位置変更
gltf.scene.rotation.set(0, (0 * Math.PI /180), 0); // モデル向き変更
scene.add(gltf.scene); // モデルをシーンに追加
}, undefined, function (error) {
console.error(error);
3行目でDRACOLoderをインポートして、8行目でインスタンス化しています。
9行目には、「draco_wasm_wrapper.js」を含むdracoディレクトリの場所を示すパスを入力します。このパスについては、下のwebpackの設定で指定した場所を指すようにします。
「/assets/models/gltf/model_name.gltf」には、表示したいGLTF形式のファイルか、GLB形式のファイルを指定してください。
webpackのDraco設定方法
「draco_wasm_wrapper.js」を含むdracoディレクトリはnode_modulesディレクトリ内にあります。
ですが、node_modulesを配信用のディレクトリ(distなど)に入れておくわけにもいかないので、dracoディレクトリをwebpackで自動で配信用ディレクトリにコピーするようにします。
■ ファイルのコピーを行うプラグインの追加
コマンド:
npm install copy-webpack-plugin --save-dev
■ webpack.configの設定
webpack.config.js:
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
plugins: [
// ファイルをコピーするプラグイン
new CopyWebpackPlugin({
patterns: [
// dracoのLoaderもdist内に含める記述の追加
from: './node_modules/three/examples/jsm/libs/draco/',
to: 'draco',
CopyWebpackPluginを用いて、10行目でdracoディレクトリのある場所を指定し、ここから11行目のディレクトリにdracoディレクトリの中身をコピーします。
webpackのoutput先として指定しているディレクトリ以下に11行目で指定したディレクトリが作成されます。
Draco圧縮のコマンド
ついでに、GLTFおよびGLBファイルのDraco圧縮方法をまとめておきます。
ツールインストール:
sudo npm install -g gltf-pipeline
GLTFファイルのDraco圧縮:
gltf-pipeline -i model_name.gltf -o modelDraco.gltf -d
GLB形式のファイルでもファイル拡張子をglbに変えるだけです。