create-threejs-game 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +97 -0
  2. package/bin/cli.js +370 -0
  3. package/package.json +29 -0
  4. package/template/.claude/skills/threejs-animation/SKILL.md +552 -0
  5. package/template/.claude/skills/threejs-fundamentals/SKILL.md +488 -0
  6. package/template/.claude/skills/threejs-geometry/SKILL.md +548 -0
  7. package/template/.claude/skills/threejs-interaction/SKILL.md +660 -0
  8. package/template/.claude/skills/threejs-lighting/SKILL.md +481 -0
  9. package/template/.claude/skills/threejs-loaders/SKILL.md +623 -0
  10. package/template/.claude/skills/threejs-materials/SKILL.md +520 -0
  11. package/template/.claude/skills/threejs-postprocessing/SKILL.md +602 -0
  12. package/template/.claude/skills/threejs-shaders/SKILL.md +642 -0
  13. package/template/.claude/skills/threejs-textures/SKILL.md +628 -0
  14. package/template/.codex/skills/threejs-animation/SKILL.md +552 -0
  15. package/template/.codex/skills/threejs-fundamentals/SKILL.md +488 -0
  16. package/template/.codex/skills/threejs-geometry/SKILL.md +548 -0
  17. package/template/.codex/skills/threejs-interaction/SKILL.md +660 -0
  18. package/template/.codex/skills/threejs-lighting/SKILL.md +481 -0
  19. package/template/.codex/skills/threejs-loaders/SKILL.md +623 -0
  20. package/template/.codex/skills/threejs-materials/SKILL.md +520 -0
  21. package/template/.codex/skills/threejs-postprocessing/SKILL.md +602 -0
  22. package/template/.codex/skills/threejs-shaders/SKILL.md +642 -0
  23. package/template/.codex/skills/threejs-textures/SKILL.md +628 -0
  24. package/template/README.md +352 -0
  25. package/template/docs/.gitkeep +0 -0
  26. package/template/plans/.gitkeep +0 -0
  27. package/template/prompts/01-mockup-generation.md +44 -0
  28. package/template/prompts/02-prd-generation.md +119 -0
  29. package/template/prompts/03-tdd-generation.md +127 -0
  30. package/template/prompts/04-execution-plan.md +89 -0
  31. package/template/prompts/05-implementation.md +61 -0
  32. package/template/public/assets/.gitkeep +0 -0
  33. package/template/scripts/config.example.json +12 -0
  34. package/template/scripts/generate-assets-json.js +149 -0
  35. package/template/scripts/generate-mockup.js +197 -0
  36. package/template/scripts/generate-plan.js +295 -0
  37. package/template/scripts/generate-prd.js +297 -0
  38. package/template/scripts/generate-tdd.js +283 -0
  39. package/template/scripts/pipeline.js +229 -0
@@ -0,0 +1,548 @@
1
+ ---
2
+ name: threejs-geometry
3
+ description: 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.
4
+ ---
5
+
6
+ # Three.js Geometry
7
+
8
+ ## Quick Start
9
+
10
+ ```javascript
11
+ import * as THREE from "three";
12
+
13
+ // Built-in geometry
14
+ const box = new THREE.BoxGeometry(1, 1, 1);
15
+ const sphere = new THREE.SphereGeometry(0.5, 32, 32);
16
+ const plane = new THREE.PlaneGeometry(10, 10);
17
+
18
+ // Create mesh
19
+ const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });
20
+ const mesh = new THREE.Mesh(box, material);
21
+ scene.add(mesh);
22
+ ```
23
+
24
+ ## Built-in Geometries
25
+
26
+ ### Basic Shapes
27
+
28
+ ```javascript
29
+ // Box - width, height, depth, widthSegments, heightSegments, depthSegments
30
+ new THREE.BoxGeometry(1, 1, 1, 1, 1, 1);
31
+
32
+ // Sphere - radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength
33
+ new THREE.SphereGeometry(1, 32, 32);
34
+ new THREE.SphereGeometry(1, 32, 32, 0, Math.PI * 2, 0, Math.PI); // Full sphere
35
+ new THREE.SphereGeometry(1, 32, 32, 0, Math.PI); // Hemisphere
36
+
37
+ // Plane - width, height, widthSegments, heightSegments
38
+ new THREE.PlaneGeometry(10, 10, 1, 1);
39
+
40
+ // Circle - radius, segments, thetaStart, thetaLength
41
+ new THREE.CircleGeometry(1, 32);
42
+ new THREE.CircleGeometry(1, 32, 0, Math.PI); // Semicircle
43
+
44
+ // Cylinder - radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded
45
+ new THREE.CylinderGeometry(1, 1, 2, 32, 1, false);
46
+ new THREE.CylinderGeometry(0, 1, 2, 32); // Cone
47
+ new THREE.CylinderGeometry(1, 1, 2, 6); // Hexagonal prism
48
+
49
+ // Cone - radius, height, radialSegments, heightSegments, openEnded
50
+ new THREE.ConeGeometry(1, 2, 32, 1, false);
51
+
52
+ // Torus - radius, tube, radialSegments, tubularSegments, arc
53
+ new THREE.TorusGeometry(1, 0.4, 16, 100);
54
+
55
+ // TorusKnot - radius, tube, tubularSegments, radialSegments, p, q
56
+ new THREE.TorusKnotGeometry(1, 0.4, 100, 16, 2, 3);
57
+
58
+ // Ring - innerRadius, outerRadius, thetaSegments, phiSegments
59
+ new THREE.RingGeometry(0.5, 1, 32, 1);
60
+ ```
61
+
62
+ ### Advanced Shapes
63
+
64
+ ```javascript
65
+ // Capsule - radius, length, capSegments, radialSegments
66
+ new THREE.CapsuleGeometry(0.5, 1, 4, 8);
67
+
68
+ // Dodecahedron - radius, detail
69
+ new THREE.DodecahedronGeometry(1, 0);
70
+
71
+ // Icosahedron - radius, detail (0 = 20 faces, higher = smoother)
72
+ new THREE.IcosahedronGeometry(1, 0);
73
+
74
+ // Octahedron - radius, detail
75
+ new THREE.OctahedronGeometry(1, 0);
76
+
77
+ // Tetrahedron - radius, detail
78
+ new THREE.TetrahedronGeometry(1, 0);
79
+
80
+ // Polyhedron - vertices, indices, radius, detail
81
+ const vertices = [1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1];
82
+ const indices = [2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1];
83
+ new THREE.PolyhedronGeometry(vertices, indices, 1, 0);
84
+ ```
85
+
86
+ ### Path-Based Shapes
87
+
88
+ ```javascript
89
+ // Lathe - points[], segments, phiStart, phiLength
90
+ const points = [
91
+ new THREE.Vector2(0, 0),
92
+ new THREE.Vector2(0.5, 0),
93
+ new THREE.Vector2(0.5, 1),
94
+ new THREE.Vector2(0, 1),
95
+ ];
96
+ new THREE.LatheGeometry(points, 32);
97
+
98
+ // Extrude - shape, options
99
+ const shape = new THREE.Shape();
100
+ shape.moveTo(0, 0);
101
+ shape.lineTo(1, 0);
102
+ shape.lineTo(1, 1);
103
+ shape.lineTo(0, 1);
104
+ shape.lineTo(0, 0);
105
+
106
+ const extrudeSettings = {
107
+ steps: 2,
108
+ depth: 1,
109
+ bevelEnabled: true,
110
+ bevelThickness: 0.1,
111
+ bevelSize: 0.1,
112
+ bevelSegments: 3,
113
+ };
114
+ new THREE.ExtrudeGeometry(shape, extrudeSettings);
115
+
116
+ // Tube - path, tubularSegments, radius, radialSegments, closed
117
+ const curve = new THREE.CatmullRomCurve3([
118
+ new THREE.Vector3(-1, 0, 0),
119
+ new THREE.Vector3(0, 1, 0),
120
+ new THREE.Vector3(1, 0, 0),
121
+ ]);
122
+ new THREE.TubeGeometry(curve, 64, 0.2, 8, false);
123
+ ```
124
+
125
+ ### Text Geometry
126
+
127
+ ```javascript
128
+ import { FontLoader } from "three/examples/jsm/loaders/FontLoader.js";
129
+ import { TextGeometry } from "three/examples/jsm/geometries/TextGeometry.js";
130
+
131
+ const loader = new FontLoader();
132
+ loader.load("fonts/helvetiker_regular.typeface.json", (font) => {
133
+ const geometry = new TextGeometry("Hello", {
134
+ font: font,
135
+ size: 1,
136
+ depth: 0.2, // Was 'height' in older versions
137
+ curveSegments: 12,
138
+ bevelEnabled: true,
139
+ bevelThickness: 0.03,
140
+ bevelSize: 0.02,
141
+ bevelSegments: 5,
142
+ });
143
+
144
+ // Center text
145
+ geometry.computeBoundingBox();
146
+ geometry.center();
147
+
148
+ const mesh = new THREE.Mesh(geometry, material);
149
+ scene.add(mesh);
150
+ });
151
+ ```
152
+
153
+ ## BufferGeometry
154
+
155
+ The base class for all geometries. Stores data as typed arrays for GPU efficiency.
156
+
157
+ ### Custom BufferGeometry
158
+
159
+ ```javascript
160
+ const geometry = new THREE.BufferGeometry();
161
+
162
+ // Vertices (3 floats per vertex: x, y, z)
163
+ const vertices = new Float32Array([
164
+ -1,
165
+ -1,
166
+ 0, // vertex 0
167
+ 1,
168
+ -1,
169
+ 0, // vertex 1
170
+ 1,
171
+ 1,
172
+ 0, // vertex 2
173
+ -1,
174
+ 1,
175
+ 0, // vertex 3
176
+ ]);
177
+ geometry.setAttribute("position", new THREE.BufferAttribute(vertices, 3));
178
+
179
+ // Indices (for indexed geometry - reuse vertices)
180
+ const indices = new Uint16Array([
181
+ 0,
182
+ 1,
183
+ 2, // triangle 1
184
+ 0,
185
+ 2,
186
+ 3, // triangle 2
187
+ ]);
188
+ geometry.setIndex(new THREE.BufferAttribute(indices, 1));
189
+
190
+ // Normals (required for lighting)
191
+ const normals = new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]);
192
+ geometry.setAttribute("normal", new THREE.BufferAttribute(normals, 3));
193
+
194
+ // UVs (for texturing)
195
+ const uvs = new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]);
196
+ geometry.setAttribute("uv", new THREE.BufferAttribute(uvs, 2));
197
+
198
+ // Colors (per-vertex colors)
199
+ const colors = new Float32Array([
200
+ 1,
201
+ 0,
202
+ 0, // red
203
+ 0,
204
+ 1,
205
+ 0, // green
206
+ 0,
207
+ 0,
208
+ 1, // blue
209
+ 1,
210
+ 1,
211
+ 0, // yellow
212
+ ]);
213
+ geometry.setAttribute("color", new THREE.BufferAttribute(colors, 3));
214
+ // Use with: material.vertexColors = true
215
+ ```
216
+
217
+ ### BufferAttribute Types
218
+
219
+ ```javascript
220
+ // Common attribute types
221
+ new THREE.BufferAttribute(array, itemSize);
222
+
223
+ // Typed array options
224
+ new Float32Array(count * itemSize); // Positions, normals, UVs
225
+ new Uint16Array(count); // Indices (up to 65535 vertices)
226
+ new Uint32Array(count); // Indices (larger meshes)
227
+ new Uint8Array(count * itemSize); // Colors (0-255 range)
228
+
229
+ // Item sizes
230
+ // Position: 3 (x, y, z)
231
+ // Normal: 3 (x, y, z)
232
+ // UV: 2 (u, v)
233
+ // Color: 3 (r, g, b) or 4 (r, g, b, a)
234
+ // Index: 1
235
+ ```
236
+
237
+ ### Modifying BufferGeometry
238
+
239
+ ```javascript
240
+ const positions = geometry.attributes.position;
241
+
242
+ // Modify vertex
243
+ positions.setXYZ(index, x, y, z);
244
+
245
+ // Access vertex
246
+ const x = positions.getX(index);
247
+ const y = positions.getY(index);
248
+ const z = positions.getZ(index);
249
+
250
+ // Flag for GPU update
251
+ positions.needsUpdate = true;
252
+
253
+ // Recompute normals after position changes
254
+ geometry.computeVertexNormals();
255
+
256
+ // Recompute bounding box/sphere after changes
257
+ geometry.computeBoundingBox();
258
+ geometry.computeBoundingSphere();
259
+ ```
260
+
261
+ ### Interleaved Buffers (Advanced)
262
+
263
+ ```javascript
264
+ // More efficient memory layout for large meshes
265
+ const interleavedBuffer = new THREE.InterleavedBuffer(
266
+ new Float32Array([
267
+ // pos.x, pos.y, pos.z, uv.u, uv.v (repeated per vertex)
268
+ -1, -1, 0, 0, 0, 1, -1, 0, 1, 0, 1, 1, 0, 1, 1, -1, 1, 0, 0, 1,
269
+ ]),
270
+ 5, // stride (floats per vertex)
271
+ );
272
+
273
+ geometry.setAttribute(
274
+ "position",
275
+ new THREE.InterleavedBufferAttribute(interleavedBuffer, 3, 0),
276
+ ); // size 3, offset 0
277
+ geometry.setAttribute(
278
+ "uv",
279
+ new THREE.InterleavedBufferAttribute(interleavedBuffer, 2, 3),
280
+ ); // size 2, offset 3
281
+ ```
282
+
283
+ ## EdgesGeometry & WireframeGeometry
284
+
285
+ ```javascript
286
+ // Edge lines (only hard edges)
287
+ const edges = new THREE.EdgesGeometry(boxGeometry, 15); // 15 = threshold angle
288
+ const edgeMesh = new THREE.LineSegments(
289
+ edges,
290
+ new THREE.LineBasicMaterial({ color: 0xffffff }),
291
+ );
292
+
293
+ // Wireframe (all triangles)
294
+ const wireframe = new THREE.WireframeGeometry(boxGeometry);
295
+ const wireMesh = new THREE.LineSegments(
296
+ wireframe,
297
+ new THREE.LineBasicMaterial({ color: 0xffffff }),
298
+ );
299
+ ```
300
+
301
+ ## Points
302
+
303
+ ```javascript
304
+ // Create point cloud
305
+ const geometry = new THREE.BufferGeometry();
306
+ const positions = new Float32Array(1000 * 3);
307
+
308
+ for (let i = 0; i < 1000; i++) {
309
+ positions[i * 3] = (Math.random() - 0.5) * 10;
310
+ positions[i * 3 + 1] = (Math.random() - 0.5) * 10;
311
+ positions[i * 3 + 2] = (Math.random() - 0.5) * 10;
312
+ }
313
+
314
+ geometry.setAttribute("position", new THREE.BufferAttribute(positions, 3));
315
+
316
+ const material = new THREE.PointsMaterial({
317
+ size: 0.1,
318
+ sizeAttenuation: true, // Size decreases with distance
319
+ color: 0xffffff,
320
+ });
321
+
322
+ const points = new THREE.Points(geometry, material);
323
+ scene.add(points);
324
+ ```
325
+
326
+ ## Lines
327
+
328
+ ```javascript
329
+ // Line (connected points)
330
+ const points = [
331
+ new THREE.Vector3(-1, 0, 0),
332
+ new THREE.Vector3(0, 1, 0),
333
+ new THREE.Vector3(1, 0, 0),
334
+ ];
335
+ const geometry = new THREE.BufferGeometry().setFromPoints(points);
336
+ const line = new THREE.Line(
337
+ geometry,
338
+ new THREE.LineBasicMaterial({ color: 0xff0000 }),
339
+ );
340
+
341
+ // LineLoop (closed loop)
342
+ const loop = new THREE.LineLoop(geometry, material);
343
+
344
+ // LineSegments (pairs of points)
345
+ const segmentsGeometry = new THREE.BufferGeometry();
346
+ segmentsGeometry.setAttribute(
347
+ "position",
348
+ new THREE.BufferAttribute(
349
+ new Float32Array([
350
+ -1,
351
+ 0,
352
+ 0,
353
+ 0,
354
+ 1,
355
+ 0, // segment 1
356
+ 0,
357
+ 1,
358
+ 0,
359
+ 1,
360
+ 0,
361
+ 0, // segment 2
362
+ ]),
363
+ 3,
364
+ ),
365
+ );
366
+ const segments = new THREE.LineSegments(segmentsGeometry, material);
367
+ ```
368
+
369
+ ## InstancedMesh
370
+
371
+ Efficiently render many copies of the same geometry.
372
+
373
+ ```javascript
374
+ const geometry = new THREE.BoxGeometry(1, 1, 1);
375
+ const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });
376
+ const count = 1000;
377
+
378
+ const instancedMesh = new THREE.InstancedMesh(geometry, material, count);
379
+
380
+ // Set transforms for each instance
381
+ const dummy = new THREE.Object3D();
382
+ const matrix = new THREE.Matrix4();
383
+
384
+ for (let i = 0; i < count; i++) {
385
+ dummy.position.set(
386
+ (Math.random() - 0.5) * 20,
387
+ (Math.random() - 0.5) * 20,
388
+ (Math.random() - 0.5) * 20,
389
+ );
390
+ dummy.rotation.set(Math.random() * Math.PI, Math.random() * Math.PI, 0);
391
+ dummy.scale.setScalar(0.5 + Math.random());
392
+ dummy.updateMatrix();
393
+
394
+ instancedMesh.setMatrixAt(i, dummy.matrix);
395
+ }
396
+
397
+ // Flag for GPU update
398
+ instancedMesh.instanceMatrix.needsUpdate = true;
399
+
400
+ // Optional: per-instance colors
401
+ instancedMesh.instanceColor = new THREE.InstancedBufferAttribute(
402
+ new Float32Array(count * 3),
403
+ 3,
404
+ );
405
+ for (let i = 0; i < count; i++) {
406
+ instancedMesh.setColorAt(
407
+ i,
408
+ new THREE.Color(Math.random(), Math.random(), Math.random()),
409
+ );
410
+ }
411
+ instancedMesh.instanceColor.needsUpdate = true;
412
+
413
+ scene.add(instancedMesh);
414
+ ```
415
+
416
+ ### Update Instance at Runtime
417
+
418
+ ```javascript
419
+ // Update single instance
420
+ const matrix = new THREE.Matrix4();
421
+ instancedMesh.getMatrixAt(index, matrix);
422
+ // Modify matrix...
423
+ instancedMesh.setMatrixAt(index, matrix);
424
+ instancedMesh.instanceMatrix.needsUpdate = true;
425
+
426
+ // Raycasting with instanced mesh
427
+ const intersects = raycaster.intersectObject(instancedMesh);
428
+ if (intersects.length > 0) {
429
+ const instanceId = intersects[0].instanceId;
430
+ }
431
+ ```
432
+
433
+ ## InstancedBufferGeometry (Advanced)
434
+
435
+ For custom per-instance attributes beyond transform/color.
436
+
437
+ ```javascript
438
+ const geometry = new THREE.InstancedBufferGeometry();
439
+ geometry.copy(new THREE.BoxGeometry(1, 1, 1));
440
+
441
+ // Add per-instance attribute
442
+ const offsets = new Float32Array(count * 3);
443
+ for (let i = 0; i < count; i++) {
444
+ offsets[i * 3] = Math.random() * 10;
445
+ offsets[i * 3 + 1] = Math.random() * 10;
446
+ offsets[i * 3 + 2] = Math.random() * 10;
447
+ }
448
+ geometry.setAttribute("offset", new THREE.InstancedBufferAttribute(offsets, 3));
449
+
450
+ // Use in shader
451
+ // attribute vec3 offset;
452
+ // vec3 transformed = position + offset;
453
+ ```
454
+
455
+ ## Geometry Utilities
456
+
457
+ ```javascript
458
+ import * as BufferGeometryUtils from "three/examples/jsm/utils/BufferGeometryUtils.js";
459
+
460
+ // Merge geometries (must have same attributes)
461
+ const merged = BufferGeometryUtils.mergeGeometries([geo1, geo2, geo3]);
462
+
463
+ // Merge with groups (for multi-material)
464
+ const merged = BufferGeometryUtils.mergeGeometries([geo1, geo2], true);
465
+
466
+ // Compute tangents (required for normal maps)
467
+ BufferGeometryUtils.computeTangents(geometry);
468
+
469
+ // Interleave attributes for better performance
470
+ const interleaved = BufferGeometryUtils.interleaveAttributes([
471
+ geometry.attributes.position,
472
+ geometry.attributes.normal,
473
+ geometry.attributes.uv,
474
+ ]);
475
+ ```
476
+
477
+ ## Common Patterns
478
+
479
+ ### Center Geometry
480
+
481
+ ```javascript
482
+ geometry.computeBoundingBox();
483
+ geometry.center(); // Move vertices so center is at origin
484
+ ```
485
+
486
+ ### Scale to Fit
487
+
488
+ ```javascript
489
+ geometry.computeBoundingBox();
490
+ const size = new THREE.Vector3();
491
+ geometry.boundingBox.getSize(size);
492
+ const maxDim = Math.max(size.x, size.y, size.z);
493
+ geometry.scale(1 / maxDim, 1 / maxDim, 1 / maxDim);
494
+ ```
495
+
496
+ ### Clone and Transform
497
+
498
+ ```javascript
499
+ const clone = geometry.clone();
500
+ clone.rotateX(Math.PI / 2);
501
+ clone.translate(0, 1, 0);
502
+ clone.scale(2, 2, 2);
503
+ ```
504
+
505
+ ### Morph Targets
506
+
507
+ ```javascript
508
+ // Base geometry
509
+ const geometry = new THREE.BoxGeometry(1, 1, 1, 4, 4, 4);
510
+
511
+ // Create morph target
512
+ const morphPositions = geometry.attributes.position.array.slice();
513
+ for (let i = 0; i < morphPositions.length; i += 3) {
514
+ morphPositions[i] *= 2; // Scale X
515
+ morphPositions[i + 1] *= 0.5; // Squash Y
516
+ }
517
+
518
+ geometry.morphAttributes.position = [
519
+ new THREE.BufferAttribute(new Float32Array(morphPositions), 3),
520
+ ];
521
+
522
+ const mesh = new THREE.Mesh(geometry, material);
523
+ mesh.morphTargetInfluences[0] = 0.5; // 50% blend
524
+ ```
525
+
526
+ ## Performance Tips
527
+
528
+ 1. **Use indexed geometry**: Reuse vertices with indices
529
+ 2. **Merge static meshes**: Reduce draw calls with `mergeGeometries`
530
+ 3. **Use InstancedMesh**: For many identical objects
531
+ 4. **Choose appropriate segment counts**: More segments = smoother but slower
532
+ 5. **Dispose unused geometry**: `geometry.dispose()`
533
+
534
+ ```javascript
535
+ // Good segment counts for common uses
536
+ new THREE.SphereGeometry(1, 32, 32); // Good quality
537
+ new THREE.SphereGeometry(1, 64, 64); // High quality
538
+ new THREE.SphereGeometry(1, 16, 16); // Performance mode
539
+
540
+ // Dispose when done
541
+ geometry.dispose();
542
+ ```
543
+
544
+ ## See Also
545
+
546
+ - `threejs-fundamentals` - Scene setup and Object3D
547
+ - `threejs-materials` - Material types for meshes
548
+ - `threejs-shaders` - Custom vertex manipulation