Documentation
    Preparing search index...

    Class BufferGeometry

    Vertex positions plus optional indices — the geometry every MVP-tier renderable draws (§53).

    const geometry = new BufferGeometry({
    positions: new Float32Array([0, 0, 0, 1, 0, 0, 0, 1, 0]),
    });
    geometry.computeBounds(); // { min: (0,0,0), max: (1,1,0) }
    geometry.dispose(); // §83: explicit lifetime

    Geometries are shared, not owned by nodes: any number of Renderables may point at one, and disposing it is the job of whoever created it (§83).

    Hierarchy (View Summary)

    Index
    id: string

    Stable identity (§53), assigned at construction from a monotonic counter and formatted geometry-<n>. Unique within a process, ascending in construction order, never reused — and, crucially, never copied: a clone is a different geometry and gets the next id (see Geometry.clone).

    • get bounds(): BoundingVolume

      This geometry's local BoundingVolume — §53's bounds field, spelled as a getter so that it cannot go stale.

      Identical to calling BufferGeometry.computeBounds, down to the identity of the returned object: reading the property recomputes exactly when the method would.

      Returns BoundingVolume

    • get byteLength(): number

      Bytes this geometry holds (§83, §84's bufferMemory) — the sum of the byteLengths of positions and whichever of normals, uvs, colors, joints, weights, positions1, normals1, and indices are present, and therefore exactly what a backend uploads for it.

      // 3 vertices × 3 floats × 4 bytes
      new BufferGeometry({ positions: new Float32Array(9) }).byteLength; // 36

      0 once disposed, because a disposed geometry holds nothing — that is the same fact positions reports by becoming empty, stated as a single rule so that a write into a disposed geometry (already a §83 "disposed resource still in use" mistake) cannot resurrect its bytes in the process-wide totals.

      Derived on every read rather than cached: it is five property reads and an addition, nothing on the draw path calls it, and a cached copy would be one more thing an in-place edit could invalidate.

      Returns number

    • get colors(): Float32Array<ArrayBufferLike> | undefined

      Optional per-vertex straight RGBA colors, or undefined for a geometry that carries none (§53, §60a). Held by reference, like BufferGeometry.positions, and subject to the same rules: assigning validates (four floats per vertex, index-aligned, finite, §85) and bumps the version; in-place edits are invisible and need BufferGeometry.markDirty — which is the fast path a debug-draw overlay rewriting its segment colors every frame takes. Assigning undefined drops the attribute; a vertexColors material drawing a color-less geometry then multiplies by GL's constant default (0, 0, 0, 1), i.e. renders black.

      Replacing positions with an array of a different vertex count while colors are present therefore throws: drop or replace the colors first.

      Returns Float32Array<ArrayBufferLike> | undefined

    • set colors(value: Float32Array<ArrayBufferLike> | undefined): void

      Parameters

      • value: Float32Array<ArrayBufferLike> | undefined

      Returns void

    • get disposed(): boolean

      Whether BufferGeometry.dispose has run.

      Returns boolean

    • get drawCount(): number

      Number of elements one draw call issues: the index count when indexed, the vertex count otherwise. Always a whole number of primitives.

      Returns number

    • get indices(): GeometryIndexArray | undefined

      Optional index buffer, or undefined for sequential vertices. Assigning validates against the current positions and mode and bumps the version; assigning undefined drops indexing (and then requires a vertex count that divides into whole primitives).

      Returns GeometryIndexArray | undefined

    • set indices(value: GeometryIndexArray | undefined): void

      Parameters

      Returns void

    • get joints(): Uint16Array<ArrayBufferLike> | undefined

      Optional per-vertex joint indices as quadruplets, or undefined for a geometry no skin influences (§53, §54; RFC 0003). Held by reference, like BufferGeometry.positions, and subject to the same rules: assigning validates (four entries per vertex, index-aligned, §85) and bumps the version; in-place edits are invisible and need BufferGeometry.markDirty. Assigning undefined drops the attribute — the geometry then never draws skinned, whatever skeleton its mesh carries (the render list warns about the mismatch in a development build).

      Each entry indexes Skeleton.bones (§33: insertion order is the ABI) and is deliberately not range-checked here — see the module header.

      Returns Uint16Array<ArrayBufferLike> | undefined

    • set joints(value: Uint16Array<ArrayBufferLike> | undefined): void

      Parameters

      • value: Uint16Array<ArrayBufferLike> | undefined

      Returns void

    • get mode(): GeometryDrawMode

      Primitive assembly. Assigning re-validates the buffers against the new mode — switching a triangle geometry to "lines" fails unless the counts divide by 2 — and bumps the version.

      Returns GeometryDrawMode

    • set mode(value: GeometryDrawMode): void

      Parameters

      Returns void

    • get normals(): Float32Array<ArrayBufferLike> | undefined

      Optional per-vertex normals, or undefined for an attribute-free layout (§53, §68). Held by reference, like BufferGeometry.positions, and subject to the same rules: assigning validates (index-aligned with positions, finite, §85) and bumps the version; in-place edits need BufferGeometry.markDirty. Assigning undefined drops the attribute — the geometry draws unlit-only from then on (a lit draw of a normal-less geometry shades from its ambient term alone; see @fourjs/render-webgl).

      Replacing positions with an array of a different vertex count while normals are present therefore throws: drop or replace the normals first.

      Returns Float32Array<ArrayBufferLike> | undefined

    • set normals(value: Float32Array<ArrayBufferLike> | undefined): void

      Parameters

      • value: Float32Array<ArrayBufferLike> | undefined

      Returns void

    • get normals1(): Float32Array<ArrayBufferLike> | undefined

      Optional first morph-target normals, or undefined (§54 GPU morph). Location 7. Same assignment rules as BufferGeometry.normals.

      Returns Float32Array<ArrayBufferLike> | undefined

    • set normals1(value: Float32Array<ArrayBufferLike> | undefined): void

      Parameters

      • value: Float32Array<ArrayBufferLike> | undefined

      Returns void

    • get positions(): Float32Array

      Vertex positions as xyz triplets. The array is held by reference, not copied — a builder that generated it hands over ownership, and a renderer may upload straight from it.

      Assigning a new array validates it (§85) and bumps BufferGeometry.version. Editing the existing array in place is legal and cheap, but invisible here: call BufferGeometry.markDirty afterwards.

      Returns Float32Array

    • set positions(value: Float32Array): void

      Parameters

      • value: Float32Array

      Returns void

    • get positions1(): Float32Array<ArrayBufferLike> | undefined

      Optional first morph-target positions, or undefined (§54 GPU morph). Location 6. Same assignment rules as BufferGeometry.normals.

      Returns Float32Array<ArrayBufferLike> | undefined

    • set positions1(value: Float32Array<ArrayBufferLike> | undefined): void

      Parameters

      • value: Float32Array<ArrayBufferLike> | undefined

      Returns void

    • get uvs(): Float32Array<ArrayBufferLike> | undefined

      Optional per-vertex texture coordinates as uv pairs, or undefined for a geometry that carries none (§53, §55). Held by reference, like BufferGeometry.positions, and subject to the same rules: assigning validates (two floats per vertex, index-aligned, finite, §85) and bumps the version; in-place edits are invisible and need BufferGeometry.markDirty. Assigning undefined drops the attribute — a textured draw of a uv-less geometry then samples the texel at (0, 0) for every fragment, because GL's constant attribute default is (0, 0, 0, 1).

      Replacing positions with an array of a different vertex count while uvs are present therefore throws: drop or replace the uvs first, exactly as for BufferGeometry.normals.

      Returns Float32Array<ArrayBufferLike> | undefined

    • set uvs(value: Float32Array<ArrayBufferLike> | undefined): void

      Parameters

      • value: Float32Array<ArrayBufferLike> | undefined

      Returns void

    • get version(): number

      Counter incremented on every mutation (§53). Backends cache GPU buffers against it; treat it as opaque and compare for inequality, exactly like Transform.version. Monotonic, never wraps in a realistic session.

      Returns number

    • get vertexCount(): number

      Number of vertices — positions.length / 3.

      Returns number

    • get weights(): Float32Array<ArrayBufferLike> | undefined

      Optional per-vertex joint weights as quadruplets, index-parallel with BufferGeometry.joints, or undefined (§53, §54; RFC 0003). Held by reference and subject to the same rules as every attribute: assigning validates (four finite floats per vertex, §85) and bumps the version; in-place edits need BufferGeometry.markDirty. A per-vertex sum of 1 is the author's contract, not validated — see the module header.

      Returns Float32Array<ArrayBufferLike> | undefined

    • set weights(value: Float32Array<ArrayBufferLike> | undefined): void

      Parameters

      • value: Float32Array<ArrayBufferLike> | undefined

      Returns void

    • An independent copy of this geometry — same vertex data, same mode, a new BufferGeometry.id, version 0 (§53).

      const wobbly = geometry.clone();
      wobbly.positions[1] += 0.5; // does not touch `geometry`
      wobbly.markDirty();

      Every typed array is copied, not shared. That is the only choice that survives contact with this class's own fast path: attributes are held by reference and the documented way to edit them is an in-place write followed by BufferGeometry.markDirty. A shallow clone would therefore give two geometries one buffer and two independent version counters — an in-place edit through either handle would silently change what the other draws while leaving the other's version (and so every backend cache keyed on it) untouched. That is not a cheaper clone; it is a cache-coherence bug with a convenient name.

      There is nothing else in a geometry to copy: the bounds are derived (the clone recomputes them on first use, to the same values), the id is deliberately not copied, and the geometry holds no references to nodes, materials, or backends.

      The cost is honest and worth stating: clone() allocates and copies byteLength bytes, and reports them to the §83 totals as a second live geometry. Cloning is for forking data — a procedural mesh about to be deformed per instance. Sharing one geometry between many renderables needs no clone at all (§83: geometries are shared, not owned by nodes).

      Returns BufferGeometry

      TypeError if this geometry has been disposed. A disposed geometry holds no data, so the copy would be a silently empty mesh — §83 names "disposed resources still in use" as a thing to detect, and a refusal at the call site is the earliest place to detect it.

    • Returns this geometry's local BoundingVolume, recomputing it only when BufferGeometry.version has advanced since the last call (§53: bounds are computed, then cached against the version).

      Allocates nothing — the returned volume and its three vectors are owned by the geometry and rewritten in place on the next recompute, so callers that keep the values must copy them.

      A geometry with no vertices returns the empty box min = +Infinity, max = -Infinity (decision, WP-3.3): that is the identity element of bounds union, so an empty geometry folded into a scene bound contributes nothing, whereas a zero-sized box at the origin would drag the scene bound to include a point that has no geometry in it. Its center and radius are NaN for the same reason stated positively — the volume of no points is not a point at the origin (R-21).

      Returns BoundingVolume

    • Releases this geometry's CPU-side data (§83). Idempotent.

      The typed arrays are dropped — positions becomes empty, normals, uvs, colors, joints, weights, and indices become undefined — so a large mesh's memory is reclaimable the moment its owner is done with it, and the version is bumped so any backend cache keyed on it re-reads (and finds nothing to draw). Nothing throws afterwards: BufferGeometry.disposed is the flag renderers and the §83 "disposed resource still in use" diagnostic check.

      Disposing does not notify the renderables pointing at this geometry; ownership is explicit and upwards (§83), so whoever created the geometry decides when nothing needs it any more.

      It does remove this geometry and its bytes from the process-wide §83 totals (geometryMemoryBytes, liveGeometryCount), exactly once: the idempotence guard above is what makes a double dispose() subtract once rather than twice.

      Returns void

    • Announces a mutation the geometry could not see — an in-place write into positions, normals, uvs, colors, or indices. Bumps BufferGeometry.version by one, which invalidates the cached bounds and every backend buffer keyed on the version.

      Calling it after a setter is harmless, only wasteful: the version advances again and the bounds recompute once more.

      Returns void