I have a Three.js scene consisting of many buildings which are formed by stacking ExtrudeGeometry
meshes (think buildings in Mapbox GL JS):
I'm creating these meshes using THREE.Shape
and THREE.ExtrudeGeometry
(I'm using react-three-fiber):
function coordsToShape(coords) {
const shape = new Shape();
let [x, z] = coords[0];
shape.moveTo(x, z);
for (const [x, z] of coords.slice(1)) {
shape.lineTo(x, z);
}
return shape;
}
function Floor(props) {
const {coords, bottom, top, color} = props;
const shape = coordsToShape(coords);
const geom = new ExtrudeGeometry(shape, {depth: top - bottom, bevelEnabled: false});
return (
<mesh castShadow geometry={geom} position={[0, bottom, 0]} rotation-x={-Math.PI / 2}>
<meshPhongMaterial color={color} />
</mesh>
)
}
Then I stack the floors to produce the scene:
export default function App() {
return (
<Canvas>
{ /* lights, controls, etc. */ }
<GroundPlane />
<Floor coords={coords1} bottom={0} top={1} color="skyblue" />
<Floor coords={coords2} bottom={1} top={3} color="pink" />
<Floor coords={coords3} bottom={0} top={1} color="aqua" />
<Floor coords={coords4} bottom={1} top={3} color="orange" />
</Canvas>
)
}
Full code/demo here. This results in one mesh for the ground plane and one for each building section, so five total.
I've read that using instancing to reduce the number of meshes is a good idea. Is instancing relevant to this scene? Most instancing examples show identical geometries with colors, positions and rotations varying. But can the geometry vary? Should I be using mergeBufferGeometries
? But if I do that, will I still get the performance wins? Since I have coordinate arrays already, I'd also be happy using them to construct a large buffer of coordinates directly.