この方法は必ずしも最速ではありませんが、個人的なテストは実行可能であり、効果はより優れています。
以前は、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 に圧縮され、ロードされて通常に使用されます