Last active
January 15, 2025 22:26
-
-
Save donmccurdy/9f094575c1f1a48a2ddda513898f6496 to your computer and use it in GitHub Desktop.
Example Node.js glTF conversion script, using three.js.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env node | |
const fs = require('fs'); | |
const path = require('path'); | |
const THREE = require('three'); | |
const program = require('commander'); | |
const Canvas = require('canvas'); | |
const { Blob, FileReader } = require('vblob'); | |
// Patch global scope to imitate browser environment. | |
global.window = global; | |
global.Blob = Blob; | |
global.FileReader = FileReader; | |
global.THREE = THREE; | |
global.document = { | |
createElement: (nodeName) => { | |
if (nodeName !== 'canvas') throw new Error(`Cannot create node ${nodeName}`); | |
const canvas = new Canvas(256, 256); | |
// This isn't working — currently need to avoid toBlob(), so export to embedded .gltf not .glb. | |
// canvas.toBlob = function () { | |
// return new Blob([this.toBuffer()]); | |
// }; | |
return canvas; | |
} | |
}; | |
// https://github.com/mrdoob/three.js/issues/9562 | |
require('three/examples/js/exporters/GLTFExporter'); | |
program | |
.version('0.0.1') | |
.usage('[options] <file>') | |
.option('-o, --output <file>', 'output filename', String) | |
// .option('-b, --binary', 'use binary (.glb) format (default false)') | |
.option('-m, --myoption', 'my custom option (default 1.0)', Number) | |
.parse(process.argv); | |
program.binary = !!program.binary; | |
program.myoption = program.myoption || 1; | |
const inputPath = program.args[0]; | |
if (!inputPath) { program.help(); } | |
if (!program.output) { | |
program.output = path.basename(inputPath, '.foo'); | |
program.output += program.binary ? '.glb' : '.gltf'; | |
} | |
console.log(' → input: %j', program.args); | |
console.log(' → output: %j', program.output); | |
console.log(' → binary: %j', program.binary); | |
console.log(' → my custom option: %j', program.myoption); | |
console.log(`Loading "${inputPath}"`); | |
let mesh = new THREE.Mesh(...); // (load or create mesh here) | |
console.log('Converting to glTF'); | |
const exporter = new THREE.GLTFExporter(); | |
exporter.parse(mesh, (content) => { | |
console.log(`Writing to ${program.output}`); | |
if (typeof content === 'object') content = JSON.stringify(content); | |
fs.writeFileSync(program.output, content); | |
}, {binary: program.binary}); |
Hi. I was able to reduce it a little bit further:
Foo2Gltf.mjs:
import { writeFileSync } from 'fs';
import { basename } from 'path';
import { GLTFExporter } from 'three/examples/jsm/exporters/GLTFExporter.js'
import { FileReader } from 'vblob';
// Patch global scope to imitate browser environment.
global.FileReader = FileReader;
const exportMeshToGLTF = (mesh, outputPath, options = { binary: false }) => {
// Create an instance of the GLTFExporter
const exporter = new GLTFExporter();
// Define the output file name
let output = outputPath;
if (!output) {
output = basename('output', '.foo');
output += options.binary ? '.glb' : '.gltf';
}
console.log('Converting to glTF');
exporter.parse(
mesh,
(content) => {
console.log(`Writing to ${output}`);
if (typeof content === 'object') content = JSON.stringify(content);
writeFileSync(output, content);
console.log('GLTF file has been saved.');
},
options
);
};
export default exportMeshToGLTF;
and usage is:
index.mjs:
import { MeshBasicMaterial, BoxGeometry, Mesh } from 'three'
import exportMeshToGLTF from './Foo2Gltf.mjs';
// Create a geometry, for example, a box geometry
const geometry = new BoxGeometry();
const material = new MeshBasicMaterial({ color: 0x00ff00 });
const mesh = new Mesh(geometry, material);
exportMeshToGLTF(mesh, "cube.gltf")
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I am working on a 3D editor with nw.js. The editor part is 'normal' JS with THREE.js and right now I am using nw.js only to write the file to a specific directory. From that, I can report that
properly exports gltf including textures.