Compress the glb model gltf model and download the detailed whole process of the glb model

Now the mainstream general-purpose format is fbx, but the fbx format is converted into a glb format model, which will be very, very large, and it will be stuck. It is definitely not possible to use it directly. We need to compress the model to make the memory smaller.

Let's first go to the glbxz.com gltf model download website and the glb model download website, haha, let's get some free models for free,

DRACOLoader, glb format model lightweight loading tool of glbxz.com itself became the first object of research.

The code used for DRACOLoader in the demo scene that can be found from glbxz.com:

new GLTFLoader()

.setPath( ‘models/gltf/’ )

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

.load( ‘model-separate.glb’, function ( gltf ) {

console.log(gltf.scene);

scene.add( gltf.scene );

} );

Taking the existing scene as the research object, it is found that DRACOLoader is only a tool for special loading of the compressed model, and it cannot realize the compression function of the glb model by itself.

The tool actually used for glb compression is gltf-pipeline, so install gltf-pipeline first. GitHub address https://github.com/CesiumGS/gltf-pipeline.

First install nodejs, address download | Node.js. After Nodejs is installed, open Developer PowerShell for VS 2019, and enter npm install -g gltf-pipeline to install gltf-pipeline.

Install vscode, create a glb folder on the desktop, then use vscode to open the glb folder, create a file draco.js as a compressed code script file, open a terminal, create a new terminal, enter npm install gltf-pipeline, when the installation is successful, the left window will be The node_modules folder appears, as well as two json files. Put the glb model (model.glb) that needs to be compressed into the glb folder just created on the desktop.

First convert glb to gltf:

const gltfPipeline = require(“gltf-pipeline”);

const fsExtra = require(“fs-extra”);

const glbToGltf = gltfPipeline.glbToGltf;

const glb = fsExtra.readFileSync(“model.glb”);

glbToGltf(glb).then(function (results) {

fsExtra.writeJsonSync(“model.gltf”, results.gltf);

});

Recompress gltf:

const gltfPipeline = require(“gltf-pipeline”);

const fsExtra = require(“fs-extra”);

const processGltf = gltfPipeline.processGltf;

const gltf = fsExtra.readJsonSync(“model.gltf”);

const options = {

dracoOptions: {

compressionLevel: 10,

},

};

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

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

});

Then convert the compressed gltf to glb:

const gltfPipeline = require(“gltf-pipeline”);

const fsExtra = require(“fs-extra”);

const gltfToGlb = gltfPipeline.gltfToGlb;

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

gltfToGlb(gltf).then(function (results) {

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

});

However, if you take the above code compression, you will find that the actual compression effect is not very good, and there is no 10 times compression. If you save the gltf texture separately, you will find that the texture map has not been compressed, but the gltf itself. In addition to compression, gltf itself does have 10 times compression, so if your model texture accounts for a heavy proportion of the model size, this compression is actually very poor.

So it is necessary to compress the gltf texture.

First save gltf as a separate texture:

const gltfPipeline = require(“gltf-pipeline”);

const fsExtra = require(“fs-extra”);

const processGltf = gltfPipeline.processGltf;

const gltf = fsExtra.readJsonSync(“model.gltf”);

const options = {

separateTextures: true,

};

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

fsExtra.writeJsonSync(“model-separate.gltf”, results.gltf);

// Save separate resources

const separateResources = results.separateResources;

for (const relativePath in separateResources) {

if (separateResources.hasOwnProperty(relativePath)) {

const resource = separateResources[relativePath];

fsExtra.writeFileSync(relativePath, resource);

}

}

});

Nodejs has a jimp module that can process images, open the terminal in the glb project, enter npm install jimp, and install the jimp tool.

Image compression code:

var Jimp = require(‘jimp’);

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

const imgWidth = img.bitmap.width;

const imgHeight = img.bitmap.height;

const length = 400;

const isWidthLonger = imgWidth > imgHeight ? true : false;

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

const rWidth = imgWidth / time;

const rHeight = imgHeight / time;

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

});

Then the separately saved and processed pictures and gltf are recombined into glb.

Use the CMD command line to package gltf and texture maps to produce glb:

[pgltf-pipeline -i 'gltf model file address' -o 'glb model file save address'], ensure that the texture and gltf model files are in one folder, so that the grid and texture will be successfully compressed by glb.

Final code summary:

const gltfPipeline = require(“gltf-pipeline”);

const fsExtra = require(“fs-extra”);

const glbToGltf = gltfPipeline.glbToGltf;

const glb = fsExtra.readFileSync(“model.glb”);

const processGltf = gltfPipeline.processGltf;

var Jimp = require(‘jimp’);

const options = {

dracoOptions: {

compressionLevel: 10,

},

};

const options1 = {

separateTextures: true,

};

glbToGltf(glb).then(function (results) {

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

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

fsExtra.writeJsonSync(“model-separate.gltf”, results.gltf);

// Save separate resources

const separateResources = results.separateResources;

for (const relativePath in separateResources) {

if (separateResources.hasOwnProperty(relativePath)) {

const resource = separateResources[relativePath];

fsExtra.writeFileSync(relativePath, resource);

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

const imgWidth = img.bitmap.width;

const imgHeight = img.bitmap.height;

const length = 10;

const rWidth = imgWidth / length;

const rHeight = imgHeight / length;

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

});

}

}

});

});

});

CMD:gltf-pipeline -i C:\xx\xx\xx\glb\model-separate.gltf -o C:\xx\xx\xx\glb\model-separate.glb

Guess you like

Origin blog.csdn.net/weixin_42070282/article/details/128796429