Skip to main content Inicio Creadores afovea game-dev-skills threejs-geometry
threejs-geometry Three.js geometry — BufferGeometry, 15+ built-in shapes, custom vertex/index data, InstancedMesh for many identical objects, geometry merging, EdgesGeometry, point clouds, morph targets, and InstancedBufferGeometry. Use when creating or modifying 3D geometry, optimising repeated objects, or building procedural meshes. Adapted from CloudAI-X/threejs-skills (MIT).
Ir a la instalación Skills Marketplace Descubre y explora habilidades de IA creadas por la comunidad.
Ocupaciones relacionadas SOC
Basado en la clasificación ocupacional SOC
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Copiar promptMostrar detalles del prompt Un comando directo omite el prompt de revisión. Revisa el origen antes de ejecutarlo.
npx skills add https://github.com/afovea/game-dev-skills --skill threejs-geometryEl comando permanece en una sola línea. Desplázate horizontalmente para revisarlo antes de copiarlo.
¿Prefieres una copia local? Descarga los archivos que SkillsMP tiene disponibles ahora.
Descargar Zip Descargando... Más de este repositorio Art Director persona for visual style, pillars, art bible, cross-discipline visual consistency, art critique, and art QA. Use when a task needs visual direction, style enforcement, or cohesion across concept, environment, character, VFX, and lighting.
Audio Director persona for sound design, music direction, mix, audio implementation patterns, and audio pipeline. Use when a task needs reasoning about audio intent, audio-mechanic integration, mix balance, or the audio toolchain.
Post-pipeline cleanup and verification pass for game-development work. Regenerate / re-bake any derived content, rebuild the project, verify the editor / engine opens cleanly, run automated test suites, take a perf snapshot against budgets, and confirm save / network / cert / pipeline surfaces are untouched (or correctly versioned) against the pre-run baseline.
name threejs-geometry description Three.js geometry — BufferGeometry, 15+ built-in shapes, custom vertex/index data, InstancedMesh for many identical objects, geometry merging, EdgesGeometry, point clouds, morph targets, and InstancedBufferGeometry. Use when creating or modifying 3D geometry, optimising repeated objects, or building procedural meshes. Adapted from CloudAI-X/threejs-skills (MIT). license MIT compatibility Portable reference skill for agents that support markdown skills or prompt files. Works best alongside project Three.js source files and renderer.info draw-call monitoring. disable-model-invocation true metadata {"owner":"game-delivery","version":"2.0.0","language":"en-GB","category":"web-rendering","upstream_references":["https://github.com/CloudAI-X/threejs-skills (MIT — see NOTICE.md)"],"tags":["three-js","geometry","buffer-geometry","instancing","instanced-mesh","procedural","point-cloud","morph-targets"],"intents":["geometry-creation","instancing","geometry-merging","point-cloud-setup","procedural-mesh"],"output_types":["code-example","api-reference","optimisation-plan"]}
Three.js Geometry
Quick Start
import * as THREE from 'three' ;
const geometry = new THREE .BoxGeometry (1 , 1 , 1 );
const material = new THREE .MeshStandardMaterial ({ color : 0x44aa88 });
const mesh = new THREE .Mesh (geometry, material);
scene.add (mesh);
const custom = new THREE .BufferGeometry ();
const vertices = new Float32Array ([
0 , 1 , 0 ,
-1 , -1 , 0 ,
1 , -1 , 0 ,
]);
custom.setAttribute ('position' , new THREE .BufferAttribute (vertices, 3 ));
scene.add (new . (custom, material));
THREE
Mesh
Built-in Geometry Types
Primitives
new THREE .BoxGeometry (width, height, depth, widthSeg, heightSeg, depthSeg);
new THREE .BoxGeometry (1 , 1 , 1 );
new THREE .SphereGeometry (radius, widthSeg, heightSeg, phiStart, phiLength, thetaStart, thetaLength);
new THREE .SphereGeometry (0.5 , 32 , 32 );
new THREE .PlaneGeometry (width, height, widthSeg, heightSeg);
new THREE .PlaneGeometry (10 , 10 , 64 , 64 );
new THREE .CylinderGeometry (radiusTop, radiusBottom, height, radialSeg, heightSeg, openEnded);
new THREE .CylinderGeometry (0.5 , 0.5 , 2 , 32 );
new THREE .CylinderGeometry (0 , 0.5 , 1 , 32 );
new THREE .TorusGeometry (radius, tube, radialSeg, tubularSeg, arc);
new THREE .TorusGeometry (1 , 0.4 , 16 , 100 );
new THREE .TorusKnotGeometry (radius, tube, tubularSeg, radialSeg, p, q);
new THREE .TorusKnotGeometry (1 , 0.3 , 128 , 16 , 2 , 3 );
new THREE .CircleGeometry (radius, segments, thetaStart, thetaLength);
new THREE .CircleGeometry (0.5 , 32 );
new THREE .RingGeometry (innerRadius, outerRadius, thetaSeg, phiSeg, thetaStart, thetaLength);
new THREE .RingGeometry (0.3 , 0.5 , 32 );
new THREE .CapsuleGeometry (radius, length, capSeg, radialSeg);
new THREE .CapsuleGeometry (0.5 , 1 , 8 , 16 );
new THREE .IcosahedronGeometry (radius, detail);
new THREE .OctahedronGeometry (radius, detail);
Path-Based Shapes
const points = [];
for (let i = 0 ; i < 10 ; i++) {
points.push (new THREE .Vector2 (Math .sin (i * 0.2 ) + 0.5 , i * 0.2 - 1 ));
}
new THREE .LatheGeometry (points, 32 );
const 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 = {
depth : 0.5 ,
bevelEnabled : true ,
bevelThickness : 0.1 ,
bevelSize : 0.1 ,
bevelSegments : 3 ,
};
new THREE .ExtrudeGeometry (shape, extrudeSettings);
const path = new THREE .CatmullRomCurve3 ([
new THREE .Vector3 (-1 , 0 , 0 ),
new THREE .Vector3 (0 , 1 , 0 ),
new THREE .Vector3 (1 , 0 , 0 ),
]);
new THREE .TubeGeometry (path, 64 , 0.1 , 8 , false );
BufferGeometry The foundation class for all geometry in Three.js — stores data as typed arrays on the GPU.
Custom Geometry const geometry = new THREE .BufferGeometry ();
const positions = new Float32Array ([
0 , 0 , 0 ,
1 , 0 , 0 ,
0 , 1 , 0 ,
1 , 1 , 0 ,
]);
geometry.setAttribute ('position' , new THREE .BufferAttribute (positions, 3 ));
const normals = new Float32Array ([
0 , 0 , 1 ,
0 , 0 , 1 ,
0 , 0 , 1 ,
0 , 0 , 1 ,
]);
geometry.setAttribute ('normal' , new THREE .BufferAttribute (normals, 3 ));
const uvs = new Float32Array ([
0 , 0 ,
1 , 0 ,
0 , 1 ,
1 , 1 ,
]);
geometry.setAttribute ('uv' , new THREE .BufferAttribute (uvs, 2 ));
const indices = new Uint16Array ([0 , 1 , 2 , 1 , 3 , 2 ]);
geometry.setIndex (new THREE .BufferAttribute (indices, 1 ));
const colours = new Float32Array ([
1 , 0 , 0 ,
0 , 1 , 0 ,
0 , 0 , 1 ,
1 , 1 , 0 ,
]);
geometry.setAttribute ('color' , new THREE .BufferAttribute (colours, 3 ));
geometry.computeVertexNormals ();
Runtime Modification const positions = geometry.attributes .position ;
for (let i = 0 ; i < positions.count ; i++) {
const y = Math .sin (positions.getX (i) * 2 + time) * 0.5 ;
positions.setY (i, y);
}
positions.needsUpdate = true ;
geometry.computeBoundingBox ();
geometry.computeBoundingSphere ();
Bounding Volumes geometry.computeBoundingBox ();
geometry.computeBoundingSphere ();
const box = geometry.boundingBox ;
const sphere = geometry.boundingSphere ;
const inside = box.containsPoint (new THREE .Vector3 (0.5 , 0.5 , 0 ));
InstancedMesh — Many Identical Objects Critical for performance. One draw call for thousands of identical meshes.
const count = 10000 ;
const geometry = new THREE .BoxGeometry (0.1 , 0.1 , 0.1 );
const material = new THREE .MeshStandardMaterial ({ color : 0xff0000 });
const instancedMesh = new THREE .InstancedMesh (geometry, material, count);
instancedMesh.castShadow = true ;
instancedMesh.receiveShadow = true ;
const dummy = new THREE .Object3D ();
const colour = new THREE .Color ();
for (let i = 0 ; i < count; i++) {
dummy.position .random ().multiplyScalar (20 );
dummy.rotation .set (
Math .random () * Math .PI ,
Math .random () * Math .PI ,
0 ,
);
dummy.scale .setScalar (0.5 + Math .random () * 0.5 );
dummy.updateMatrix ();
instancedMesh.setMatrixAt (i, dummy.matrix );
colour.setHSL (Math .random (), 0.8 , 0.5 );
instancedMesh.setColorAt (i, colour);
}
instancedMesh.instanceMatrix .needsUpdate = true ;
if (instancedMesh.instanceColor ) instancedMesh.instanceColor .needsUpdate = true ;
scene.add (instancedMesh);
function moveInstance (index, position ) {
dummy.position .copy (position);
dummy.updateMatrix ();
instancedMesh.setMatrixAt (index, dummy.matrix );
instancedMesh.instanceMatrix .needsUpdate = true ;
}
Raycasting on InstancedMesh const raycaster = new THREE .Raycaster ();
function onClick (event ) {
const mouse = new THREE .Vector2 (
(event.clientX / window .innerWidth ) * 2 - 1 ,
-(event.clientY / window .innerHeight ) * 2 + 1 ,
);
raycaster.setFromCamera (mouse, camera);
const intersects = raycaster.intersectObject (instancedMesh);
if (intersects.length > 0 ) {
const id = intersects[0 ].instanceId ;
instancedMesh.getMatrixAt (id, dummy.matrix );
console .log ('Clicked instance:' , id);
}
}
Geometry Merging Combine static meshes into one — eliminates individual draw calls.
import { mergeGeometries } from 'three/addons/utils/BufferGeometryUtils.js' ;
const geos = objects.map (o => {
const geo = o.geometry .clone ();
geo.applyMatrix4 (o.matrixWorld );
return geo;
});
const merged = mergeGeometries (geos, false );
const mesh = new THREE .Mesh (merged, sharedMaterial);
scene.add (mesh);
const mergedMulti = mergeGeometries (geos, true );
const meshMulti = new THREE .Mesh (mergedMulti, [mat1, mat2]);
Only merge static geometry. Merged meshes cannot be transformed individually.
Wireframes, Edges, and Points
const wireMat = new THREE .MeshBasicMaterial ({ wireframe : true , color : 0x00ff00 });
const wireMesh = new THREE .Mesh (geometry, wireMat);
const edges = new THREE .EdgesGeometry (geometry, 30 );
const edgeMesh = new THREE .LineSegments (edges, new THREE .LineBasicMaterial ({ color : 0xffffff }));
const wireGeo = new THREE .WireframeGeometry (geometry);
const wireLine = new THREE .LineSegments (wireGeo, new THREE .LineBasicMaterial ({ color : 0x888888 }));
const pointMat = new THREE .PointsMaterial ({ size : 0.02 , color : 0xffffff , sizeAttenuation : true });
const pointMesh = new THREE .Points (geometry, pointMat);
Morph Targets Blend between alternative vertex positions for animation.
const baseGeometry = new THREE .SphereGeometry (1 , 32 , 32 );
const morphGeo = baseGeometry.clone ();
const morphPos = morphGeo.attributes .position ;
for (let i = 0 ; i < morphPos.count ; i++) {
morphPos.setY (i, morphPos.getY (i) * 0.5 );
morphPos.setX (i, morphPos.getX (i) * 1.5 );
}
baseGeometry.morphAttributes .position = [morphPos];
const mesh = new THREE .Mesh (baseGeometry, new THREE .MeshStandardMaterial ({ morphTargets : true }));
scene.add (mesh);
function animate ( ) {
mesh.morphTargetInfluences [0 ] = Math .sin (clock.getElapsedTime ()) * 0.5 + 0.5 ;
requestAnimationFrame (animate);
renderer.render (scene, camera);
}
InstancedBufferGeometry — Custom Per-Instance Attributes For instanced particles or objects needing per-instance shader data beyond transform and colour.
const count = 50000 ;
const geometry = new THREE .PlaneGeometry (0.05 , 0.05 );
const seeds = new Float32Array (count);
const speeds = new Float32Array (count);
for (let i = 0 ; i < count; i++) {
seeds[i] = Math .random ();
speeds[i] = 0.5 + Math .random () * 1.5 ;
}
geometry.setAttribute ('aSeed' , new THREE .InstancedBufferAttribute (seeds, 1 ));
geometry.setAttribute ('aSpeed' , new THREE .InstancedBufferAttribute (speeds, 1 ));
const material = new THREE .ShaderMaterial ({
uniforms : { uTime : { value : 0 } },
vertexShader : `
attribute float aSeed;
attribute float aSpeed;
uniform float uTime;
varying float vSeed;
void main() {
vSeed = aSeed;
vec3 pos = position;
pos.y += mod(aSeed + uTime * aSpeed, 10.0) - 5.0;
gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
}
` ,
fragmentShader : `
varying float vSeed;
void main() { gl_FragColor = vec4(vSeed, 0.5, 1.0 - vSeed, 1.0); }
` ,
});
const mesh = new THREE .InstancedMesh (geometry, material, count);
scene.add (mesh);
Performance Tips
InstancedMesh over individual meshes — 100+ identical objects = use instancing
Merge static geometry — buildings, terrain props that never move
Right segment count — 32 segments for spheres; 64×64 for subdivided planes; avoid excess
Index your geometry — shared vertices via index array = smaller GPU buffer
Non-indexed geometry for flat-shaded low-poly — avoids vertex duplication issues
Dispose on removal — geometry.dispose() frees GPU memory
console .log ('Draw calls:' , renderer.info .render .calls );
console .log ('Triangles:' , renderer.info .render .triangles );
console .log ('Geometries:' , renderer.info .memory .geometries );
See Also
threejs-fundamentals — scene setup and Object3D transforms
threejs-materials — materials for geometry
three-js-best-practices — draw-call budget and instancing rules
threejs-animation — morph target animation with AnimationMixer