This guide shows you how to create your first Threebox scene with a simple 3D object.
Prerequisites
- Mapbox GL JS v2.2.0 or higher (or Azure Maps SDK)
- Threebox library
- Mapbox access token (or Azure subscription key)
Installation
Include Threebox from CDN:<!-- Mapbox GL JS -->
<link href="https://api.mapbox.com/mapbox-gl-js/v2.2.0/mapbox-gl.css" rel="stylesheet">
<script src="https://api.mapbox.com/mapbox-gl-js/v2.2.0/mapbox-gl.js"></script>
<!-- Threebox -->
<script src="https://cdn.jsdelivr.net/gh/jscastro76/threebox/dist/threebox.js"></script>
<link href="https://cdn.jsdelivr.net/gh/jscastro76/threebox/dist/threebox.css" rel="stylesheet" />
Install via npm:npm install threebox-plugin
Then import in your code:import { Threebox } from 'threebox-plugin';
import 'threebox-plugin/dist/threebox.css';
Configuration
Create a configuration file with your access token:
var config = {
accessToken: 'pk.your_mapbox_token_here'
}
For Azure Maps, add subscriptionKey: 'your_azure_key' to the config object.
Basic Example: Sphere
Here’s a complete working example that renders a red sphere on the map:
<!doctype html>
<head>
<title>Threebox Basic Example</title>
<link href="https://api.mapbox.com/mapbox-gl-js/v2.2.0/mapbox-gl.css" rel="stylesheet">
<script src="https://api.mapbox.com/mapbox-gl-js/v2.2.0/mapbox-gl.js"></script>
<script src="../dist/threebox.js"></script>
<link href="../dist/threebox.css" rel="stylesheet" />
<script src="config.js"></script>
<style>
body, html {
width: 100%;
height: 100%;
margin: 0;
}
#map {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id='map'></div>
<script type="module">
mapboxgl.accessToken = config.accessToken;
// Starting location for the map and sphere
var origin = [-122.4340, 37.7353, 1];
// Initialize the map
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/light-v9',
center: origin,
zoom: 17,
pitch: 60,
antialias: true
});
// Wait for map style to load
map.on('style.load', function() {
// Add a custom 3D layer
map.addLayer({
id: 'custom_layer',
type: 'custom',
renderingMode: '3d',
onAdd: function(map, mbxContext) {
// Initialize Threebox
window.tb = new Threebox(
map,
mbxContext,
{
defaultLights: true,
enableSelectingObjects: true
}
);
// Create a red sphere
var sphere = tb.sphere({
color: 'red',
material: 'MeshToonMaterial'
}).setCoords(origin);
// Add event listeners
sphere.addEventListener('ObjectMouseOver', onObjectMouseOver, false);
sphere.addEventListener('ObjectMouseOut', onObjectMouseOut, false);
// Add sphere to the scene
tb.add(sphere);
},
render: function(gl, matrix) {
tb.update();
}
});
});
// Event handlers
function onObjectMouseOver(e) {
console.log("Mouse over: " + e.detail.name);
}
function onObjectMouseOut(e) {
console.log("Mouse out: " + e.detail.name);
}
</script>
</body>
Code Breakdown
1. Initialize the Map
var map = new mapboxgl.Map({
container: 'map', // DOM element ID
style: 'mapbox://styles/mapbox/light-v9',
center: origin, // [lng, lat]
zoom: 17,
pitch: 60, // 3D perspective angle
antialias: true // Smooth 3D rendering
});
Set pitch to a value greater than 0 to enable 3D perspective. Values typically range from 0-60 degrees.
2. Create a Custom Layer
Threebox works within a Mapbox custom layer:
map.addLayer({
id: 'custom_layer',
type: 'custom',
renderingMode: '3d',
onAdd: function(map, mbxContext) {
// Initialize Threebox here
},
render: function(gl, matrix) {
// Update Threebox on each frame
tb.update();
}
});
3. Initialize Threebox
window.tb = new Threebox(
map, // Mapbox map instance
mbxContext, // Mapbox GL context
{
defaultLights: true, // Add default lighting
enableSelectingObjects: true // Enable object selection
}
);
4. Create and Add Objects
var sphere = tb.sphere({
color: 'red',
material: 'MeshToonMaterial'
}).setCoords(origin);
tb.add(sphere);
Threebox Initialization Options
Here are the key configuration options:
| Option | Type | Default | Description |
|---|
defaultLights | boolean | false | Add default scene lighting |
enableSelectingObjects | boolean | false | Enable 3D object selection |
enableSelectingFeatures | boolean | false | Enable fill-extrusion selection |
enableDraggingObjects | boolean | false | Enable dragging with [Shift] |
enableRotatingObjects | boolean | false | Enable rotation with [Alt] |
enableTooltips | boolean | false | Show default tooltips |
realSunlight | boolean | false | Use real sun position |
sky | boolean | false | Add atmospheric sky layer |
terrain | boolean | false | Enable terrain integration |
Common Geometries
Threebox provides built-in geometry helpers:
var sphere = tb.sphere({
radius: 50,
color: 'blue',
material: 'MeshStandardMaterial',
units: 'meters'
}).setCoords([lng, lat, altitude]);
Coordinate System
Threebox uses [longitude, latitude, altitude] coordinates:
// San Francisco coordinates
var origin = [-122.4340, 37.7353, 1];
// Set object position
sphere.setCoords(origin);
// Get object position
var coords = sphere.coordinates;
Updating the Scene
Call tb.update() in the render function to update the scene:
render: function(gl, matrix) {
tb.update(); // Required on every frame
}
Without tb.update(), objects won’t render or update properly.
Add Stats.js to monitor performance:
import Stats from 'https://threejs.org/examples/jsm/libs/stats.module.js';
let stats = new Stats();
map.getContainer().appendChild(stats.dom);
function animate() {
requestAnimationFrame(animate);
stats.update();
}
animate();
Complete Example with Multiple Objects
Here’s an example with multiple object types:
map.on('style.load', function() {
map.addLayer({
id: 'custom_layer',
type: 'custom',
renderingMode: '3d',
onAdd: function(map, mbxContext) {
window.tb = new Threebox(
map,
mbxContext,
{
defaultLights: true,
enableSelectingObjects: true,
enableTooltips: true
}
);
// Add a sphere
var sphere = tb.sphere({
radius: 30,
color: 'green',
material: 'MeshPhysicalMaterial',
units: 'meters'
}).setCoords([-122.3512, 47.6202, 0]);
tb.add(sphere);
// Add a box
var geometry = new THREE.BoxGeometry(30, 60, 120);
var redMaterial = new THREE.MeshPhongMaterial({
color: 0x660000,
side: THREE.DoubleSide
});
var cube = tb.Object3D({
obj: new THREE.Mesh(geometry, redMaterial),
units: 'meters'
}).setCoords([-122.34548, 47.617538, 0]);
cube.addTooltip("This is a red cube", true);
tb.add(cube);
// Add a line
var line = tb.line({
geometry: [
[-122.3512, 47.6202, 0],
[-122.34548, 47.617538, 50],
[-122.3491, 47.6207, 0]
],
width: 3,
color: 'yellow'
});
tb.add(line);
},
render: function(gl, matrix) {
tb.update();
}
});
});
Azure Maps Setup
To use Threebox with Azure Maps:
<!DOCTYPE html>
<html>
<head>
<!-- Azure Maps SDK -->
<link rel="stylesheet" href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/2/atlas.min.css" type="text/css">
<script src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/2/atlas.js"></script>
<!-- Threebox -->
<script src="../dist/threebox.js"></script>
<link href="../dist/threebox.css" rel="stylesheet" />
</head>
<body>
<div id="myMap" style="width: 100%; height: 100%;"></div>
<script>
// Initialize Azure Map
var map = new atlas.Map("myMap", {
center: [-122.3491, 47.6207],
subscriptionKey: config.subscriptionKey,
zoom: 16,
pitch: 60,
style: "satellite",
antialias: true
});
map.events.add("style.load", function() {
let intMap = map.map; // Get internal Mapbox GL map
window.tb = new Threebox(
intMap,
intMap.getCanvas().getContext('webgl'),
{ defaultLights: true }
);
intMap.addLayer({
id: 'custom_layer',
type: 'custom',
renderingMode: '3d',
onAdd: function(map, mbxContext) {
// Add 3D objects here
},
render: function(gl, matrix) {
tb.update();
}
});
});
</script>
</body>
</html>
Access the internal Mapbox GL map via map.map when using Azure Maps.
Troubleshooting
Objects not appearing?
- Ensure
tb.update() is called in the render function
- Check that coordinates are valid [lng, lat, alt]
- Verify the map has loaded (
style.load event)
- Confirm
renderingMode: '3d' is set
Performance issues?
- Reduce the number of objects
- Use lower-poly models
- Disable shadows if not needed
- Check Stats.js for FPS monitoring
GLB models not loading?
- Add
.glb MIME type to your web server config
- Ensure the file path is correct
- Check browser console for errors
Next Steps
Load 3D Models
Learn how to load and configure GLB/GLTF models
Add Animations
Animate objects along paths
Enable Interactions
Add selection, dragging, and rotation
API Reference
Complete API documentation