Skip to content

Three.js - Loading 3D Models

Creating every shape from scratch with code is impractical for complex scenes. The real power of 3D graphics comes from importing models created in dedicated 3D modeling software like Blender, Maya, or Cinema 4D. Three.js supports various model formats, but one stands out as the standard for the web.

The glTF (GL Transmission Format) is the format officially recommended by the Three.js team and the wider web 3D community. It’s often referred to as the “JPEG of 3D.”

  • Optimized for Web: It’s designed for efficient transmission and fast loading on the web.
  • Complete Scene Description: A glTF file can contain geometry, materials, textures, animations, skeletons (for rigged characters), and more in a single package.
  • PBR Materials: It fully supports Physically-Based Rendering (PBR) materials, which are the standard for realistic graphics.
  • Two Flavors: It comes in two versions: .gltf (a JSON file with external binary data and textures) and .glb (a single, binary file with everything packed inside). .glb is usually easier to handle.

Loading any model in Three.js follows a consistent three-step pattern:

  1. Import the appropriate Loader: Loaders for different formats are not part of the core Three.js library but are available as add-ons in the examples/jsm/loaders/ directory.
  2. Instantiate the loader and call .load(): The .load() method takes the model’s URL, a success callback function, an optional progress callback, and an error callback.
  3. Process the result in the success callback: The loaded data (e.g., the model’s scene) is passed to the callback. You then add this to your main Three.js scene.

Here’s a modern, complete example of loading a .glb file.

import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
// 1. Instantiate the loader
const gltfLoader = new GLTFLoader();
// 2. Call .load()
gltfLoader.load(
'/models/FlightHelmet/glTF/FlightHelmet.gltf', // URL to your model
(gltf) => { // Success callback
// The loaded data is a gltf object
console.log('Load successful!', gltf);
// gltf.scene contains the THREE.Group with all the meshes, lights, etc.
scene.add(gltf.scene);
},
(progress) => { // Progress callback (optional)
console.log('Loading model...', (progress.loaded / progress.total * 100) + '%');
},
(error) => { // Error callback (optional)
console.error('An error happened', error);
}
);

Pro Tip: Using async/await can make loading code cleaner, especially when you need to load multiple assets. You can promisify the loader’s .loadAsync() method.

async function loadModel() {
const gltfLoader = new GLTFLoader();
try {
const gltf = await gltfLoader.loadAsync('/models/myModel.glb');
scene.add(gltf.scene);
} catch (error) {
console.error('Failed to load model:', error);
}
}
loadModel();

Draco is an open-source library from Google for compressing 3D geometry. It can significantly reduce the file size of your models. A glTF model can be saved with Draco-compressed geometry. To load it, you need to provide GLTFLoader with a DRACOLoader instance.

import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
// Instantiate a loader
const gltfLoader = new GLTFLoader();
// Instantiate a Draco loader
const dracoLoader = new DRACOLoader();
// You must provide a path to the Draco decoder libraries.
// These files are in the three/examples/jsm/libs/draco/ folder.
// Copy them to your public/draco directory.
dracoLoader.setDecoderPath('/draco/');
// Tell the GLTFLoader to use the DracoLoader for compressed geometry
gltfLoader.setDRACOLoader(dracoLoader);
// Load the compressed model as usual
gltfLoader.load('/models/myCompressedModel.glb', (gltf) => {
scene.add(gltf.scene);
});

While glTF is preferred, you might encounter other formats.

A simple, text-based format that defines geometry. It’s often paired with an .mtl file for materials. It does not support animations. Use OBJLoader and, if needed, MTLLoader.

import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js';
import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader.js';
const mtlLoader = new MTLLoader();
mtlLoader.load('/models/myModel.mtl', (materials) => {
materials.preload();
const objLoader = new OBJLoader();
objLoader.setMaterials(materials);
objLoader.load('/models/myModel.obj', (object) => {
scene.add(object);
});
});

A format common in 3D printing and CAD. It only describes surface geometry and has no concept of color, materials, or textures. You must apply a material yourself after loading.

import { STLLoader } from 'three/examples/jsm/loaders/STLLoader.js';
const stlLoader = new STLLoader();
stlLoader.load('/models/my3DPrint.stl', (geometry) => {
const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
});

If your model doesn’t load or appears incorrectly, follow these steps:

  • Check the Console: Always check the browser’s developer console for errors. The error callback in the .load() method is your best friend here.
  • CORS Errors: If you see a Cross-Origin Resource Sharing (CORS) error, it means you’re trying to load files directly from your filesystem without a server. Use a local development server like Vite, which solves this problem.
  • Verify the Model: Open the model in another viewer (e.g., https://gltf-viewer.donmccurdy.com/ for glTF, or Blender). If it’s broken there, the issue is with the model file itself, not your code.
  • It’s Invisible! The model might be too big, too small, or your camera might be inside it. Try scaling the model down or up: gltf.scene.scale.set(0.1, 0.1, 0.1);. Also, make sure you have lights in your scene; many materials are black without light.
  • Missing Textures: Check the browser’s Network tab. If you see 404 errors for texture files, the paths inside your model file are likely incorrect. Paths should be relative to the model file (e.g., textures/diffuse.png, not C:\Users\...).

You don’t have to create everything yourself! Here are some great resources:

  • Sketchfab: A massive repository of 3D models, many available for free under Creative Commons licenses. You can download them directly in glTF format.
  • Poly Pizza: A great source for free, low-poly models in .glb format, perfect for web experiences.
  • Blender: The free and open-source 3D creation suite. It’s the perfect tool for creating your own models or converting other formats to glTF.