Three.js 軽量 GLB モデルの詳細な全体プロセス

この方法は必ずしも最速ではありませんが、個人的なテストは実行可能であり、効果はより優れています。

以前は、Unity3d 3 次元エンジンを使用して Web プロジェクトを開発していましたが、初期段階で黒い画面の読み込み時間が長かったため、プロジェクト開発には新しい 3 次元技術ソリューション、three.js+glb が使用されました。当事者Aのプロジェクトのモデルのほとんどは工業用モデルであるため、モデルが大きく面の数も多く、three.jsシーン自体のモデル読み込みには一定の上限があるため、モデルの軽量化は困難です。は比較的重要な問題です。

DRACOLoader は、three.js 独自の glb 形式モデル用の軽量読み込みツールであり、最初の研究対象となりました。

デモ シーンの DRACOLoader に使用できるコードは、three.js にあります。

新しいGLTFLoader ()

setPath ( 'models/gltf/'  )

setDRACOLoader ( new DRACOLoader () .setDecoderPath ( 'js/libs/draco/gltf/'  ) )

ロード( 'モデル別.glb' ,関数 ( gltf ) {

コンソールログ(gltf.scene);

シーン。追加( gltf.scene );

} );

既存のシーンを研究対象とすると、DRACOLoader は圧縮モデルを特殊にロードするためのツールにすぎず、それ自体では glb モデルの圧縮機能を実現できないことがわかります。

実際に glb 圧縮に使用するツールは gltf-pipeline なので、最初に gltf-pipeline をインストールします。GitHub アドレスhttps://github.com/CesiumGS/gltf-pipeline

まず、nodejs をインストールし、ダウンロード | Node.jsにアクセスします。Nodejs がインストールされたら、VS 2019 の開発者 PowerShell を開き、「npm install -g gltf-pipeline」と入力して gltf-pipeline をインストールします。

vscode をインストールし、デスクトップに glb フォルダーを作成し、vscode を使用して glb フォルダーを開き、ファイル draco.js を圧縮コード スクリプト ファイルとして作成し、ターミナルを開き、新しいターミナルを作成し、「npm install gltf-pipeline」と入力し、インストールが成功すると、左側のウィンドウが表示されます。node_modules フォルダーと 2 つの json ファイルが表示されます。圧縮する必要がある glb モデル (model.glb) を、デスクトップ上に作成した glb フォルダーに置きます。

まず glb を gltf に変換します。

const gltfPipeline = require("gltf-パイプライン");

const fsExtra = require("fs-extra");

const glbToGltf = gltfPipeline.glbToGltf;

const glb = fsExtra.readFileSync("model.glb");

glbToGltf(glb).then(関数 (結果) {

  fsExtra.writeJsonSync("model.gltf", results.gltf);

});

gltf を再圧縮します。

const gltfPipeline = require("gltf-パイプライン");

const fsExtra = require("fs-extra");

const processGltf = gltfPipeline.processGltf;

const gltf = fsExtra.readJsonSync("model.gltf");

const オプション = {

  ドラコオプション: {

    圧縮レベル: 10、

  }、

};

processGltf(gltf, オプション).then(関数 (結果) {

  fsExtra.writeJsonSync("model-draco.gltf", results.gltf);

});

次に、圧縮された gltf を glb に変換します。

const gltfPipeline = require("gltf-パイプライン");

const fsExtra = require("fs-extra");

const gltfToGlb = gltfPipeline.gltfToGlb;

const gltf = fsExtra.readJsonSync("model-draco.gltf");

gltfToGlb(gltf).then(関数 (結果) {

  fsExtra.writeFileSync("model-draco.glb", results.glb);

});

ただし、上記のコード圧縮を実行すると、実際の圧縮効果はあまり良くなく、10 倍の圧縮はありません。gltf テクスチャを個別に保存すると、テクスチャ マップが圧縮されていないことがわかります。圧縮に加えて、gltf 自体には 10 倍の圧縮があるため、モデル テクスチャがモデル サイズの大きな割合を占めている場合、この圧縮は実際には非常に不十分になります。

したがって、gltf テクスチャを圧縮する必要があります。

まず、gltf を別のテクスチャとして保存します。

const gltfPipeline = require("gltf-パイプライン");

const fsExtra = require("fs-extra");

const processGltf = gltfPipeline.processGltf;

const gltf = fsExtra.readJsonSync("model.gltf");

const オプション = {

  セパレートテクスチャ: true、

};

processGltf(gltf, オプション).then(関数 (結果) {

  fsExtra.writeJsonSync("モデル別.gltf", results.gltf);

  // 個別のリソースを保存する

  constセパレートリソース = results.セパレートリソース;

  for (constrelativePath in SeparateResources) {

    if (セパレートリソース.hasOwnProperty(relativePath)) {

      const resource = SeparateResources[相対パス];

      fsExtra.writeFileSync(relativePath, resource);

    }

  }

});

Nodejs には、画像を処理できる jimp モジュールがあり、glb プロジェクトでターミナルを開き、「npm install jimp」と入力して、jimp ツールをインストールします。

画像圧縮コード:

var Jimp = require('jimp');

Jimp.read('image0.png').then(img => {

  const imgWidth = img.bitmap.width;

  const imgHeight = img.bitmap.height;

  定数の長さ = 400;

  const isWidthLonger = imgWidth > imgHeight ? 真/偽;

  const time = (isWidthLonger ? imgWidth : imgHeight) / 長さ;

  const rWidth = imgWidth / 時間;

  const rHeight = imgHeight / 時間;

  return img.resize(rWidth, rHeight ).write(`image0.png`);

});

次に、別々に保存して処理した写真と gltf を glb に再結合します。

CMD コマンド ラインを使用して gltf とテクスチャ マップをパッケージ化し、glb を生成します。

[pgltf-pipeline -i 'gltf モデル ファイル アドレス' -o 'glb モデル ファイル保存アドレス']、glb がグリッドとテクスチャに対して正常に圧縮されるように、テクスチャ ファイルと gltf モデル ファイルが 1 つのフォルダー内にあることを確認します。

最終的なコードの概要:

const gltfPipeline = require("gltf-パイプライン");

const fsExtra = require("fs-extra");

const glbToGltf = gltfPipeline.glbToGltf;

const glb = fsExtra.readFileSync("model.glb");

const processGltf = gltfPipeline.processGltf;

var Jimp = require('jimp');

const オプション = {

  ドラコオプション: {

    圧縮レベル: 10、

  }、

};

const オプション 1 = {

  セパレートテクスチャ: true、

};

glbToGltf(glb).then(関数 (結果) {

  processGltf(results.gltf, options).then(function (results) {

    processGltf(results.gltf, options1).then(function (results) {

      fsExtra.writeJsonSync("モデル別.gltf", results.gltf);

      // 個別のリソースを保存する

      constセパレートリソース = results.セパレートリソース;

      for (constrelativePath in SeparateResources) {

        if (セパレートリソース.hasOwnProperty(relativePath)) {

          const resource = SeparateResources[相対パス];

          fsExtra.writeFileSync(relativePath, resource);

          Jimp.read(relativePath).then(img => {

            const imgWidth = img.bitmap.width;

            const imgHeight = img.bitmap.height;

            定数の長さ = 10;

            const rWidth = imgWidth / 長さ;

            const rHeight = imgHeight / 長さ;

            return img.resize(rWidth, rHeight ).write(relativePath);

          });

        }

      }

    });

  });

});

CMD:gltf-pipeline -i C:\xx\xx\xx\glb\モデル別.gltf -o C:\xx\xx\xx\glb\モデル別.glb

glb の最後の 4158KB は 138KB に圧縮され、ロードされて通常に使用されます

おすすめ

転載: blog.csdn.net/Bug1997/article/details/126768305