Skip to content
Skillv1.0.0

threejs-geometry

Build and optimize Three.js geometry with built-in primitives, BufferGeometry, BufferAttributes, indexed meshes, custom vertex data, lines and points, and instanced rendering. Use when creating meshes

by akillness(0) 0 installs
Free
Sign in to install

Free account. Installing gives you the manifest plus copy-paste snippets.

See reviews

About

Imported from akillness/jeo-skills (.agent-skills/threejs-geometry/SKILL.md). Install upstream with npx skills add akillness/jeo-skills --skill threejs-geometry. Copyright stays with the author (MIT).

Three.js Geometry

Use this skill for mesh shape and vertex-data work. Route surface appearance to threejs-materials, image/UV asset handling to threejs-textures, and whole-scene setup to threejs-fundamentals.

When to use this skill

  • Choose a built-in primitive, BufferGeometry, ShapeGeometry, or text geometry
  • Generate positions, normals, colors, UVs, and indices for a custom mesh
  • Update dynamic attributes safely or fix broken normals, winding, and culling
  • Replace repeated identical meshes with InstancedMesh after measuring draw-call cost

Instructions

Step 1: Select the simplest geometry representation

  1. Start with a built-in geometry when its topology matches the feature.
  2. Use BufferGeometry for generated or imported vertex data; legacy Geometry is not a current Three.js path.
  3. Choose indexed geometry when vertices are genuinely shared. Do not index seams that require different normals, UVs, or vertex colors.
  4. Treat one mesh's geometry as immutable shared data unless the feature explicitly owns it; clone before per-instance mutation.

Step 2: Build valid attribute buffers

const geometry = new THREE.BufferGeometry();
geometry.setAttribute(
  "position",
  new THREE.Float32BufferAttribute([
    -1, -1, 0,
     1, -1, 0,
     0,  1, 0,
  ], 3),
);
geometry.setIndex([0, 1, 2]);
geometry.computeVertexNormals();
geometry.computeBoundingSphere();

const mesh = new THREE.Mesh(geometry, material);

Attribute item sizes must match their semantic: positions/normals are 3, UVs are 2, and colors are usually 3. Set attribute.needsUpdate = true after modifying a GPU-uploaded attribute. Recompute bounds whenever dynamic positions can move beyond prior bounds.

Step 3: Apply performance tools only for measured bottlenecks

Situation Preferred approach
Many copies of one geometry/material InstancedMesh
Per-instance color or transform Instance attributes/matrices
Large static terrain or model Indexed BufferGeometry, sensible culling
Thousands of tiny particles Points with one geometry/material
Debug edges or a technical wireframe EdgesGeometry / WireframeGeometry
Different topology or material Separate mesh; do not force instancing
const instances = new THREE.InstancedMesh(geometry, material, count);
const matrix = new THREE.Matrix4();
for (let i = 0; i < count; i += 1) {
  matrix.makeTranslation(i * 2, 0, 0);
  instances.setMatrixAt(i, matrix);
}
instances.instanceMatrix.needsUpdate = true;

Step 4: Manage ownership and teardown

Call geometry.dispose() when a feature-owned geometry has no consumers. Dispose replacements after swapping them out; do not dispose a cached/shared geometry from an asset loader until its last user is gone.

Step 5: Verify shape and budget

  • Inspect normals, UV seams, face winding, and bounding volumes with helpers/debug views.
  • Check a representative low- and high-density input for holes, NaNs, or backface loss.
  • Measure draw calls and GPU/CPU frame time before and after instancing.
  • Test dynamic geometry updates through the feature's normal lifecycle and teardown.

Examples

Build a disposable procedural grid

Generate attributes from stable input values, validate array lengths before upload, then store the geometry owner beside its cleanup function. Recreating a large geometry every frame is almost always a bug; mutate a dynamic attribute only when measurements justify it.

Center a loaded or generated mesh

Use geometry.computeBoundingBox() and derive an offset from its center, then update bounds. Avoid guessing center from a single vertex or applying a mesh transform when the asset's local origin is semantically important.

Best practices

  1. Keep coordinate-system and units conventions consistent with the scene.
  2. Use typed arrays; do not build hot vertex buffers from object arrays per frame.
  3. Recompute normals only when topology/positions require it, not on every render.
  4. Update bounds after dynamic position changes so frustum culling stays correct.
  5. Treat instancing as a draw-call optimization, not a cure for expensive shaders or over-detailed geometry.

References

Use it

Copy one of these into your project. Installing also returns the manifest and these snippets.

yaml
targets:
  - https://api.opensmartroute.ai/api/v1/registry/akillness-jeo-skills-threejs-geometry/manifest   # or paste the manifest below

Manifest

An Open Capability Manifest: the router reads it to know what this does, what it costs and when to pick it.

akillness-jeo-skills-threejs-geometry.ocm.jsonjson
{
  "ocm": "1",
  "id": "akillness-jeo-skills-threejs-geometry",
  "kind": "skill",
  "name": "threejs-geometry",
  "description": "Build and optimize Three.js geometry with built-in primitives, BufferGeometry, BufferAttributes, indexed meshes, custom vertex data, lines and points, and instanced rendering. Use when creating meshes, editing vertices or UVs, generating shapes, reducing draw calls, or diagnosing geometry memory and culling behavior. Triggers on: Three.js geometry, BufferGeometry, BufferAttribute, vertices, indices, custom mesh, InstancedMesh, instancing, draw calls, line geometry, points, mesh optimization.",
  "publisher": "akillness",
  "version": "1.0.0",
  "capabilities": {
    "domains": [
      "math"
    ],
    "tags": [
      "skill-md",
      "three-js",
      "geometry",
      "buffergeometry",
      "bufferattribute",
      "instancing",
      "meshes",
      "webgl",
      "skills-sh"
    ],
    "languages": [
      "en"
    ]
  },
  "quality_prior": 0.6,
  "examples": [
    "Build and optimize Three.js geometry with built-in primitives, BufferGeometry, BufferAttributes, indexed meshes, custom vertex data, lines and points, and instanced rendering. Use when creating meshes, editing vertices or UVs, generating shapes, reducing draw calls, or diagnosing geometry memory and culling behavior. Triggers on: Three.js geometry, BufferGeometry, BufferAttribute, vertices, indices, custom mesh, InstancedMesh, instancing, draw calls, line geometry, points, mesh optimization."
  ],
  "primary": false,
  "metadata": {
    "source": {
      "provider": "skills.sh",
      "repository": "https://github.com/akillness/jeo-skills",
      "path": ".agent-skills/threejs-geometry/SKILL.md",
      "ref": "HEAD",
      "url": "https://github.com/akillness/jeo-skills/blob/HEAD/.agent-skills/threejs-geometry/SKILL.md",
      "key": "akillness/jeo-skills/.agent-skills/threejs-geometry/SKILL.md"
    },
    "allowed_tools": [
      "Bash",
      "Read",
      "Write",
      "Edit",
      "Glob",
      "Grep"
    ],
    "license": "MIT"
  },
  "instructions": "# Three.js Geometry\n\nUse this skill for mesh shape and vertex-data work. Route surface appearance to\n`threejs-materials`, image/UV asset handling to `threejs-textures`, and whole-scene setup\nto `threejs-fundamentals`.\n\n## When to use this skill\n\n- Choose a built-in primitive, `BufferGeometry`, `ShapeGeometry`, or text geometry\n- Generate positions, normals, colors, UVs, and indices for a custom mesh\n- Update dynamic attributes safely or fix broken normals, winding, and culling\n- Replace repeated identical meshes with `InstancedMesh` after measuring draw-call cost\n\n## Instructions\n\n### Step 1: ",
  "cost": {
    "context_tokens": 1135
  }
}

Fetch it by URL: GET /api/v1/registry/akillness-jeo-skills-threejs-geometry/manifest?version=1.0.0

Reviews

Star ratings from people who tried it. One review per account; edit yours any time.

No reviews yet. Install it, try it, and be the first to rate it.