Threejs Geometry

calesthio/OpenMontage/.claude/skills/threejs-geometry

by calesthio9327439db69021ab4b0e2776729bf3b58fdb5a87No license65K starsListed Oct 9, 2026Updated Oct 9, 2026Repository updated 5 days ago

Three.js geometry creation - built-in shapes, BufferGeometry, custom geometry, instancing. Use when creating 3D shapes, working with vertices, building custom meshes, or optimizing with instanced rendering.

AI-generated overview

Reference for creating Three.js geometries: built-in shapes, custom BufferGeometry, instancing and performance patterns.

What it does
Provides code snippets and parameter references for Three.js geometry work, covering built-in shapes such as box, sphere, cylinder and torus, plus path-based shapes like lathe, extrude and tube. It explains BufferGeometry attributes, typed arrays, interleaved buffers, edges and wireframe geometry, points and lines. It also documents InstancedMesh and InstancedBufferGeometry for repeated objects, geometry utilities such as merging and tangent computation, and common patterns like centering, scaling and morph targets.
When to use it
Use when writing Three.js code that creates or modifies 3D shapes, builds custom meshes from vertices, or needs to render many identical objects efficiently. Also useful when tuning segment counts, merging static meshes or disposing geometry for performance.
Requirements
Requires a JavaScript project with the three package installed; text geometry examples also need a font JSON file loaded through FontLoader. No scripts are shipped; the skill is instructions and code snippets only.

Three.js Geometry

Quick Start

javascript
import * as THREE from "three";
// Built-in geometryconst box = new THREE.BoxGeometry(1, 1, 1);const sphere = new THREE.SphereGeometry(0.5, 32, 32);const plane = new THREE.PlaneGeometry(10, 10);
// Create meshconst material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });const mesh = new THREE.Mesh(box, material);scene.add(mesh);

Built-in Geometries

Basic Shapes

javascript
// Box - width, height, depth, widthSegments, heightSegments, depthSegmentsnew THREE.BoxGeometry(1, 1, 1, 1, 1, 1);
// Sphere - radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLengthnew THREE.SphereGeometry(1, 32, 32);new THREE.SphereGeometry(1, 32, 32, 0, Math.PI * 2, 0, Math.PI); // Full spherenew THREE.SphereGeometry(1, 32, 32, 0, Math.PI); // Hemisphere
// Plane - width, height, widthSegments, heightSegmentsnew THREE.PlaneGeometry(10, 10, 1, 1);
// Circle - radius, segments, thetaStart, thetaLengthnew THREE.CircleGeometry(1, 32);new THREE.CircleGeometry(1, 32, 0, Math.PI); // Semicircle
// Cylinder - radiusTop, radiusBottom, height, radialSegments, heightSegments, openEndednew THREE.CylinderGeometry(1, 1, 2, 32, 1, false);new THREE.CylinderGeometry(0, 1, 2, 32); // Conenew THREE.CylinderGeometry(1, 1, 2, 6); // Hexagonal prism
// Cone - radius, height, radialSegments, heightSegments, openEndednew THREE.ConeGeometry(1, 2, 32, 1, false);
// Torus - radius, tube, radialSegments, tubularSegments, arcnew THREE.TorusGeometry(1, 0.4, 16, 100);
// TorusKnot - radius, tube, tubularSegments, radialSegments, p, qnew THREE.TorusKnotGeometry(1, 0.4, 100, 16, 2, 3);
// Ring - innerRadius, outerRadius, thetaSegments, phiSegmentsnew THREE.RingGeometry(0.5, 1, 32, 1);

Advanced Shapes

javascript
// Capsule - radius, length, capSegments, radialSegmentsnew THREE.CapsuleGeometry(0.5, 1, 4, 8);
// Dodecahedron - radius, detailnew THREE.DodecahedronGeometry(1, 0);
// Icosahedron - radius, detail (0 = 20 faces, higher = smoother)new THREE.IcosahedronGeometry(1, 0);
// Octahedron - radius, detailnew THREE.OctahedronGeometry(1, 0);
// Tetrahedron - radius, detailnew THREE.TetrahedronGeometry(1, 0);
// Polyhedron - vertices, indices, radius, detailconst vertices = [1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1];const indices = [2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1];new THREE.PolyhedronGeometry(vertices, indices, 1, 0);

Path-Based Shapes

javascript
// Lathe - points[], segments, phiStart, phiLengthconst points = [  new THREE.Vector2(0, 0),  new THREE.Vector2(0.5, 0),  new THREE.Vector2(0.5, 1),  new THREE.Vector2(0, 1),];new THREE.LatheGeometry(points, 32);
// Extrude - shape, optionsconst shape = new THREE.Shape();shape.moveTo(0, 0);shape.lineTo(1, 0);shape.lineTo(1, 1);shape.lineTo(0, 1);shape.lineTo(0, 0);
const extrudeSettings = {  steps: 2,  depth: 1,  bevelEnabled: true,  bevelThickness: 0.1,  bevelSize: 0.1,  bevelSegments: 3,};new THREE.ExtrudeGeometry(shape, extrudeSettings);
// Tube - path, tubularSegments, radius, radialSegments, closedconst curve = new THREE.CatmullRomCurve3([  new THREE.Vector3(-1, 0, 0),  new THREE.Vector3(0, 1, 0),  new THREE.Vector3(1, 0, 0),]);new THREE.TubeGeometry(curve, 64, 0.2, 8, false);

Text Geometry

javascript
import { FontLoader } from "three/examples/jsm/loaders/FontLoader.js";import { TextGeometry } from "three/examples/jsm/geometries/TextGeometry.js";
const loader = new FontLoader();loader.load("fonts/helvetiker_regular.typeface.json", (font) => {  const geometry = new TextGeometry("Hello", {    font: font,    size: 1,    depth: 0.2, // Was 'height' in older versions    curveSegments: 12,    bevelEnabled: true,    bevelThickness: 0.03,    bevelSize: 0.02,    bevelSegments: 5,  });
  // Center text  geometry.computeBoundingBox();  geometry.center();
  const mesh = new THREE.Mesh(geometry, material);  scene.add(mesh);});

BufferGeometry

The base class for all geometries. Stores data as typed arrays for GPU efficiency.

Custom BufferGeometry

javascript
const geometry = new THREE.BufferGeometry();
// Vertices (3 floats per vertex: x, y, z)const vertices = new Float32Array([  -1,  -1,  0, // vertex 0  1,  -1,  0, // vertex 1  1,  1,  0, // vertex 2  -1,  1,  0, // vertex 3]);geometry.setAttribute("position", new THREE.BufferAttribute(vertices, 3));
// Indices (for indexed geometry - reuse vertices)const indices = new Uint16Array([  0,  1,  2, // triangle 1  0,  2,  3, // triangle 2]);geometry.setIndex(new THREE.BufferAttribute(indices, 1));
// Normals (required for lighting)const normals = new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]);geometry.setAttribute("normal", new THREE.BufferAttribute(normals, 3));
// UVs (for texturing)const uvs = new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]);geometry.setAttribute("uv", new THREE.BufferAttribute(uvs, 2));
// Colors (per-vertex colors)const colors = new Float32Array([  1,  0,  0, // red  0,  1,  0, // green  0,  0,  1, // blue  1,  1,  0, // yellow]);geometry.setAttribute("color", new THREE.BufferAttribute(colors, 3));// Use with: material.vertexColors = true

BufferAttribute Types

javascript
// Common attribute typesnew THREE.BufferAttribute(array, itemSize);
// Typed array optionsnew Float32Array(count * itemSize); // Positions, normals, UVsnew Uint16Array(count); // Indices (up to 65535 vertices)new Uint32Array(count); // Indices (larger meshes)new Uint8Array(count * itemSize); // Colors (0-255 range)
// Item sizes// Position: 3 (x, y, z)// Normal: 3 (x, y, z)// UV: 2 (u, v)// Color: 3 (r, g, b) or 4 (r, g, b, a)// Index: 1

Modifying BufferGeometry

javascript
const positions = geometry.attributes.position;
// Modify vertexpositions.setXYZ(index, x, y, z);
// Access vertexconst x = positions.getX(index);const y = positions.getY(index);const z = positions.getZ(index);
// Flag for GPU updatepositions.needsUpdate = true;
// Recompute normals after position changesgeometry.computeVertexNormals();
// Recompute bounding box/sphere after changesgeometry.computeBoundingBox();geometry.computeBoundingSphere();

Interleaved Buffers (Advanced)

javascript
// More efficient memory layout for large meshesconst interleavedBuffer = new THREE.InterleavedBuffer(  new Float32Array([    // pos.x, pos.y, pos.z, uv.u, uv.v (repeated per vertex)    -1, -1, 0, 0, 0, 1, -1, 0, 1, 0, 1, 1, 0, 1, 1, -1, 1, 0, 0, 1,  ]),  5, // stride (floats per vertex));
geometry.setAttribute(  "position",  new THREE.InterleavedBufferAttribute(interleavedBuffer, 3, 0),); // size 3, offset 0geometry.setAttribute(  "uv",  new THREE.InterleavedBufferAttribute(interleavedBuffer, 2, 3),); // size 2, offset 3

EdgesGeometry & WireframeGeometry

javascript
// Edge lines (only hard edges)const edges = new THREE.EdgesGeometry(boxGeometry, 15); // 15 = threshold angleconst edgeMesh = new THREE.LineSegments(  edges,  new THREE.LineBasicMaterial({ color: 0xffffff }),);
// Wireframe (all triangles)const wireframe = new THREE.WireframeGeometry(boxGeometry);const wireMesh = new THREE.LineSegments(  wireframe,  new THREE.LineBasicMaterial({ color: 0xffffff }),);

Points

javascript
// Create point cloudconst geometry = new THREE.BufferGeometry();const positions = new Float32Array(1000 * 3);
for (let i = 0; i < 1000; i++) {  positions[i * 3] = (Math.random() - 0.5) * 10;  positions[i * 3 + 1] = (Math.random() - 0.5) * 10;  positions[i * 3 + 2] = (Math.random() - 0.5) * 10;}
geometry.setAttribute("position", new THREE.BufferAttribute(positions, 3));
const material = new THREE.PointsMaterial({  size: 0.1,  sizeAttenuation: true, // Size decreases with distance  color: 0xffffff,});
const points = new THREE.Points(geometry, material);scene.add(points);

Lines

javascript
// Line (connected points)const points = [  new THREE.Vector3(-1, 0, 0),  new THREE.Vector3(0, 1, 0),  new THREE.Vector3(1, 0, 0),];const geometry = new THREE.BufferGeometry().setFromPoints(points);const line = new THREE.Line(  geometry,  new THREE.LineBasicMaterial({ color: 0xff0000 }),);
// LineLoop (closed loop)const loop = new THREE.LineLoop(geometry, material);
// LineSegments (pairs of points)const segmentsGeometry = new THREE.BufferGeometry();segmentsGeometry.setAttribute(  "position",  new THREE.BufferAttribute(    new Float32Array([      -1,      0,      0,      0,      1,      0, // segment 1      0,      1,      0,      1,      0,      0, // segment 2    ]),    3,  ),);const segments = new THREE.LineSegments(segmentsGeometry, material);

InstancedMesh

Efficiently render many copies of the same geometry.

javascript
const geometry = new THREE.BoxGeometry(1, 1, 1);const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });const count = 1000;
const instancedMesh = new THREE.InstancedMesh(geometry, material, count);
// Set transforms for each instanceconst dummy = new THREE.Object3D();const matrix = new THREE.Matrix4();
for (let i = 0; i < count; i++) {  dummy.position.set(    (Math.random() - 0.5) * 20,    (Math.random() - 0.5) * 20,    (Math.random() - 0.5) * 20,  );  dummy.rotation.set(Math.random() * Math.PI, Math.random() * Math.PI, 0);  dummy.scale.setScalar(0.5 + Math.random());  dummy.updateMatrix();
  instancedMesh.setMatrixAt(i, dummy.matrix);}
// Flag for GPU updateinstancedMesh.instanceMatrix.needsUpdate = true;
// Optional: per-instance colorsinstancedMesh.instanceColor = new THREE.InstancedBufferAttribute(  new Float32Array(count * 3),  3,);for (let i = 0; i < count; i++) {  instancedMesh.setColorAt(    i,    new THREE.Color(Math.random(), Math.random(), Math.random()),  );}instancedMesh.instanceColor.needsUpdate = true;
scene.add(instancedMesh);

Update Instance at Runtime

javascript
// Update single instanceconst matrix = new THREE.Matrix4();instancedMesh.getMatrixAt(index, matrix);// Modify matrix...instancedMesh.setMatrixAt(index, matrix);instancedMesh.instanceMatrix.needsUpdate = true;
// Raycasting with instanced meshconst intersects = raycaster.intersectObject(instancedMesh);if (intersects.length > 0) {  const instanceId = intersects[0].instanceId;}

InstancedBufferGeometry (Advanced)

For custom per-instance attributes beyond transform/color.

javascript
const geometry = new THREE.InstancedBufferGeometry();geometry.copy(new THREE.BoxGeometry(1, 1, 1));
// Add per-instance attributeconst offsets = new Float32Array(count * 3);for (let i = 0; i < count; i++) {  offsets[i * 3] = Math.random() * 10;  offsets[i * 3 + 1] = Math.random() * 10;  offsets[i * 3 + 2] = Math.random() * 10;}geometry.setAttribute("offset", new THREE.InstancedBufferAttribute(offsets, 3));
// Use in shader// attribute vec3 offset;// vec3 transformed = position + offset;

Geometry Utilities

javascript
import * as BufferGeometryUtils from "three/examples/jsm/utils/BufferGeometryUtils.js";
// Merge geometries (must have same attributes)const merged = BufferGeometryUtils.mergeGeometries([geo1, geo2, geo3]);
// Merge with groups (for multi-material)const merged = BufferGeometryUtils.mergeGeometries([geo1, geo2], true);
// Compute tangents (required for normal maps)BufferGeometryUtils.computeTangents(geometry);
// Interleave attributes for better performanceconst interleaved = BufferGeometryUtils.interleaveAttributes([  geometry.attributes.position,  geometry.attributes.normal,  geometry.attributes.uv,]);

Common Patterns

Center Geometry

javascript
geometry.computeBoundingBox();geometry.center(); // Move vertices so center is at origin

Scale to Fit

javascript
geometry.computeBoundingBox();const size = new THREE.Vector3();geometry.boundingBox.getSize(size);const maxDim = Math.max(size.x, size.y, size.z);geometry.scale(1 / maxDim, 1 / maxDim, 1 / maxDim);

Clone and Transform

javascript
const clone = geometry.clone();clone.rotateX(Math.PI / 2);clone.translate(0, 1, 0);clone.scale(2, 2, 2);

Morph Targets

javascript
// Base geometryconst geometry = new THREE.BoxGeometry(1, 1, 1, 4, 4, 4);
// Create morph targetconst morphPositions = geometry.attributes.position.array.slice();for (let i = 0; i < morphPositions.length; i += 3) {  morphPositions[i] *= 2; // Scale X  morphPositions[i + 1] *= 0.5; // Squash Y}
geometry.morphAttributes.position = [  new THREE.BufferAttribute(new Float32Array(morphPositions), 3),];
const mesh = new THREE.Mesh(geometry, material);mesh.morphTargetInfluences[0] = 0.5; // 50% blend

Performance Tips

  1. Use indexed geometry: Reuse vertices with indices
  2. Merge static meshes: Reduce draw calls with mergeGeometries
  3. Use InstancedMesh: For many identical objects
  4. Choose appropriate segment counts: More segments = smoother but slower
  5. Dispose unused geometry: geometry.dispose()
javascript
// Good segment counts for common usesnew THREE.SphereGeometry(1, 32, 32); // Good qualitynew THREE.SphereGeometry(1, 64, 64); // High qualitynew THREE.SphereGeometry(1, 16, 16); // Performance mode
// Dispose when donegeometry.dispose();

See Also

  • threejs-fundamentals - Scene setup and Object3D
  • threejs-materials - Material types for meshes
  • threejs-shaders - Custom vertex manipulation

Source and attribution

Source:calesthio/OpenMontagein.claude/skills/threejs-geometryat commit9327439

License: No license

Content belongs to its original authors. SourceWeft indexes it from a public repository.

Report or request removal