Skip to content

Additional Format Loaders

This page documents the various 3D asset format loaders available in Three.js beyond GLTF. These loaders enable importing models, scenes, and point clouds from legacy and specialized formats. For GLTF import/export (the recommended modern format), see GLTF Import & Export.

The additional format loaders are located in examples/jsm/loaders/ and support a wide range of formats from animation-capable scene formats (FBX, Collada) to simple mesh formats (OBJ, STL) to point cloud data (PCD, PLY, VTK).

Format Categories and Capabilities

Three.js supports loaders across several format categories, each with different capabilities:

FormatLoader ClassGeometryMaterialsTexturesAnimationsLights/CamerasNotes
FBXFBXLoaderFull scene format, industry standard
Collada (.dae)ColladaLoaderXML-based, Khronos standard
VRML (.wrl)VRMLLoaderWeb3D legacy format
OBJOBJLoaderVia MTLVia MTLSimple mesh format
STLSTLLoaderCAD/3D printing
PLYPLYLoaderVertex colorsPoint cloud/mesh
3MFThreeMFLoader3D printing standard
AMFAMFLoader3D printing (XML)
PCDPCDLoaderPointsVertex colorsPoint Cloud Data
VTKVTKLoaderVertex colorsScientific visualization
NRRDNRRDLoaderVolume dataMedical imaging voxels
XYZXYZLoaderPointsSimple point cloud
KMZKMZLoaderCompressed Collada

FBXLoader Architecture

FBXLoader is the most comprehensive additional format loader, supporting full scene hierarchies with animations, materials, textures, lights, cameras, and skeletal animations. It handles both ASCII and binary FBX formats version 7.0+.

FBX Parsing Pipeline

FBX Parsing Pipeline: load() → parse() → FBXTreeParser

SVG
100%

The loader uses FileLoader to load the raw data as an ArrayBuffer, then determines format with isFbxFormatBinary() and isFbxFormatASCII() helper functions. The parsers construct a global fbxTree object containing all FBX nodes, which FBXTreeParser then processes sequentially through its parsing methods. The final output is stored in a global sceneGraph variable of type Group.

FBX Object Types and Three.js Mapping

The FBX format contains multiple object types in fbxTree.Objects.Model that FBXTreeParser.parseModels() converts to Three.js objects based on the node.attrType field:

FBX node.attrType → Three.js Object Mapping

SVG
100%

FBX Material System

FBX materials in fbxTree.Objects.Material have a ShadingModel property that determines the Three.js material type. The parseMaterial() method extracts material parameters and the parseParameters() method processes texture connections:

FBX Material Parsing: materialNode.ShadingModel → MeshLambertMaterial/MeshPhongMaterial

SVG
100%

FBX Deformers and Skeletal Animation

FBX deformers in fbxTree.Objects.Deformer are processed by parseDeformers() which returns a structure with skeletons and morphTargets dictionaries. The deformerNode.attrType determines the deformer type:

FBX Deformer Processing: parseDeformers() → bindSkeleton()

SVG
100%

FBX Animation System

FBX animations are parsed by AnimationParser.parse() which constructs AnimationClip objects from the animation data in fbxTree.Objects.AnimationCurveNode and related nodes. The parser uses parseAnimStack(), parseAnimationLayers(), and parseAnimationCurveNodes() to build the animation hierarchy:

FBX Animation Pipeline: AnimationParser.parse() → AnimationClip

SVG
100%

OBJLoader and MTLLoader

The OBJ format is a simple ASCII mesh format that stores vertex positions, normals, UV coordinates, and face definitions. Materials are defined in a separate MTL file.

OBJ Parsing State Machine

OBJLoader.parse() uses a ParserState object to accumulate vertex data and build objects. The parser reads line-by-line, dispatching to state methods based on the line prefix:

OBJ Line-by-Line Parser: ParserState methods

SVG
100%

MTLLoader Material Creation

MTLLoader.parse() reads MTL line-by-line, building a materialsInfo dictionary. It returns a MaterialCreator instance that lazily creates materials when create(materialName) is called:

MTL Parsing: MaterialCreator.create() → MeshPhongMaterial

SVG
100%

ColladaLoader Architecture

Collada (.dae) is an XML-based format that supports full scene graphs with animations, kinematics, and physics. ColladaLoader is one of the most complex loaders.

Collada Parsing Pipeline

ColladaLoader.parse() uses DOMParser to parse the XML, then calls helper functions like parseLibrary() and buildLibrary() for each library section. The result includes a scene (Group), animations array, and kinematics object:

Collada XML Processing: parseLibrary() → buildLibrary() → Result

SVG
100%

Collada Library System

Collada organizes content into libraries that are parsed independently and then cross-referenced:

LibraryXML ElementParser FunctionThree.js Output
Geometries<library_geometries>parseGeometry()BufferGeometry
Materials<library_materials>parseMaterial()MeshLambertMaterial / MeshPhongMaterial
Effects<library_effects>parseEffect()Material parameters
Images<library_images>parseImage()Texture
Animations<library_animations>parseAnimation()AnimationClip
Cameras<library_cameras>parseCamera()PerspectiveCamera / OrthographicCamera
Lights<library_lights>parseLight()DirectionalLight / PointLight / SpotLight
Visual Scenes<library_visual_scenes>parseVisualScene()Group hierarchy

Point Cloud Loaders

Three.js provides several loaders for point cloud data formats, each returning a Points object with a BufferGeometry containing position and optional color/normal attributes.

Point Cloud Format Comparison

Point cloud loaders all return a Points object containing a BufferGeometry with vertex positions and optional color/normal attributes:

Point Cloud Loaders: parse() → Points

SVG
100%

PCD Header and Data Parsing

PCDLoader.parse() first calls parseHeader() to extract PCD metadata, then uses PCDheader.data to determine which parsing path to take. The _getDataView() helper reads typed data from the binary buffer:

PCD Data Extraction: parseHeader() → parse ASCII/binary/compressed

SVG
100%

3D Printing Format Loaders

Several loaders target 3D printing workflows, with different levels of material support.

3D Printing Format Loaders

Three loaders target 3D printing workflows with varying complexity:

3D Printing Format Capabilities

FormatLoaderGeometryMaterialsTexturesOutput
STLSTLLoaderTriangle meshBufferGeometry (no material)
3MF3MFLoaderTriangle mesh✓ (PBR)Group with MeshStandardMaterial
AMFAMFLoaderTriangle mesh✓ (basic)Group with MeshPhongMaterial

STL Format: STLLoader.parse() detects ASCII vs binary with isBinary(), then calls parseASCII() or parseBinary(). Binary STL may contain "Magics" color data in the attribute byte count field.

3MF Format: 3MFLoader.parse() uses JSZip to extract 3D/3dmodel.model XML file, parses resources (basematerials, texture2d, objects), and builds meshes with material arrays. Supports pbmetallicdisplayproperties for PBR metallic/roughness.

AMF Format: AMFLoader.parse() handles both plain XML and ZIP-compressed AMF files. Parses <object><mesh><vertices> and <volume><triangle> structure with optional <material> definitions.

3MF Material and Texture System

3MFLoader parses XML resources and builds materials with buildBasematerialsMeshStandardSet() or buildMaterialsMeshPhong(). The buildTexture() method loads textures from the ZIP archive:

3MF Resource Processing: XML resources → Material arrays

SVG
100%

VRMLLoader Scene Graph

VRMLLoader parses VRML 2.0 files, which use a hierarchical scene graph with nodes and fields:

VRML Node Types

VRMLLoader.parse() uses the Chevrotain parser library to tokenize and parse VRML 2.0 syntax into an AST (Abstract Syntax Tree). The parseTree() function walks the AST and calls buildNode() for each node based on node.name:

VRML Parsing: Chevrotain → AST → buildNode() → Scene

SVG
100%

VTKLoader for Scientific Visualization

VTKLoader supports the VTK (Visualization Toolkit) format for scientific and medical data visualization. It handles both ASCII and binary POLYDATA:

VTK POLYDATA Structure

VTKLoader.parse() calls parseASCII() or parseBinary() based on the file content. The parser uses state machine variables (inPointsSection, inPolygonsSection, etc.) to track which section is being read:

VTK Section-Based Parsing: parseASCII/parseBinary() → BufferGeometry

SVG
100%

NRRDLoader for Medical Imaging

NRRDLoader loads NRRD (Nearly Raw Raster Data) format files commonly used for medical imaging and scientific volume visualization. Unlike mesh loaders, it returns a Volume object containing 3D voxel data rather than surface geometry.

NRRD Format Structure

NRRD files consist of a text header followed by raw binary volume data. The header specifies dimensions, data type, encoding, and spatial transformations:

NRRD Header Fields

FieldDescriptionExample
typeData type (uint8, int16, float, etc.)type: unsigned char
dimensionNumber of dimensionsdimension: 3
sizesSize along each dimensionsizes: 256 256 128
encodingData encoding (raw, gzip, bzip2)encoding: gzip
endianByte order (little, big)endian: little
space directionsSpatial transformation vectorsspace directions: (1,0,0) (0,1,0) (0,0,1)

NRRD Parsing Pipeline

NRRDLoader.parse() splits the file into header and data sections, parses the header with field-specific functions in _fieldFunctions, then decodes the data based on the encoding type:

NRRD Parsing: parseHeader() → decompression → Volume object

SVG
100%

Volume Object and Coordinate Systems

The Volume class stores 3D voxel data and provides methods for accessing values and extracting 2D slices. It maintains two coordinate systems:

IJK Coordinate System: Integer indices into the volume data array (0 to xLength-1, etc.)

RAS Coordinate System: Real-world spatial coordinates (Right-Anterior-Superior) defined by the space directions header

The volume.matrix property transforms from IJK to RAS coordinates, and volume.extractSlice(axis, index) returns a VolumeSlice object for rendering:

// Volume structure
class Volume {
    xLength: number;        // Width in IJK
    yLength: number;        // Height in IJK  
    zLength: number;        // Depth in IJK
    data: TypedArray;       // Voxel values
    spacing: Vector3;       // Physical spacing
    matrix: Matrix4;        // IJK to RAS transform
    
    getData(i, j, k): number;
    extractSlice(axis, index): VolumeSlice;
}

VolumeSlice Rendering

VolumeSlice represents a 2D cross-section of the volume as a Mesh with a dynamically-generated texture. The updateGeometry() method positions the slice plane in RAS space, and repaint() extracts voxel data to a canvas texture:

VolumeSlice Architecture: Canvas texture → PlaneGeometry mesh

SVG
100%

NRRD Usage Example

import { NRRDLoader } from 'three/addons/loaders/NRRDLoader.js';

const loader = new NRRDLoader();
const volume = await loader.loadAsync('brain.nrrd');

// Create slice through the volume
const sliceZ = volume.extractSlice('z', Math.floor(volume.zLength / 2));
scene.add(sliceZ.mesh);

// Access voxel data
const value = volume.getData(128, 128, 64); // IJK coordinates
console.log(`Voxel value at (128,128,64): ${value}`);

// Volume properties
console.log(`Volume dimensions: ${volume.xLength} x ${volume.yLength} x ${volume.zLength}`);
console.log(`RAS dimensions: ${volume.RASDimensions.join(' x ')}`);

Common Loader Patterns

All Three.js loaders follow common architectural patterns inherited from the Loader base class:

Loader Base Class Integration

All loaders extend the Loader base class which provides common functionality like setPath(), setResourcePath(), setCrossOrigin(), and setRequestHeader(). The typical pattern is:

Common Loader Pattern: load() → FileLoader → parse()

SVG
100%

Coordinate System Conversion

Many formats use different coordinate systems (Z-up vs Y-up). Loaders handle this through transformation:

FormatNative Coordinate SystemConversion Strategy
FBXY-up (native)No conversion needed
ColladaZ-up or Y-up (specified in <up_axis>)Apply 90° X-rotation if Z-up
OBJY-upNo conversion needed
VRMLY-upNo conversion needed
STLZ-up (convention)Manual rotation recommended: object.rotation.set(-Math.PI/2, 0, 0)
3MFZ-up (3D printing standard)Manual rotation recommended

Material Default Handling

When materials are missing or unsupported, loaders use default materials:

// FBXLoader default material
const material = new MeshPhongMaterial({
    name: Loader.DEFAULT_MATERIAL_NAME,
    color: 0xcccccc
});

// OBJLoader default material  
const material = new MeshPhongMaterial();

// STLLoader - geometry only, no default material
// Application must provide material

Usage Examples

Loading FBX with Animations

import { FBXLoader } from 'three/addons/loaders/FBXLoader.js';

const loader = new FBXLoader();
const fbx = await loader.loadAsync('model.fbx');

scene.add(fbx);

// Access animations
if (fbx.animations && fbx.animations.length > 0) {
    const mixer = new THREE.AnimationMixer(fbx);
    const action = mixer.clipAction(fbx.animations[0]);
    action.play();
}

Loading OBJ with MTL Materials

import { OBJLoader } from 'three/addons/loaders/OBJLoader.js';
import { MTLLoader } from 'three/addons/loaders/MTLLoader.js';

// Load materials first
const mtlLoader = new MTLLoader();
const materials = await mtlLoader.loadAsync('model.mtl');
materials.preload();

// Load OBJ with materials
const objLoader = new OBJLoader();
objLoader.setMaterials(materials);
const object = await objLoader.loadAsync('model.obj');
scene.add(object);

Loading Point Cloud Data

import { PCDLoader } from 'three/addons/loaders/PCDLoader.js';

const loader = new PCDLoader();
const points = await loader.loadAsync('pointcloud.pcd');

// Points object contains geometry with position and color
points.geometry.center();
points.geometry.rotateX(Math.PI); // Z-up to Y-up
scene.add(points);

Loader Capabilities and Limitations

Format-Specific Limitations

FBXLoader:

ColladaLoader:

VRMLLoader:

STLLoader:

VTKLoader:

NRRDLoader:

Performance Considerations

  • Binary formats (binary FBX, binary STL, binary PLY) load faster than ASCII
  • Compressed formats (3MF, KMZ, compressed PCD) require decompression overhead via fflate
  • Large point clouds (PCD, PLY, XYZ) can create very large geometries - consider LOD or culling
  • Complex scenes (FBX, Collada) with many objects should use scene graph traversal optimization