threejs-geometry

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.

By cloudai-x · 9,615 installs

npx skills add cloudai-x/threejs-skills --skill threejs-geometry

Source repository · Upstream listing

Three.js Geometry Targets three.js r186. Examples use WebGLRenderer; the WebGPU and TSL section uses WebGPURenderer. Quick Start Built in Geometries Basic Shapes Advanced Shapes Path Based Shapes Text Geometry BufferGeometry The base class of every geometry: typed arrays of vertex data plus an optional index. Attributes are named buffers of itemSize values per vertex; position , normal and uv are the ones materials read by default. Custom BufferGeometry Attribute Types Updating a BufferGeometry Interleaved Buffers Edges and Wireframes Points Under WebGPURenderer the WebGPU backend draws points at one pixel whatever the material size; see the WebGPU and TSL section for the instanced Sprite that restores sizes. Lines LineLoop is not supported under WebGPURenderer: it logs an error and renders nothing. Close a loop there by repeating the first point and using Line. InstancedMesh One draw call for many copies of one geometry, each with its own transform. At runtime, update and raycast instances like this: InstancedBufferGeometry Per instance attributes beyond transform and color. BatchedMesh Many different geometries sharing one material, each instance with its own transform. WebGLRenderer draws them with one multi draw call where WEBGL multi draw is available; the WebGPU backend issues one draw per instance. Geometry Utilities Transforming Geometry To rotate or scale an object around a point without touching vertex data, set a pivot instead of re centering the geometry: Morph Targets Performance and Disposal Cut draw calls: mergeGeometries for static meshes, InstancedMesh for repeated geometry, BatchedMesh for many different geometries (one multi draw call on WebGLRenderer where WEBGL multi draw is available). Segment counts trade smoothness for vertex count; the sphere default of 32 by 16 suits most uses, go higher only for close ups. To free a whole subtree, traverse it as in Common Mistakes. InstancedMesh.dispose() additionally frees its morph texture. WebGPU and TSL The geometry classes, InstancedMesh and BatchedMesh keep the API shown above under WebGPURenderer. What differs: the WebGPU backend draws Points at one pixel and issues one draw per BatchedMesh instance, LineLoop is skipped with an error, and per instance shader data is a TSL node. The WebGPU backend draws points at one pixel whatever the material size. Larger points render as a single Sprite drawn once per position: Custom per instance attributes are TSL nodes, not GLSL declarations. Build displacement on positionLocal, which already carries the instance transforms: Common Mistakes BufferGeometryUtils.computeTangents(geometry) → geometry.computeTangents() : BufferGeometryUtils exports no computeTangents; the core method needs an index plus position, normal and uv attributes. new THREE.BufferAttribute(new Uint8Array(rgbBytes), 3) → new THREE.BufferAttribute(new Uint8Array(rgbBytes), 3, true) : unnormalized bytes reach the shader as 0.0 to 255.0 and the colors blow out. geometry.copy(new THREE.BoxGeometry(1, 1, 1)); → geometry.copy(new THREE.BoxGeometry(1, 1, 1)); geometry.instanceCount = count; : InstancedBufferGeometry.copy() overwrites instanceCount with the source's undefined, and WebGLRenderer then draws no instances. batchedMesh.addGeometry(boxGeometry) → batchedMesh.addInstance(batchedMesh.addGeometry(boxGeometry)) : a geometry added to a BatchedMesh renders only through an instance created with addInstance (required since r166). new THREE.LineLoop(geometry, material) → new THREE.Line(new THREE.BufferGeometry().setFromPoints([...linePoints, linePoints[0]]), material) : WebGPURenderer does not support LineLoop; it logs an error and skips the object, so repeat the first point to close a Line. import { TextGeometry } from "three/examples/jsm/geometries/TextGeometry.js" → import { TextGeometry } from "three/addons/geometries/TextGeometry.js" : the examples/jsm specifier does not resolve under the documented import maps, which map three/addons/ but not three/examples/. capsule.parameters.length → capsule.parameters.height : the CapsuleGeometry parameter was renamed from length to height in r176, and a fifth parameter heightSegments was added. { font: font, size: 1, height: 0.2 } → { font: font, size: 1, depth: 0.2 } : the TextGeometry extrusion option was renamed from height to depth in r163; an old height is ignored and the text extrudes the default 50 units. new THREE.Points(cloud, new THREE.PointsMaterial({ size: 10 })) → new THREE.Sprite(new THREE.PointsNodeMaterial({ positionNode: instancedBufferAttribute(attr) })) : the WebGPU backend draws Points at one pixel whatever the size, so larger points need the instanced Sprite form. new THREE.ShaderMaterial({ vertexShader: offsetVertexShader }) → material.positionNode = positionLocal.add(instancedBufferAttribute(offsetAttribute)) : WebGPURenderer has no node version of ShaderMaterial; it logs that the material is not compatible and falls back to a plain NodeMaterial, so per instance data there is a TSL node. material.positionNode = positionGeometry.add(offset) → material.positionNode = positionLocal.add(offset) : positionLocal already carries skinning, morph targets, batching and instancing; positionGeometry is the raw attribute. mesh.morphTargetInfluences[0] = 0.5 → mesh.updateMorphTargets(); mesh.morphTargetInfluences[0] = 0.5; : influences exist only for morph attributes the mesh saw at construction, so refresh them after adding targets to an existing mesh. gltf.scene.dispose() → gltf.scene.traverse((child) = { child.geometry?.dispose(); for (const material of [child.material ?? []].flat()) { for (const value of Object.values(material)) if (value?.isTexture) value.dispose(); material.dispose(); } child.dispose(); }) : Object3D.dispose() frees renderer state for that one object only; it does not visit children or dispose geometries, materials or textures. new THREE.BoxBufferGeometry(1, 1, 1) → new THREE.BoxGeometry(1, 1, 1) : the BufferGeometry aliases of the built in shapes no longer exist; every built in geometry is already a BufferGeometry. BufferGeometryUtils.mergeBufferGeometries([geo1, geo2]) → BufferGeometryUtils.mergeGeometries([geo1, geo2]) : the old name is not exported, so the call throws a TypeError. geometry.setAttribute("uv2", geometry.attributes.uv) → material.aoMap = aoTexture; : an aoMap reads uv (channel 0) by default; only a separate baked unwrap goes in uv1 , with aoTexture.channel = 1 . new THREE.LineBasicMaterial({ linewidth: 4 }) → new Line2(new LineGeometry().setPositions(xyzArray), new LineMaterial({ linewidth: 4 })) : WebGL and WebGPU draw line primitives one pixel wide whatever linewidth says; Line2, LineGeometry and LineMaterial from three/addons/lines/ draw thick lines on WebGLRenderer, and under WebGPURenderer the Line2 from three/addons/lines/webgpu/Line2.js takes a Line2NodeMaterial from three/webgpu. See Also threejs fundamentals scene setup, the render loop, Object3D transforms and disposal. threejs materials material types and settings for the meshes built here. threejs shaders ShaderMaterial vertex and fragment code for WebGLRenderer. threejs animation animating morph target influences and transforms over time. threejs loaders glTF and other formats that bring their own geometry. threejs performance choosing between merging, instancing, batching and LOD by measured draw calls.