Overview
The extrusion feature allows you to create 3D shapes by extruding 2D polygons vertically. This is perfect for creating buildings, walls, terrain features, or any custom 3D geometry based on geographic coordinates.
Basic Usage
const extrusion = tb . extrusion ({
coordinates: [
[
[ - 122.4194 , 37.7749 ],
[ - 122.4184 , 37.7749 ],
[ - 122.4184 , 37.7739 ],
[ - 122.4194 , 37.7739 ],
[ - 122.4194 , 37.7749 ] // Close the polygon
]
],
height: 100 ,
materials: new THREE . MeshStandardMaterial ({ color: 0x660000 })
});
extrusion . setCoords ([ - 122.4194 , 37.7749 ]);
tb . add ( extrusion );
API Signature
Options
Parameter Type Default Description coordinatesArray[[[]]]Nested array of polygon coordinates (GeoJSON format) geometryOptionsobject{}Three.js ExtrudeGeometry settings heightnumber100Extrusion height materialsTHREE.MaterialMeshPhongMaterialMaterial for the extruded shape scalenumber | {x,y,z}1Scale factor rotationnumber | {x,y,z}0Rotation in degrees units'scene' | 'meters''scene'Coordinate system anchorstring'center'Anchor point for positioning bboxbooleantrueShow bounding box when selected tooltipbooleantrueEnable tooltip raycastedbooleantrueInclude in raycasting
Extrusions accept coordinates in GeoJSON polygon format:
Simple Polygon
const coordinates = [
[ // Outer ring
[ - 122.4194 , 37.7749 ], // Point 1
[ - 122.4184 , 37.7749 ], // Point 2
[ - 122.4184 , 37.7739 ], // Point 3
[ - 122.4194 , 37.7739 ], // Point 4
[ - 122.4194 , 37.7749 ] // Close the ring (same as Point 1)
]
];
Polygon with Holes
const coordinates = [
[ // Outer ring
[ - 122.4200 , 37.7750 ],
[ - 122.4180 , 37.7750 ],
[ - 122.4180 , 37.7730 ],
[ - 122.4200 , 37.7730 ],
[ - 122.4200 , 37.7750 ]
],
[ // Inner ring (hole)
[ - 122.4195 , 37.7745 ],
[ - 122.4185 , 37.7745 ],
[ - 122.4185 , 37.7735 ],
[ - 122.4195 , 37.7735 ],
[ - 122.4195 , 37.7745 ]
]
];
The first array is the outer boundary, and subsequent arrays define holes within the shape.
Creating Extrusions
Simple Building
const building = tb . extrusion ({
coordinates: [
[
[ - 73.9857 , 40.7484 ],
[ - 73.9847 , 40.7484 ],
[ - 73.9847 , 40.7474 ],
[ - 73.9857 , 40.7474 ],
[ - 73.9857 , 40.7484 ]
]
],
height: 200 ,
materials: new THREE . MeshStandardMaterial ({
color: 0x2194ce ,
metalness: 0.5 ,
roughness: 0.5
}),
units: 'meters'
});
building . setCoords ([ - 73.9857 , 40.7484 ]);
tb . add ( building );
Building with Courtyard
const buildingWithCourtyard = tb . extrusion ({
coordinates: [
// Outer perimeter
[
[ - 122.420 , 37.775 ],
[ - 122.418 , 37.775 ],
[ - 122.418 , 37.773 ],
[ - 122.420 , 37.773 ],
[ - 122.420 , 37.775 ]
],
// Courtyard (hole)
[
[ - 122.4195 , 37.7745 ],
[ - 122.4185 , 37.7745 ],
[ - 122.4185 , 37.7735 ],
[ - 122.4195 , 37.7735 ],
[ - 122.4195 , 37.7745 ]
]
],
height: 150 ,
materials: new THREE . MeshStandardMaterial ({ color: 0x8B4513 })
});
buildingWithCourtyard . setCoords ([ - 122.419 , 37.774 ]);
tb . add ( buildingWithCourtyard );
Geometry Options
The geometryOptions parameter accepts Three.js ExtrudeGeometry settings:
const extrusion = tb . extrusion ({
coordinates: [[
[ - 122.4194 , 37.7749 ],
[ - 122.4184 , 37.7749 ],
[ - 122.4184 , 37.7739 ],
[ - 122.4194 , 37.7739 ],
[ - 122.4194 , 37.7749 ]
]],
geometryOptions: {
depth: 100 , // Extrusion depth
bevelEnabled: true , // Enable beveled edges
bevelThickness: 2 , // Bevel depth
bevelSize: 2 , // Bevel height
bevelSegments: 3 , // Bevel smoothness
steps: 1 , // Depth subdivisions
curveSegments: 12 // Curve smoothness
},
materials: new THREE . MeshStandardMaterial ({ color: 0x660000 })
});
Use bevelEnabled: true to create rounded edges on buildings and other architectural features.
Advanced Examples
Multi-Material Extrusion
// Different materials for walls and top
const materials = [
new THREE . MeshStandardMaterial ({ color: 0x808080 }), // Walls
new THREE . MeshStandardMaterial ({ color: 0x404040 }) // Top/Bottom
];
const building = tb . extrusion ({
coordinates: [[
[ - 122.4194 , 37.7749 ],
[ - 122.4184 , 37.7749 ],
[ - 122.4184 , 37.7739 ],
[ - 122.4194 , 37.7739 ],
[ - 122.4194 , 37.7749 ]
]],
height: 200 ,
materials: materials
});
From GeoJSON Feature
function extrudeGeoJSON ( feature , height , color ) {
return tb . extrusion ({
coordinates: feature . geometry . coordinates ,
height: height || feature . properties . height || 100 ,
materials: new THREE . MeshStandardMaterial ({
color: color || feature . properties . color || 0x660000
}),
units: 'meters'
});
}
// Use with GeoJSON feature
const buildingFeature = {
type: 'Feature' ,
geometry: {
type: 'Polygon' ,
coordinates: [[
[ - 122.4194 , 37.7749 ],
[ - 122.4184 , 37.7749 ],
[ - 122.4184 , 37.7739 ],
[ - 122.4194 , 37.7739 ],
[ - 122.4194 , 37.7749 ]
]]
},
properties: {
height: 150 ,
color: 0x2194ce
}
};
const building = extrudeGeoJSON ( buildingFeature );
building . setCoords ([ - 122.4189 , 37.7744 ]);
tb . add ( building );
Complex Shape with Custom Geometry
const complexBuilding = tb . extrusion ({
coordinates: [
[ // L-shaped building
[ - 122.420 , 37.775 ],
[ - 122.419 , 37.775 ],
[ - 122.419 , 37.774 ],
[ - 122.418 , 37.774 ],
[ - 122.418 , 37.773 ],
[ - 122.420 , 37.773 ],
[ - 122.420 , 37.775 ]
]
],
geometryOptions: {
depth: 100 ,
bevelEnabled: true ,
bevelThickness: 1 ,
bevelSize: 1 ,
bevelSegments: 2
},
materials: new THREE . MeshStandardMaterial ({
color: 0x996633 ,
metalness: 0.3 ,
roughness: 0.7
})
});
complexBuilding . setCoords ([ - 122.419 , 37.774 ]);
tb . add ( complexBuilding );
Working with Vector2
You can also use Three.js Vector2 arrays directly:
const points = [
new THREE . Vector2 ( 0 , 0 ),
new THREE . Vector2 ( 100 , 0 ),
new THREE . Vector2 ( 100 , 100 ),
new THREE . Vector2 ( 0 , 100 ),
new THREE . Vector2 ( 0 , 0 )
];
const extrusion = tb . extrusion ({
coordinates: points ,
height: 50 ,
materials: new THREE . MeshStandardMaterial ({ color: 0xff0000 }),
units: 'scene'
});
Common Patterns
City Block Generator
function createCityBlock ( center , blockSize , buildingCount ) {
const buildings = [];
const spacing = blockSize / buildingCount ;
for ( let i = 0 ; i < buildingCount ; i ++ ) {
for ( let j = 0 ; j < buildingCount ; j ++ ) {
const x = center [ 0 ] + ( i - buildingCount / 2 ) * spacing ;
const y = center [ 1 ] + ( j - buildingCount / 2 ) * spacing ;
const size = spacing * 0.8 ;
const building = tb . extrusion ({
coordinates: [[
[ x , y ],
[ x + size , y ],
[ x + size , y + size ],
[ x , y + size ],
[ x , y ]
]],
height: Math . random () * 200 + 50 ,
materials: new THREE . MeshStandardMaterial ({
color: Math . random () * 0xffffff
})
});
building . setCoords ([ x + size / 2 , y + size / 2 ]);
tb . add ( building );
buildings . push ( building );
}
}
return buildings ;
}
// Create a 5x5 grid of buildings
const cityBlock = createCityBlock ([ - 122.4194 , 37.7749 ], 0.01 , 5 );
Terrain Feature
function createWall ( start , end , height , thickness ) {
// Calculate perpendicular offset for thickness
const dx = end [ 0 ] - start [ 0 ];
const dy = end [ 1 ] - start [ 1 ];
const len = Math . sqrt ( dx * dx + dy * dy );
const offsetX = - dy / len * thickness ;
const offsetY = dx / len * thickness ;
return tb . extrusion ({
coordinates: [[
[ start [ 0 ], start [ 1 ]],
[ end [ 0 ], end [ 1 ]],
[ end [ 0 ] + offsetX , end [ 1 ] + offsetY ],
[ start [ 0 ] + offsetX , start [ 1 ] + offsetY ],
[ start [ 0 ], start [ 1 ]]
]],
height: height ,
materials: new THREE . MeshStandardMaterial ({
color: 0x8B7355 ,
roughness: 0.9
})
});
}
const wall = createWall (
[ - 122.420 , 37.775 ],
[ - 122.418 , 37.775 ],
10 ,
0.0001
);
wall . setCoords ([ - 122.419 , 37.775 ]);
tb . add ( wall );
Implementation Details
The extrusion feature uses Three.js geometry classes internally:
src/objects/extrusion.js:14-25
function extrusion ( opt ) {
opt = utils . _validate ( opt , Objects . prototype . _defaults . extrusion );
let shape = extrusion . prototype . buildShape ( opt . coordinates );
let geometry = extrusion . prototype . buildGeometry ( shape , opt . geometryOptions );
let mesh = new THREE . Mesh ( geometry , opt . materials );
opt . obj = mesh ;
return new Object3D ( opt );
}
Building the Shape
src/objects/extrusion.js:28-39
buildShape : function ( coords ) {
if ( coords [ 0 ] instanceof ( THREE . Vector2 || THREE . Vector3 ))
return new THREE . Shape ( coords );
let shape = new THREE . Shape ();
for ( let i = 0 ; i < coords . length ; i ++ ) {
if ( i === 0 ) {
shape = new THREE . Shape ( this . buildPoints ( coords [ 0 ], coords [ 0 ]));
} else {
shape . holes . push ( new THREE . Path ( this . buildPoints ( coords [ i ], coords [ 0 ])));
}
}
return shape ;
}
Converting Coordinates
src/objects/extrusion.js:41-49
buildPoints : function ( coords , initCoords ) {
const points = [];
let init = utils . projectToWorld ([ initCoords [ 0 ][ 0 ], initCoords [ 0 ][ 1 ], 0 ]);
for ( let i = 0 ; i < coords . length ; i ++ ) {
let pos = utils . projectToWorld ([ coords [ i ][ 0 ], coords [ i ][ 1 ], 0 ]);
points . push ( new THREE . Vector2 (
utils . toDecimal (( pos . x - init . x ), 9 ),
utils . toDecimal (( pos . y - init . y ), 9 )
));
}
return points ;
}
Coordinates are converted to world space and normalized to prevent floating-point precision issues.
Keep polygon vertex count reasonable (< 100 vertices)
Simplify complex shapes when possible
Use bevel settings sparingly for better performance
Share materials across multiple extrusions
Use simpler materials for distant objects
Consider texture atlases for many buildings
Group extrusions with similar properties
Consider merging geometries for static scenes
Use instancing for repeated shapes
Next Steps
Primitives Create spheres, lines, and tubes
Materials & Lighting Configure materials and scene lighting