Load and Visualize PCD Point Clouds with Three.js

This article explains how to load, parse, and render 3D point cloud data from external .pcd files using the PCDLoader in Three.js. You will learn how to set up the necessary boilerplate scene, import the loader, retrieve the point data, and customize its appearance for web-based 3D visualization.

1. Import Three.js and PCDLoader

To work with Point Cloud Data (PCD) files, you must import both the core Three.js library and the specific PCDLoader module from the Three.js examples folder.

import * as THREE from 'three';
import { PCDLoader } from 'three/addons/loaders/PCDLoader.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

2. Set Up the 3D Scene

Before loading the file, create a basic Three.js environment consisting of a scene, a camera, a renderer, and orbit controls to navigate the 3D space.

// Create scene
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x111111);

// Create camera
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 0, 10);

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

// Add controls
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;

3. Load and Parse the PCD File

Instantiate the PCDLoader and use its .load() method to fetch and parse the external .pcd file. Once parsed, the loader returns a THREE.Points object containing the geometry (vertices and optional colors) and a default material.

const loader = new PCDLoader();

// Load a resource
loader.load(
    'models/pointcloud.pcd', // Replace with your actual file path
    function (points) {
        // Success callback: customize point size and add to scene
        points.material.size = 0.05; 
        points.material.color.setHex(0x00ff00); // Set points to green
        
        // Center the point cloud geometry
        points.geometry.center();
        
        scene.add(points);
        console.log('PCD file loaded successfully.');
    },
    function (xhr) {
        // Progress callback
        console.log((xhr.loaded / xhr.total * 100) + '% loaded');
    },
    function (error) {
        // Error callback
        console.error('An error occurred while loading the PCD file:', error);
    }
);

4. Render Loop

To display the loaded point cloud and allow interactive navigation, set up the standard Three.js animation and render loop.

function animate() {
    requestAnimationFrame(animate);
    
    // Update controls for damping effect
    controls.update();
    
    renderer.render(scene, camera);
}

// Handle window resizing
window.addEventListener('resize', () => {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
});

animate();