Skip to content
Make with
m

maplibre-three-plugin

Three.js 3D rendering bridge

Maintained by dvt3d

Bridge Three.js 3D objects and scenes into MapLibre GL JS maps. Add 3D models, animations, and custom WebGL content to your maps.

Live demo

maplibre-three-plugin running on MapLibre GL JS in your browser

Loading the map…

Demo code
import * as THREE from "three";
import { MapScene, Creator, SceneTransform } from "@dvt3d/maplibre-three-plugin";
import type { PluginDemo } from "../types";

export default {
  center: [2.2975, 48.8555], // the Champ de Mars, Paris
  zoom: 16,
  pitch: 60,
  bearing: -20,
  run({ map }) {
    // A three.js scene rendered into the map, with lights.
    // (The cast only bridges the plugin's narrower typing of the map.)
    const scene = new MapScene(map as never);
    scene.addLight(new THREE.AmbientLight(0xffffff, 1.5));
    const sun = new THREE.DirectionalLight(0xffffff, 2);
    sun.position.set(100, 300, 200);
    scene.addLight(sun);

    // A group anchored at a coordinate, in meters with y up (the plugin's defaults).
    const anchor = [2.2985, 48.8562];
    const meters = SceneTransform.projectedUnitsPerMeter(anchor[1]);
    const group = Creator.createRTCGroup(
      anchor,
      [Math.PI / 2, Math.PI, 0],
      [meters, meters, meters],
    );

    // A stack of boxes, 15 m per level.
    [0xe4572e, 0xf3a712, 0x29335c, 0x669bbc].forEach((color, i) => {
      const size = 80 - i * 16;
      const box = new THREE.Mesh(
        new THREE.BoxGeometry(size, 15, size),
        new THREE.MeshStandardMaterial({ color }),
      );
      box.position.y = 7.5 + i * 15;
      group.add(box);
    });
    scene.addObject(group);
  },
} satisfies PluginDemo;