Skip to main content 首页 创作者 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).
跳到安装 Skills Marketplace 发现并探索由社区构建的 Agent Skills
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/afovea/game-dev-skills --skill threejs-geometry命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
下载 Zip 下载中... 同仓库更多 Skills 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