Batch Convert OBJ and FBX to Optimized glTF

Converting 3D assets like OBJ and FBX into the web-standard glTF (or binary GLB) format is essential for modern real-time graphics pipelines. This article details the most effective command-line utilities available for automating and batch-processing conversions from OBJ and FBX to high-performance, optimized glTF files, along with compression strategies to minimize file sizes.

1. FBX2glTF

Developed by Meta, FBX2glTF is a dedicated, high-performance command-line tool built specifically to convert FBX files to glTF 2.0. It relies on the official Autodesk FBX SDK, ensuring high fidelity for meshes, materials, skeletal animations, and skinning data.

  • Key Features: Native support for binary glTF (.glb), embedded resources, and built-in Draco geometry compression.

  • Basic Command:

    FBX2glTF -i model.fbx -o model.glb --draco
  • Batch Processing (Bash):

    for file in *.fbx; do
      FBX2glTF -i "$file" -o "${file%.fbx}.glb" --draco
    done

2. obj2gltf

Maintained by the Cesium team, obj2gltf is a Node.js-based command-line interface tailored specifically for converting OBJ files into glTF. It accurately parses .obj, .mtl, and associated textures, converting standard Blinn-Phong materials to glTF's PBR (Physically Based Rendering) metallic-roughness workflow.

  • Installation: npm install --global obj2gltf

  • Basic Command:

    obj2gltf -i model.obj -o model.glb --binary
  • Batch Processing (Bash):

    for file in *.obj; do
      obj2gltf -i "$file" -o "${file%.obj}.glb" --binary
    done

3. Blender in Headless Mode

Blender provides built-in importers for both OBJ and FBX, along with the official glTF-Blender-IO exporter. You can run Blender without a user interface using the command line to execute Python batch scripts. This approach is ideal for handling mixed assets or complex scene hierarchies.

  • Execution Command:

    blender --background --python convert_batch.py
  • Sample Python Script (convert_batch.py):

    import bpy
    import glob
    import os
    
    def process_files(extension, import_func):
        for filepath in glob.glob(f"*.{extension}"):
            bpy.ops.wm.read_factory_settings(use_empty=True)
            import_func(filepath=filepath)
            out_name = os.path.splitext(filepath)[0] + ".glb"
            bpy.ops.export_scene.gltf(
                filepath=out_name,
                export_format='GLB',
                export_draco_mesh_compression_enable=True
            )
    
    process_files("fbx", bpy.ops.import_scene.fbx)
    process_files("obj", bpy.ops.wm.obj_import)

4. Advanced Optimization: glTF-Transform

While converters can produce standard glTF files, achieving maximum compression requires dedicated optimization passes. glTF-Transform is the standard CLI utility for optimizing, inspecting, and manipulating glTF and GLB containers.

After converting your OBJ or FBX files to GLB, run them through glTF-Transform to compress textures and geometry.

  • Installation: npm install --global @gltf-transform/cli
  • Key Optimizations:
    • Draco Compression: Reduces geometry size dramatically for static meshes.

      gltf-transform draco input.glb output.glb
    • Meshopt Compression: Faster decompression on mobile and web devices than Draco.

      gltf-transform meshopt input.glb output.glb
    • Texture Optimization: Resizes and converts textures to WebP or KTX2 Basis Universal formats.

      gltf-transform webp input.glb output.glb
    • Dedicated Optimize Pipeline: Runs deduping, pruning of unused nodes, and geometry quantization in a single pass.

      gltf-transform optimize input.glb output.glb --compress meshopt

Complete Automated Pipeline Example

To handle batch conversion and optimization together in a single Bash pipeline:

#!/usr/bin/env bash

# 1. Convert all OBJ files
for f in *.obj; do
  [ -f "$f" ] || continue
  obj2gltf -i "$f" -o "temp_${f%.obj}.glb" --binary
done

# 2. Convert all FBX files
for f in *.fbx; do
  [ -f "$f" ] || continue
  FBX2glTF -i "$f" -o "temp_${f%.fbx}.glb"
done

# 3. Optimize all generated GLB files
for f in temp_*.glb; do
  [ -f "$f" ] || continue
  final_name="${f#temp_}"
  gltf-transform optimize "$f" "$final_name" --compress meshopt
  rm "$f"
done