Geometry
Raw mesh data — vertex, normal, index and UV buffers — plus the primitive builders behind
Mesh.box() and friends. Reach for it to tweak a primitive before wrapping it (scale, shifted
pivot, tiled UVs) or to build fully procedural meshes. A Geometry renders via
Mesh.from(); it is not a node itself.
At a glance
// a box whose pivot is at its BOTTOM face (so y = 0 puts it on the floor)
const geo = Geometry.box().scale(1, 2, 1).translate(0, 1, 0)
const pillar = Mesh.from(geo, { material: Material.lit({ color: '#ccc' }) })
scene.add(pillar)Primitives
Geometry.box(): Geometry // unit cube, centered on the origin
Geometry.sphere(options?: {
radius?: number // default 0.5
widthSegments?: number // default 32
heightSegments?: number // default 32
}): Geometry
Geometry.cylinder(options?: {
radius?: number // default 0.5 (both caps)
radiusTop?: number // default = radius (0 makes a cone)
radiusBottom?: number // default = radius
edges?: number // default 32
smooth?: boolean // default true — smooth side normals; false = faceted
}): Geometry
Geometry.plane(options?: {
normal?: Vec3Like // facing direction; default [0, 0, 1]
}): GeometryAll primitives are unit-sized (1 world unit ≈ 1 m across, height 1 for the cylinder), centered on
the origin, with normals and UVs filled in. The plane is a 1×1 quad perpendicular to normal.
Buffers
geo.vertices // Float32Array — x,y,z triplets
geo.normals // Float32Array — x,y,z triplets (per vertex)
geo.indices // Uint16Array — triangle (or edge/point) indices
geo.uv // Float32Array — u,v pairs (per vertex)
new Geometry(vertices, normals, indices, uv)Build procedural meshes by filling the buffers yourself and constructing directly.
indices are Uint16Array, so a single geometry tops out at 65 536 vertices.
Transforming the data
geo.translate(x, y, z): this // shift every vertex — moves the pivot
geo.scale(x, y, z): this // scale every vertex
geo.scaleUV(x, y): this // tile/stretch the texture coordinatesThese mutate the buffers in place (chainable). Baking a transform into the geometry is different
from node.scale: physics shapes and child transforms see the baked size, and normals are not
recomputed — non-uniform scale skews lighting slightly.
Draw mode
geo.kind = 'triangles' | 'edges' | 'vertices' // default 'triangles' (write-only)'edges' renders the index pairs as lines, 'vertices' as points — for wireframe/debug looks.
Pitfalls
// ✗ editing a Geometry after a Mesh was built from it
mesh.geometry.translate(0, 1, 0) // buffers already uploaded — the mesh doesn't change
// ✓ finish the geometry first, then Mesh.from(geo)See also
- Mesh —
Mesh.from(geometry)and the primitive factory shortcuts - Material — what the surface looks like
- 3D physics & shapes — auto-shapes read the node's geometry