Load Lego Models in Three.js with LDrawLoader

This article explains how to import and render realistic, Lego-like brick models in a web browser using Three.js and the LDrawLoader. You will learn how to configure the loader, set up the required LDraw parts library, and add the loaded 3D models directly into your Three.js scene with proper orientation and materials.

1. Prerequisites and Installation

To load LDraw models (.ldr or .mpd files), you need a standard Three.js setup. You must import both the core Three.js library and the LDrawLoader class, which is included in the Three.js addons directory.

Using ES modules, import the dependencies as follows:

import * as THREE from 'three';
import { LDrawLoader } from 'three/addons/loaders/LDrawLoader.js';

2. Setting Up the Three.js Scene

Before loading the model, set up a basic Three.js scene with a camera, renderer, and appropriate lighting. Because Lego bricks have reflective plastic surfaces, adding an ambient light and a directional light ensures the depth and edges of the bricks are visible.

const scene = new THREE.Scene();
scene.background = new THREE.Color(0xdeeeff);

const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(150, 150, 150);

const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);

// Add lighting
const ambientLight = new THREE.AmbientLight(0xffffff, 0.4);
scene.add(ambientLight);

const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);
dirLight.position.set(100, 150, 50);
scene.add(dirLight);

3. Configuring the LDrawLoader

LDraw files do not usually contain the 3D geometry of the bricks directly; instead, they contain references to standard Lego part IDs. The LDrawLoader must fetch these individual part geometries from an external parts library.

You must specify the path to this library using .setPartsLibraryPath() before loading your model. You can host the official LDraw library parts yourself or point to a remote repository.

const loader = new LDrawLoader();

// Point to the official LDraw parts library hosted online or locally
loader.setPartsLibraryPath('https://raw.githubusercontent.com/mrdoob/three.js/dev/examples/models/ldraw/officialLibrary/');

4. Loading and Positioning the Model

Use the .load() method to load your .ldr or .mpd file. The loader returns a THREE.Group containing the assembled Lego parts.

Note that LDraw uses a coordinate system where the Y-axis points downward, whereas Three.js uses a Y-up coordinate system. You must rotate the loaded group 180 degrees around the X-axis to orient the model correctly.

loader.load(
    'path/to/your/lego-model.ldr', 
    function ( group ) {
        // Correct the orientation (LDraw is Y-down, Three.js is Y-up)
        group.rotation.x = Math.PI;
        
        // Optional: Center the model in the scene
        const box = new THREE.Box3().setFromObject(group);
        const center = box.getCenter(new THREE.Vector3());
        group.position.sub(center);

        scene.add(group);
    },
    function ( xhr ) {
        console.log( (xhr.loaded / xhr.total * 100) + '% loaded' );
    },
    function ( error ) {
        console.error( 'An error occurred while loading the model:', error );
    }
);

5. Animation Loop

To display the scene and allow interaction, implement a standard requestAnimationFrame render loop.

function animate() {
    requestAnimationFrame(animate);
    renderer.render(scene, camera);
}
animate();