Camera Types
Threebox supports two camera types: Perspective (default) and Orthographic. Each offers different visual characteristics for your 3D scene.
Perspective Camera (Default)
The default camera type uses Three.js PerspectiveCamera with customizable field of view (FOV).
Field of View (FOV)
Control the camera’s FOV to adjust the viewing angle:
this . fov = this . options . fov ;
this . orthographic = this . options . orthographic || false ;
window . tb = new Threebox (
map ,
map . getCanvas (). getContext ( 'webgl' ),
{
defaultLights: true ,
fov: 37 // Default from ThreeboxConstants.FOV_DEGREES
}
);
FOV Property
The fov property can be set dynamically:
get fov () {
return this . options . fov ;
}
set fov ( value ) {
if ( this . camera instanceof THREE . PerspectiveCamera && this . options . fov !== value ) {
this . map . transform . fov = value ;
this . camera . fov = this . map . transform . fov ;
this . cameraSync . setupCamera ();
this . map . repaint = true ;
this . options . fov = value ;
}
}
FOV Limitations:
Valid range: 0.01 to 60 degrees (Mapbox limitation)
Below 2.5 degrees: Serious polygon and depth issues
Above 45 degrees: Clipping and performance problems
Minimum value of 0 becomes 0.01 automatically
Orthographic Camera
Orthographic projection displays objects without perspective distortion, useful for architectural or technical visualizations.
Enabling Orthographic View
window . tb = new Threebox (
map ,
map . getCanvas (). getContext ( 'webgl' ),
{
defaultLights: true ,
orthographic: true // Enable orthographic camera
}
);
Implementation Details
get orthographic () {
return this . options . orthographic ;
}
set orthographic ( value ) {
const h = this . map . getCanvas (). clientHeight ;
const w = this . map . getCanvas (). clientWidth ;
if ( value ) {
// Switch to orthographic camera
this . map . transform . fov = 0 ;
this . camera = new THREE . OrthographicCamera (
w / - 2 , w / 2 , h / 2 , h / - 2 , 0.1 , 1e21
);
} else {
// Switch to perspective camera
this . map . transform . fov = this . fov ;
this . camera = new THREE . PerspectiveCamera (
this . map . transform . fov , w / h , 0.1 , 1e21
);
}
this . camera . layers . enable ( 0 );
this . camera . layers . enable ( 1 );
this . cameraSync = new CameraSync ( this . map , this . camera , this . world );
this . map . repaint = true ;
this . options . orthographic = value ;
}
Runtime Camera Switching
// Start with perspective
window . tb = new Threebox ( map , gl , { orthographic: false });
// Switch to orthographic
tb . orthographic = true ;
// Switch back to perspective
tb . orthographic = false ;
Switching camera types at runtime recreates the camera and camera sync objects.
Camera Compatibility
With Fill-Extrusions
Orthographic + Fill-Extrusions: Pure orthographic view (FOV = 0) is not fully supported by Mapbox and causes:
Polygon rendering issues
Depth calculation problems
Fill-extrusion artifacts
Solution: Use orthographic: false with fov: 2.5 for near-orthographic view compatible with fill-extrusions.
// Orthographic-like view compatible with fill-extrusions
window . tb = new Threebox (
map ,
map . getCanvas (). getContext ( 'webgl' ),
{
defaultLights: true ,
orthographic: false , // Keep perspective camera
fov: 2.5 // Minimal FOV for near-orthographic look
}
);
Camera Configuration Matrix
Use Case orthographic fov Notes Default 3D false37Standard perspective view Wide Angle false45-60Wider view, may have clipping Narrow View false15-30Closer to orthographic feel Near-Ortho + Fill-Extrusions false2.5Minimal perspective, compatible Pure Orthographic trueN/A No fill-extrusions support Technical/Architectural trueN/A Pure orthographic, 3D objects only
Best Practices
3D Models Only Use orthographic: true when working exclusively with 3D models
With Fill-Extrusions Use orthographic: false, fov: 2.5 for near-orthographic with fill-extrusions
Wide Scenes Use moderate FOV (30-45) for large area visualization
Detail Work Use lower FOV (15-30) for focused, detailed views
Advanced Example
let map = new mapboxgl . Map ({
container: 'map' ,
style: 'mapbox://styles/mapbox/streets-v11' ,
center: [ - 74.0066 , 40.7135 ],
zoom: 16 ,
pitch: 60
});
let tb = new Threebox (
map ,
map . getCanvas (). getContext ( 'webgl' ),
{
defaultLights: true ,
orthographic: false ,
fov: 28 // Comfortable middle ground
}
);
// Camera control UI
const cameraControls = {
perspective : () => {
tb . orthographic = false ;
tb . fov = 37 ;
},
nearOrthographic : () => {
tb . orthographic = false ;
tb . fov = 2.5 ;
},
orthographic : () => {
tb . orthographic = true ;
},
wideAngle : () => {
tb . orthographic = false ;
tb . fov = 50 ;
}
};
// Bind to UI buttons
document . getElementById ( 'perspective' ). onclick = cameraControls . perspective ;
document . getElementById ( 'ortho' ). onclick = cameraControls . orthographic ;
Camera Sync
Both camera types use the CameraSync class to synchronize with Mapbox camera:
this . cameraSync = new CameraSync (
this . map ,
this . camera ,
this . world
);
The CameraSync handles:
Camera movement synchronization
Zoom level adjustments
Pitch and bearing updates
Projection matrix calculations
Camera changes trigger map.repaint = true automatically to ensure the scene re-renders.