Capítulo 810 de 859

Chapter 810: Custom BufferGeometry (Manual)

Core Idea

How BufferGeometry represents mesh data as parallel named BufferAttributes (position, normal, uv, color) per vertex, and how to build one by hand — including using indices so shared vertices aren't duplicated.

Key Concepts

  • BufferAttribute: a typed array holding one property (position, normal, uv, color…), with one entry per vertex.
  • Parallel arrays: the Nth entry across every attribute belongs to the same vertex.
  • Vertex uniqueness: a vertex must be duplicated per face whenever any attribute (typically normal or uv) differs between the faces sharing that corner — e.g. a cube needs 36 raw vertices (or 24 with indexing), not 8.
  • BufferGeometry.setIndex(): references shared vertices by index instead of repeating identical vertex data.
  • computeVertexNormals(): auto-generates normals, but produces visible seams on geometry meant to wrap seamlessly (spheres, cylinders) because it can't smooth across vertices that aren't actually shared.
  • Dynamic attributes: for geometry updated every frame, use Float32Array-backed attributes from the start and set attribute.needsUpdate = true after each change.

Code Examples

function makeSpherePositions(segmentsAround, segmentsDown) {
  const numVertices = segmentsAround * segmentsDown * 6;
  const positions = new Float32Array(numVertices * 3);
  const indices = [];
  // ...compute lat/long positions per quad, push 4 unique verts + 6 indices per quad
  return { positions, indices };
}
  • What it demonstrates: building position data and an index buffer for a sphere where quads don't share vertices with each other (so each quad can be animated independently).

Key Takeaways

  1. A BufferGeometry is a set of named parallel BufferAttributes, one entry per vertex.
  2. A vertex must be duplicated whenever any of its attributes differs between the faces touching it — this is why a cube needs more than 8 vertices.
  3. setIndex() lets you reference shared vertices instead of repeating identical vertex data.
  4. computeVertexNormals() can't smooth across a seam where positions aren't shared, so supply your own normals for geometry that must wrap seamlessly.
  5. For runtime-updated geometry, allocate TypedArrays up front and set needsUpdate = true on the changed attribute each frame.

Connects To

  • BufferGeometry: the class this whole technique builds directly on top of.