Common glTF modifications, written using the core API.

Most of these functions are Transforms, applying a modification to the Document, used with Document.transform. This project includes many common transforms already, and others can be quickly implemented using the same APIs. Other functions, like bounds, provide non-mutating functionality on top of the existing glTF-Transform property types.

Installation

Install:

npm install --save @gltf-transform/functions

Import:

import { NodeIO } from '@gltf-transform/core';
import { dedup, quantize, weld } from '@gltf-transform/functions';

const io = new NodeIO();
const document = await io.read('input.glb');

await document.transform(
    weld(),
    quantize(),
    dedup()
);

await io.write('output.glb', document);

Functions

  • bounds(node: Node | Scene): bbox
  • Computes bounding box (AABB) in world space for the given Node or Scene.

    Example:

    const {min, max} = bounds(scene);
    
  • createLayoutPlan(document: Document): LayoutPlan
  • Constructs a plan for processing vertex streams, based on unique index:attribute[] groups. Where different indices are used with the same attributes, we'll end up splitting the primitives to not share attributes, which appears to be consistent with the Meshopt implementation.

  • dedup(_options?: DedupOptions): Transform
  • draco(_options: DracoOptions): Transform
  • getTextureChannelMask(document: Document, texture: Texture): number
  • inspect(doc: Document): InspectReport
  • instance(_options?: InstanceOptions): Transform
  • listTextureChannels(document: Document, texture: Texture): TextureChannel[]
  • listTextureInfo(document: Document, texture: Texture): TextureInfo[]
  • Lists all TextureInfo definitions associated with a given Texture.

    Example:

    // Find TextureInfo instances associated with the texture.
    const results = listTextureInfo(document, texture);
    
    // Find which UV sets (TEXCOORD_0, TEXCOORD_1, ...) are required.
    const texCoords = results.map((info) => info.getTexCoord());
    // → [0, 0, 1]
    
  • listTextureSlots(doc: Document, texture: Texture): string[]
  • meshopt(_options: MeshoptOptions): Transform
  • Applies Meshopt compression using EXT_meshopt_compression. This type of compression can reduce the size of point, line, and triangle geometry, morph targets, and animation data.

    This function is a thin wrapper around reorder, quantize, and MeshoptCompression, and exposes relatively few configuration options. To access more options (like quantization bits) direct use of the underlying functions is recommended.

    Example:

    import { MeshoptEncoder } from 'meshoptimizer';
    import { reorder } from '@gltf-transform/functions';
    
    await MeshoptEncoder.ready;
    
    await document.transform(
      reorder({encoder: MeshoptEncoder, level: 'medium'})
    );
    
  • metalRough(_options?: MetalRoughOptions): Transform
  • Convert Materials from spec/gloss PBR workflow to metal/rough PBR workflow, removing KHR_materials_pbrSpecularGlossiness and adding KHR_materials_ior and KHR_materials_specular. The metal/rough PBR workflow is preferred for most use cases, and is a prerequisite for other advanced PBR extensions provided by glTF.

    No options are currently implemented for this function.

  • mozjpeg(options: SquooshOptions): Transform
  • Optimizes JPEG images by default, optionally converting PNG textures to JPEG.

    Requires @squoosh/lib, and currently works only in Node.js environments. Support for encoding in web browsers may be available pending GoogleChromeLabs/squoosh#1084.

    Example:

    import { cpus } from 'os';
    import * as squoosh from '@squoosh/lib';
    import { mozjpeg } from '@gltf-transform/functions';
    
    await document.transform(
        mozjpeg({ squoosh, jobs: cpus().length })
    );
    
  • oxipng(options: SquooshOptions): Transform
  • Optimizes PNG images by default, optionally converting JPEG textures to PNG.

    Requires @squoosh/lib, and currently works only in Node.js environments. Support for encoding in web browsers may be available pending GoogleChromeLabs/squoosh#1084.

    Example:

    import { cpus } from 'os';
    import * as squoosh from '@squoosh/lib';
    import { oxipng } from '@gltf-transform/functions';
    
    await document.transform(
        oxipng({ squoosh, jobs: cpus().length })
    );
    
  • partition(_options?: PartitionOptions): Transform
  • Partitions the binary payload of a glTF file so separate mesh or animation data is in separate .bin Buffers. This technique may be useful for engines that support lazy-loading specific binary resources as needed over the application lifecycle.

    Example:

    document.getRoot().listBuffers(); // → [Buffer]
    
    await document.transform(partition({meshes: true}));
    
    document.getRoot().listBuffers(); // → [Buffer, Buffer, ...]
    
  • prune(_options?: PruneOptions): Transform
  • Removes properties from the file if they are not referenced by a Scene. Commonly helpful for cleaning up after other operations, e.g. allowing a node to be detached and any unused meshes, materials, or other resources to be removed automatically.

    Example:

    document.getRoot().listMaterials(); // → [Material, Material]
    
    await document.transform(prune());
    
    document.getRoot().listMaterials(); // → [Material]
    

    No options are currently implemented for this function.

  • Optimizes Mesh Primitives for locality of reference. Choose whether the order should be optimal for transmission size (recommended for Web) or for GPU rendering performance. Requires a MeshoptEncoder instance from the Meshoptimizer library.

    Example:

    import { MeshoptEncoder } from 'meshoptimizer';
    import { reorder } from '@gltf-transform/functions';
    
    await MeshoptEncoder.ready;
    
    await document.transform(
        reorder({encoder: MeshoptEncoder})
    );
    
  • resample(_options?: ResampleOptions): Transform
  • Resample Animations, losslessly deduplicating keyframes to reduce file size. Duplicate keyframes are commonly present in animation 'baked' by the authoring software to apply IK constraints or other software-specific features. Based on THREE.KeyframeTrack.optimize().

    Example: (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0)

  • sequence(_options?: SequenceOptions): Transform
  • sortPrimitiveWeights(prim: Primitive | PrimitiveTarget, limit?: number): void
  • Sorts skinning weights from high to low, for each vertex of the input Primitive or PrimitiveTarget, and normalizes the weights. Optionally, uses the given 'limit' to remove least-significant joint influences such that no vertex has more than 'limit' influences.

    Most realtime engines support a limited number of joint influences per vertex, often 4 or 8. Sorting and removing the additional influences can reduce file size and improve compatibility.

    Example:

    import { sortPrimitiveWeights } from '@gltf-transform/functions';
    
    const limit = 4;
    for (const mesh of document.getRoot().listMeshes()) {
        for (const prim of mesh.listPrimitives()) {
            sortPrimitiveWeights(prim, limit);
        }
    }
    
  • Generates MikkTSpace vertex tangents for mesh primitives, which may fix rendering issues occuring with some baked normal maps. Requires access to the mikktspace WASM package, or equivalent.

    Example:

    import { generateTangents } from 'mikktspace';
    import { tangents } from '@gltf-transform/functions';
    
    await document.transform(
        tangents({generateTangents})
    );
    
  • unpartition(_options?: UnpartitionOptions): Transform
  • Removes partitions from the binary payload of a glTF file, so that the asset contains at most one (1) .bin Buffer. This process reverses the changes from a partition transform.

    Example:

    document.getRoot().listBuffers(); // → [Buffer, Buffer, ...]
    
    await document.transform(unpartition());
    
    document.getRoot().listBuffers(); // → [Buffer]
    
  • De-index Primitives, disconnecting any shared vertices. This operation will generally increase the number of vertices in a mesh, but may be helpful for some geometry operations or for creating hard edges.

    No options are currently implemented for this function.

  • webp(options: SquooshOptions): Transform
  • Converts images to WebP, using the TextureWebP extension.

    Requires @squoosh/lib, and currently works only in Node.js environments. Support for encoding in web browsers may be available pending GoogleChromeLabs/squoosh#1084.

    Example:

    import { cpus } from 'os';
    import * as squoosh from '@squoosh/lib';
    import { webp } from '@gltf-transform/functions';
    
    await document.transform(
        webp({ squoosh, jobs: cpus().length })
    );
    
  • Index Primitives and (optionally) merge similar vertices. When merged and indexed, data is shared more efficiently between vertices. File size can be reduced, and the GPU can sometimes use the vertex cache more efficiently.

    When welding, the 'tolerance' threshold determines which vertices qualify for welding based on distance between the vertices as a fraction of the primitive's bounding box (AABB). For example, tolerance=0.01 welds vertices within +/-1% of the AABB's longest dimension. Other vertex attributes are also compared during welding, with attribute-specific thresholds. For --tolerance=0, geometry is indexed in place, without merging.

    Example:

    import { weld } from '@gltf-transform/functions';
    
    await document.transform(
        weld({ tolerance: 0.001 })
    );
    
Function symbol, f(📦) → 📦, where the argument and output are a box labeled 'glTF'.

Made by Don McCurdy TypeDoc documentation Copyright 2021 under MIT license