Capítulo 835 de 859

Chapter 835: Optimize Lots of Objects (Manual)

Core Idea

Every Mesh is a separate draw request; when a scene needs thousands of similar objects (like ~19,000 boxes on a data globe), merging them into one BufferGeometry turns thousands of draw calls into one, which can take a scene from under 20fps to 60fps.

Key Concepts

  • Draw-call overhead: drawing N separate meshes costs more than drawing the equivalent geometry merged into one mesh, even if the visual result is identical.
  • Positioning without per-object scene-graph nodes: a small shared hierarchy of helper Object3Ds (e.g. lonHelperlatHelperpositionHelper) computes a world position/orientation on a sphere via rotation, reused for every data point instead of creating 3 extra scene-graph nodes per box — avoiding tens of thousands of unnecessary node updates.
  • geometry.applyMatrix4(helper.matrixWorld): bakes a computed transform directly into a geometry's vertices at creation time, so the resulting mesh doesn't need its own transform node to end up in the right place.
  • Per-vertex color via a color BufferAttribute: adding a color attribute to each box's geometry before merging lets every merged box keep an individual color (e.g. hue mapped from its data value) even though they're now one draw call.
  • BufferGeometryUtils.mergeGeometries(): combines an array of individually-transformed geometries into a single geometry for one mesh/one draw call.

Code Examples

lonHelper.rotation.y = THREE.MathUtils.degToRad(lonNdx) + lonFudge;
latHelper.rotation.x = THREE.MathUtils.degToRad(latNdx) + latFudge;
positionHelper.scale.set(0.005, 0.005, THREE.MathUtils.lerp(0.01, 0.5, amount));
originHelper.updateWorldMatrix(true, false);
geometry.applyMatrix4(originHelper.matrixWorld);
geometries.push(geometry);
// ...later: BufferGeometryUtils.mergeGeometries(geometries)
  • What it demonstrates: using a small reusable helper hierarchy to compute and bake a per-data-point transform into its geometry before merging thousands of such geometries into one draw call.

Key Takeaways

  1. Thousands of small meshes cost more to draw than the same geometry merged into one mesh, even at identical visual output.
  2. Reuse a single small helper Object3D hierarchy to compute positions instead of creating one per object — this avoids a large, unnecessary scene-graph update cost.
  3. Bake a computed transform into a geometry's vertices with applyMatrix4() when you're about to merge many geometries and don't need each one to have its own live transform node.
  4. Per-vertex colors (via a color attribute) preserve visual variation across a merged mesh that no longer has separate materials per object.

Connects To

  • MeshBasicMaterial: the material used for the merged/vertex-colored mesh in this example.
  • Optimize Lots of Objects, Animated (manual): the follow-up lesson that adds cross-dataset animation on top of this merged-geometry approach.