Documentation Index Fetch the complete documentation index at: https://mintlify.com/jscastro76/threebox/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Threadbox integrates with Mapbox GL JS’s sky and terrain layers to create immersive 3D environments. The sky layer simulates atmospheric perspective and sun position, while terrain adds elevation data for realistic landscapes.
Sky Layer
Basic Sky Setup
Enable the atmospheric sky layer:
const tb = new Threebox ( map , gl , {
sky: true ,
realSunlight: true // Automatically sync sky with sun
});
This creates a built-in sky layer that:
Shows atmospheric gradient
Positions sun based on time and location
Automatically updates with realSunlight
Manual Sky Creation
const tb = new Threebox ( map , gl );
// Create sky layer after initialization
tb . sky = true ;
// Or use internal method
tb . createSkyLayer ();
Sky Configuration
Threadbox uses Mapbox’s sky layer with automatic sun positioning:
map . on ( 'load' , () => {
const tb = new Threebox ( map , gl , {
sky: true ,
realSunlight: true
});
// Sky layer is automatically added with these properties:
// - Type: 'sky'
// - ID: 'sky-layer' (tb.skyLayerName)
// - Sun position: [azimuth, altitude] from tb.getSunSky()
});
Update Sky Position
Manually update sky with sun position:
// Get sun position for sky
const date = new Date ( '2024-06-21T16:00:00' );
const coords = map . getCenter ();
const sunPos = tb . getSunPosition ( date , [ coords . lng , coords . lat ]);
const sunSky = tb . getSunSky ( date , sunPos );
// Update sky layer
tb . updateSunSky ( sunSky );
Get Sun Sky Position
// Get current sun position for sky layer
const sunSky = tb . getSunSky ();
console . log ( 'Azimuth:' , sunSky [ 0 ]);
console . log ( 'Altitude:' , sunSky [ 1 ]);
// Get for specific date/position
const customDate = new Date ( '2024-12-21T12:00:00' );
const customPos = tb . getSunPosition ( customDate , [ - 122.4194 , 37.7749 ]);
const customSky = tb . getSunSky ( customDate , customPos );
Sky Layer Properties
Access the sky layer:
// Get sky layer ID
console . log ( tb . skyLayerName ); // 'sky-layer'
// Get layer from map
const skyLayer = map . getLayer ( tb . skyLayerName );
if ( skyLayer ) {
console . log ( 'Sky layer exists' );
}
Toggle Sky Layer
// Enable sky
tb . sky = true ;
// Disable sky (removes layer)
tb . sky = false ;
// Check if sky is enabled
if ( tb . sky ) {
console . log ( 'Sky layer is active' );
}
Terrain Layer
Basic Terrain Setup
Enable 3D terrain with elevation:
const tb = new Threebox ( map , gl , {
terrain: true ,
realSunlight: true // Automatically adjust terrain lighting
});
Manual Terrain Creation
const tb = new Threebox ( map , gl );
// Enable terrain after initialization
tb . terrain = true ;
// Or use internal method
tb . createTerrainLayer ();
Terrain Configuration
Threadbox uses Mapbox’s terrain with automatic source creation:
// Terrain source name
console . log ( tb . terrainSourceName ); // 'mapbox-dem'
// Terrain exaggeration
console . log ( tb . terrainExaggeration ); // 1.0
// Terrain raster layer (for lighting)
console . log ( tb . terrainLayerName ); // Auto-detected or ''
Custom Terrain Source
Add custom DEM (Digital Elevation Model) source:
map . on ( 'load' , () => {
// Add custom terrain source
map . addSource ( 'custom-dem' , {
'type' : 'raster-dem' ,
'url' : 'mapbox://mapbox.mapbox-terrain-dem-v1' ,
'tileSize' : 512 ,
'maxzoom' : 14
});
// Set terrain
map . setTerrain ({
'source' : 'custom-dem' ,
'exaggeration' : 1.5
});
const tb = new Threebox ( map , gl , {
realSunlight: true
});
});
Update Terrain Lighting
Adjust terrain brightness based on sun:
const sunPos = tb . getSunPosition ( new Date (), [ lng , lat ]);
tb . updateSunGround ( sunPos );
Toggle Terrain
// Enable terrain
tb . terrain = true ;
// Disable terrain
tb . terrain = false ;
// Check if terrain is enabled
if ( tb . terrain ) {
console . log ( 'Terrain is active' );
}
Combined Sky & Terrain
Complete Setup
map . on ( 'load' , () => {
const tb = new Threebox ( map , gl , {
defaultLights: false , // Use sun lighting instead
realSunlight: true , // Sun simulation
sky: true , // Atmospheric sky
terrain: true // 3D elevation
});
// Sky and terrain automatically sync with sun position
});
Time-of-Day Animation
Animate sun, sky, and terrain through the day:
let currentHour = 6 ;
function animateTimeOfDay () {
// Create date for current hour
const date = new Date ();
date . setHours ( currentHour );
date . setMinutes ( 0 );
// Get map center
const center = map . getCenter ();
const coords = [ center . lng , center . lat ];
// Update sun position
const sunPos = tb . getSunPosition ( date , coords );
tb . setSunlight ( date , coords );
// Update sky
const sunSky = tb . getSunSky ( date , sunPos );
tb . updateSunSky ( sunSky );
// Update terrain lighting
tb . updateSunGround ( sunPos );
// Increment hour
currentHour = ( currentHour + 0.5 ) % 24 ;
// Continue animation
setTimeout ( animateTimeOfDay , 1000 ); // Update every second
}
// Start animation
animateTimeOfDay ();
Location-Based Sky
Update sky when map moves:
map . on ( 'moveend' , () => {
if ( tb . sky ) {
const center = map . getCenter ();
const sunSky = tb . getSunSky ( new Date (), tb . getSunPosition ( new Date (), [ center . lng , center . lat ]));
tb . updateSunSky ( sunSky );
}
});
Advanced Configuration
Custom Sky Properties
Modify Mapbox sky layer directly:
map . on ( 'load' , () => {
const tb = new Threebox ( map , gl , { sky: true });
// Get sky layer
const skyLayer = map . getLayer ( tb . skyLayerName );
if ( skyLayer ) {
// Customize sky appearance
map . setPaintProperty ( tb . skyLayerName , 'sky-atmosphere-sun-intensity' , 5 );
map . setPaintProperty ( tb . skyLayerName , 'sky-atmosphere-color' , 'rgba(135, 206, 235, 1)' );
}
});
Terrain Exaggeration
Increase elevation for dramatic effect:
map . on ( 'load' , () => {
const tb = new Threebox ( map , gl );
// Add terrain with exaggeration
map . setTerrain ({
'source' : 'mapbox-dem' ,
'exaggeration' : 2.0 // 2x elevation
});
tb . terrain = true ;
tb . terrainExaggeration = 2.0 ;
});
Sky Gradient
Customize atmospheric gradient:
map . setPaintProperty ( tb . skyLayerName , 'sky-gradient' , [
'interpolate' ,
[ 'linear' ],
[ 'sky-radial-progress' ],
0.8 , 'rgba(135, 206, 235, 1)' , // Horizon
1 , 'rgba(0, 0, 50, 1)' // Zenith
]);
Conditional Loading Only enable sky/terrain when map pitch > 30° to save resources on 2D views
Update Frequency Update sun position every 1-5 minutes, not every frame
Terrain LOD Terrain automatically uses level-of-detail. Adjust maxzoom for performance.
Disable When Hidden Set sky: false and terrain: false when not visible
Complete Example
map . on ( 'load' , () => {
// Initialize Threebox with sky and terrain
const tb = new Threebox ( map , gl , {
defaultLights: false ,
realSunlight: true ,
realSunlightHelper: false ,
sky: true ,
terrain: true
});
// Set initial view
map . flyTo ({
center: [ - 119.5383 , 37.7153 ], // Yosemite
zoom: 13 ,
pitch: 75 ,
bearing: 40
});
// Add custom layer with 3D objects
map . addLayer ({
id: 'custom-layer' ,
type: 'custom' ,
renderingMode: '3d' ,
onAdd : function ( map , gl ) {
// Load 3D model
tb . loadObj ({
obj: '/models/tree.glb' ,
type: 'gltf' ,
scale: 5 ,
units: 'meters' ,
rotation: { x: 90 , y: 0 , z: 0 }
}, ( tree ) => {
tree . setCoords ([ - 119.5383 , 37.7153 , 1200 ]);
tree . castShadow = true ;
tb . add ( tree );
});
},
render : function ( gl , matrix ) {
tb . update ();
}
});
// Time control slider
const timeSlider = document . getElementById ( 'time-slider' );
timeSlider . addEventListener ( 'input' , ( e ) => {
const hour = parseInt ( e . target . value );
const date = new Date ();
date . setHours ( hour );
date . setMinutes ( 0 );
const center = map . getCenter ();
const coords = [ center . lng , center . lat ];
// Update everything
const sunPos = tb . getSunPosition ( date , coords );
tb . setSunlight ( date , coords );
const sunSky = tb . getSunSky ( date , sunPos );
tb . updateSunSky ( sunSky );
tb . updateSunGround ( sunPos );
document . getElementById ( 'time-display' ). textContent =
` ${ hour } :00 - ${ sunPos . altitude > 0 ? 'Day' : 'Night' } ` ;
});
// Auto-update based on pitch
map . on ( 'pitch' , () => {
const pitch = map . getPitch ();
if ( pitch < 30 && tb . sky ) {
tb . sky = false ; // Disable sky for 2D view
} else if ( pitch >= 30 && ! tb . sky ) {
tb . sky = true ; // Enable sky for 3D view
}
});
});
Troubleshooting
Ensure map pitch is > 0 (sky only visible in 3D view)
Check tb.sky === true
Verify sky layer exists: map.getLayer(tb.skyLayerName)
Make sure Mapbox GL JS version supports sky (v2.0+)
Verify terrain source is added before setting terrain
Check Mapbox GL JS version supports terrain (v2.0+)
Ensure tb.terrain === true
Verify you have a valid Mapbox access token
Sky/terrain not syncing with sun
Enable realSunlight: true in Threebox options
Manually call tb.updateSunSky() and tb.updateSunGround()
Verify date/coordinates are valid
See Also