添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
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に変えるだけです。