glTF-Transform
glTF 2.0 SDK for JavaScript and TypeScript, on Web and Node.js.
Introduction
glTF-Transform supports reading, editing, and writing 3D models in glTF 2.0 format. Unlike 3D modeling tools — which are ideal for artistic changes to geometry, materials, and animation — glTF-Transform provides fast, reproducible, and lossless control of the low-level details in a 3D model. The API automatically manages array indices and byte offsets, which would otherwise require careful management when editing files. These traits make it a good choice for bundling, splitting, or optimizing an existing model. It can also be used to apply quick fixes for common issues, to build a model procedurally, or to easily develop custom extensions on top of the glTF format. Because the core SDK is compatible with both Node.js and Web, glTF-Transform may be used to develop offline workflows and web applications alike.
Packages:
@gltf-transform/core
: Core SDK, providing an expressive API to read, edit, and write glTF files.@gltf-transform/extensions
: Extensions (optional glTF features) for the Core SDK.@gltf-transform/functions
: Functions for common glTF modifications, written using the core API.@gltf-transform/cli
: Command-line interface (CLI) to apply functions to glTF files quickly or in batch.
Scripting API
Install the scripting packages:
npm install --save @gltf-transform/core @gltf-transform/extensions @gltf-transform/functions
Read and write glTF scenes with platform I/O utilities WebIO, NodeIO, or DenoIO:
import { Document, NodeIO } from '@gltf-transform/core';
import { ALL_EXTENSIONS } from '@gltf-transform/extensions';
import draco3d from 'draco3dgltf';
// Configure I/O.
const io = new NodeIO()
.registerExtensions(ALL_EXTENSIONS)
.registerDependencies({
'draco3d.decoder': await draco3d.createDecoderModule(), // Optional.
'draco3d.encoder': await draco3d.createEncoderModule(), // Optional.
});
// Read from URL.
const document = await io.read('path/to/model.glb');
// Write to byte array (Uint8Array).
const glb = await io.writeBinary(document);
To perform changes to an existing glTF Document, import off-the-shelf scripts from the Functions package, or write your own using API classes like Material, Primitive, and Texture.
import { resample, prune, dedup, draco, textureCompress } from '@gltf-transform/functions';
import sharp from 'sharp'; // Node.js only.
await document.transform(
// Losslessly resample animation frames.
resample(),
// Remove unused nodes, textures, or other data.
prune(),
// Remove duplicate vertex or texture data, if any.
dedup(),
// Compress mesh geometry with Draco.
draco(),
// Convert textures to WebP (Requires glTF Transform v3 and Node.js).
textureCompress({
encoder: sharp,
targetFormat: 'webp',
resize: [1024, 2024],
}),
// Custom transform.
backfaceCulling({cull: true}),
);
// Custom transform: enable/disable backface culling.
function backfaceCulling(options) {
return (document) => {
for (const material of document.getRoot().listMaterials()) {
material.setDoubleSided(!options.cull);
}
};
}
To learn how glTF-Transform works, and the architecture of the scripting API, start with Concepts. To try out the scripting API without installing anything, visit gltf.report/, load a glTF model, and open the Script tab.
Command-line API
Install the CLI, supported in Node.js v14+.
npm install --global @gltf-transform/cli
List available CLI commands:
gltf-transform --help
Optimize everything all at once:
gltf-transform optimize input.glb output.glb --texture-compress webp
Or pick and choose your optimizations, building a custom pipeline.
Compress mesh geometry with Draco or Meshoptimizer:
# Draco (compresses geometry).
gltf-transform draco input.glb output.glb --method edgebreaker
# Meshopt (compresses geometry, morph targets, and keyframe animation).
gltf-transform meshopt input.glb output.glb --level medium
Resize and compress textures with Sharp, or improve VRAM usage and performance with KTX2 and Basis Universal:
# Resize textures.
gltf-transform resize input.glb output.glb --width 1024 --height 1024
# Compress textures with WebP.
gltf-transform webp input.glb output.glb --slots "baseColor"
# Compress textures with KTX2 + Basis Universal codecs, UASTC and ETC1S.
gltf-transform uastc input.glb output1.glb \
--slots "{normalTexture,occlusionTexture,metallicRoughnessTexture}" \
--level 4 --rdo 4 --zstd 18 --verbose
gltf-transform etc1s output1.glb output2.glb --quality 255 --verbose
... and much more.
Credits
See Credits.
License
Copyright 2023, MIT License.