Primary target surface
These rendering routes are generated from canonical source. Native-WebGPU acceptance remains separate from entrypoint availability.
Procedural geometry compilation for Three.js WebGPU/TSL. Use when a task needs an indexed mesh writer, contour-derived terrain or terraces, profile or branch sweeps, or a BatchedMesh, InstancedMesh, or dynamic-update decision.
These rendering routes are generated from canonical source. Native-WebGPU acceptance remains separate from entrypoint availability.
This skill contributes to the following cross-skill owner graphs.
Source hashes, claim verdicts, promoted same-lab media, fixed routes, exact tier contracts, and current limitations.
Meshes are written by semantic writers: rings, profiles, and lofts emitted into indexed buffers with explicit attribute ownership. A profile swept along a frame uses parallel transport to avoid twist — the frame advances by the minimal rotation between tangents:
$$\mathbf n_{i+1} = R\big(\mathbf t_i \times \mathbf t_{i+1},\; \angle(\mathbf t_i, \mathbf t_{i+1})\big)\,\mathbf n_i$$Smooth normals accumulate face normals weighted by corner angle, then normalize: $\mathbf n_v = \operatorname{normalize}\sum_f \theta_{v,f}\,\mathbf n_f$. Index sharing versus splitting is decided by crease angle: split when $\mathbf n_a \cdot \mathbf n_b < \cos\theta_{crease}$.
Draw-call strategy is a budget decision: $N$ unique shapes × $M$ instances favors BatchedMesh when shapes vary, InstancedMesh when only transforms do — one material slot per identity either way.
Only schema-v2 labs with accepted runtime and evidence contracts appear here. Other source directories remain visible through the demo registry without being promoted to runnable proof.
Every image identifies what it proves. Page screenshots demonstrate the published presentation only; generated inputs demonstrate asset channels only; rendering acceptance still requires same-lab readback and a schema-v2 bundle.
0 published imagesThe complete SKILL.md as loaded by agents, rendered verbatim.
Treat geometry generation as a compiler: select the representation, freeze semantic regions and error bounds, compute exact capacity, emit topology and render attributes, then validate both. Meaning belongs to generator inputs; allocation, topology, groups, updates, and disposal belong to the writer.
For multi-system work, $threejs-choose-skills is an optional coordinator.
Fields own continuous causes, materials own PBR response, motion owns
deformation state, and this skill owns rendered topology. When geometry supplies
another system, publish stable units, coordinate/frame convention, producer and
consumer owners, revision, support, validity domain, error bound, and update
phase independently of render LOD and draw indices.
Choose from the observable and update pattern:
| Contract | Representation |
|---|---|
| one unique authored surface with material regions | indexed BufferGeometry with groups |
| many same-material objects with varied topology | BatchedMesh |
| many repeats with identical topology | InstancedMesh |
| GPU-owned transforms or visibility with identical topology | matrix-free instanced geometry plus storage-backed state |
| hot visibility compaction with stable buckets | storage data plus indirect draw commands |
| continuous single-valued relief | indexed adaptive grid, quadtree, or clipmap with a seam policy |
| hard terraces, cliffs, or topology-bearing bands | contour-derived caps plus explicit walls/band meshes |
| visible overhangs or caves | bounded volumetric meshing after memory/topology gates pass |
In r185 WebGPU, BatchedMesh manages geometry and culling but the backend still
iterates visible multi-draw entries; it is not evidence of one native draw.
InstancedMesh is valid only for identical topology.
This step is complete when one representation owns each surface/object class, its culling and update unit is named, and no triangle or buffer has been emitted.
Record coordinate frames, semantic dimensions, named regions, material slots, smoothing groups, UV charts, hard boundaries, topology identities, LOD view envelope, and resource owner. Gate each LOD with a conservative error bound in physical render-target pixels at the actual target size and an unjittered view. Include the complete support and error of geometry, active displacement or deformation, filtering, and reconstruction. Use the exact camera projection or, for a perspective approximation, the nearest valid positive view depth; accept the LOD only when the projected bound is at or below that view's declared threshold. Give each view separate enter/exit thresholds with hysteresis and a minimum dwell, and keep both transition levels resident until the transition finishes. Triangle ratios are supporting counts, not an error bound.
For contour-driven work, consume one versioned field source. Read contour topology and terrain compilation before extracting a shoreline, terrace, band, cliff, or region with holes.
When placement, picking, or measurement anchors must survive LOD or rebuilds, read semantic anchors and LOD bindings before decimation.
This step is complete when every intended face belongs to a semantic region, material slot, smoothing group, UV chart, topology identity, and projected-error gate, and every required anchor has a stable source/topology identity and LOD binding policy.
Count render vertices after all required duplication and count indices before allocation:
vertexCount = smooth vertices + hard-edge duplicates + UV seams
+ material-boundary duplicates + caps and explicit boundaries
indexCount = 3 * triangleCount
Allocate typed arrays once. Use Uint16Array only when the highest referenced
vertex is at most 65535; otherwise use Uint32Array. Emit through a small
writer surface such as:
addVertex, addTriangle, addQuad
duplicateForBoundary
startSmoothingGroup, startUvChart, addGroup
finishGeometry
Every index belongs to exactly one nonoverlapping group with a stable material
index. finishGeometry asserts the planned and written counts match.
This step is complete when allocation equals the planned capacity exactly, every emitted index is owned by one group, and overflow or unfilled capacity is an explicit error.
Keep topological identity separate from render-vertex identity. Render vertices duplicate at hard normals, material boundaries, UV seams, and mirrored tangent spaces while topological edges still prove adjacency and closure.
Use analytic normals/tangents where the generator owns a parameterization.
computeVertexNormals() is for deliberately smooth shared-vertex regions. For
normal-map parity, await MikkTSpace.ready before
computeMikkTSpaceTangents(...); r185 de-indexes indexed geometry, so recompute
counts, groups, bounds, and bytes for that distinct representation.
Production UVs express physical distance or declared repeats; normalized local parameters belong in a separate debug attribute. Profile and branch sweeps use a rotation-minimizing parallel-transport frame with an explicit antiparallel fallback and closed-loop holonomy correction.
Read profile sweeps and transported frames when emitting along a curve.
This step is complete when topology closes at every undeclared boundary, normals/tangents match semantic boundaries, UV density is stable across LOD, and transported frames remain continuous through zero curvature and inflections.
Initialize and gate the renderer before allocating GPU-owned storage or indirect commands:
await renderer.init();
if (renderer.backend.isWebGPUBackend !== true) {
throw new Error('Native WebGPU is required for geometry storage and indirect draws.');
}
Check the selected storage bindings and buffer usage against the initialized device limits before compilation.
Set attribute usage before first render. Static geometry uploads once and may
release CPU arrays only when no rebuild requires them. Dynamic sections use
addUpdateRange() in component units, needsUpdate, and targeted bounds
recomputation. Capacity, item size, or usage-model changes rebuild the owning
attribute/geometry rather than mutating its contract.
When compute owns instance state, submit compute before the consuming render
and keep one transform owner. In r185, computeAsync() is not a GPU-completion
fence. Indirect commands use CPU-known byte offsets and stable homogeneous
buckets; shader masking is not visibility compaction.
Read batching, dynamic updates, and indirect draws before adding a batch container, per-frame mutation, storage state, or indirect draw.
This step is complete when each mutable byte range, dispatch, draw entry, bounding volume, and disposal point has one owner and hidden work is absent from the claimed culling result.
Validate topological identities before render duplication, then the final
BufferGeometry:
Diagnostics expose topological versus render IDs, boundaries, winding, normals, tangents, UV density, material groups, LOD/seam error, batch identity, and dirty ranges.
This step is complete when every semantic region passes topology, attribute, LOD, group, bounds, byte, lifecycle, and claimed performance gates, including adversarial contour and frame cases selected by the active branches.
The geometry system is complete when representation precedes allocation; exact capacity equals emitted data; semantic topology survives render duplication, batching, updates, and LOD; every index and mutable byte has one owner; and the final mesh passes topology, attribute, projected-error, resource, and lifecycle checks.
Preserved concept proxies and generated-asset previews. They are excluded from primary completion counts and link to the canonical lab through the schema-v2 registry.