Claude Agent Skill · by Cloudai X

Threejs Fundamentals

Install Threejs Fundamentals skill for Claude Code from cloudai-x/threejs-skills.

Install
Terminal · npx
$npx skills add https://github.com/cloudai-x/threejs-skills --skill threejs-fundamentals
Works with Paperclip

How Threejs Fundamentals fits into a Paperclip company.

Threejs Fundamentals drops into any Paperclip agent that handles this kind of work. Assign it to a specialist inside a pre-configured PaperclipOrg company and the skill becomes available on every heartbeat — no prompt engineering, no tool wiring.

S
SaaS FactoryPaired

Pre-configured AI company — 18 agents, 18 skills, one-time purchase.

$27$59
Explore pack
Source file
SKILL.md488 lines
Expand
---name: threejs-fundamentalsdescription: Three.js scene setup, cameras, renderer, Object3D hierarchy, coordinate systems. Use when setting up 3D scenes, creating cameras, configuring renderers, managing object hierarchies, or working with transforms.--- # Three.js Fundamentals ## Quick Start ```javascriptimport * as THREE from "three"; // Create scene, camera, rendererconst scene = new THREE.Scene();const camera = new THREE.PerspectiveCamera(  75,  window.innerWidth / window.innerHeight,  0.1,  1000,);const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight);renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));document.body.appendChild(renderer.domElement); // Add a meshconst geometry = new THREE.BoxGeometry(1, 1, 1);const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });const cube = new THREE.Mesh(geometry, material);scene.add(cube); // Add lightscene.add(new THREE.AmbientLight(0xffffff, 0.5));const dirLight = new THREE.DirectionalLight(0xffffff, 1);dirLight.position.set(5, 5, 5);scene.add(dirLight); camera.position.z = 5; // Animation loopfunction animate() {  requestAnimationFrame(animate);  cube.rotation.x += 0.01;  cube.rotation.y += 0.01;  renderer.render(scene, camera);}animate(); // Handle resizewindow.addEventListener("resize", () => {  camera.aspect = window.innerWidth / window.innerHeight;  camera.updateProjectionMatrix();  renderer.setSize(window.innerWidth, window.innerHeight);});``` ## Core Classes ### Scene Container for all 3D objects, lights, and cameras. ```javascriptconst scene = new THREE.Scene();scene.background = new THREE.Color(0x000000); // Solid colorscene.background = texture; // Skybox texturescene.background = cubeTexture; // Cubemapscene.environment = envMap; // Environment map for PBRscene.fog = new THREE.Fog(0xffffff, 1, 100); // Linear fogscene.fog = new THREE.FogExp2(0xffffff, 0.02); // Exponential fog``` ### Cameras **PerspectiveCamera** - Most common, simulates human eye. ```javascript// PerspectiveCamera(fov, aspect, near, far)const camera = new THREE.PerspectiveCamera(  75, // Field of view (degrees)  window.innerWidth / window.innerHeight, // Aspect ratio  0.1, // Near clipping plane  1000, // Far clipping plane); camera.position.set(0, 5, 10);camera.lookAt(0, 0, 0);camera.updateProjectionMatrix(); // Call after changing fov, aspect, near, far``` **OrthographicCamera** - No perspective distortion, good for 2D/isometric. ```javascript// OrthographicCamera(left, right, top, bottom, near, far)const aspect = window.innerWidth / window.innerHeight;const frustumSize = 10;const camera = new THREE.OrthographicCamera(  (frustumSize * aspect) / -2,  (frustumSize * aspect) / 2,  frustumSize / 2,  frustumSize / -2,  0.1,  1000,);``` **ArrayCamera** - Multiple viewports with sub-cameras. ```javascriptconst cameras = [];for (let i = 0; i < 4; i++) {  const subcamera = new THREE.PerspectiveCamera(40, 1, 0.1, 100);  subcamera.viewport = new THREE.Vector4(    Math.floor(i % 2) * 0.5,    Math.floor(i / 2) * 0.5,    0.5,    0.5,  );  cameras.push(subcamera);}const arrayCamera = new THREE.ArrayCamera(cameras);``` **CubeCamera** - Renders environment maps for reflections. ```javascriptconst cubeRenderTarget = new THREE.WebGLCubeRenderTarget(256);const cubeCamera = new THREE.CubeCamera(0.1, 1000, cubeRenderTarget);scene.add(cubeCamera); // Use for reflectionsmaterial.envMap = cubeRenderTarget.texture; // Update each frame (expensive!)cubeCamera.position.copy(reflectiveMesh.position);cubeCamera.update(renderer, scene);``` ### WebGLRenderer ```javascriptconst renderer = new THREE.WebGLRenderer({  canvas: document.querySelector("#canvas"), // Optional existing canvas  antialias: true, // Smooth edges  alpha: true, // Transparent background  powerPreference: "high-performance", // GPU hint  preserveDrawingBuffer: true, // For screenshots}); renderer.setSize(width, height);renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); // Tone mappingrenderer.toneMapping = THREE.ACESFilmicToneMapping;renderer.toneMappingExposure = 1.0; // Color space (Three.js r152+)renderer.outputColorSpace = THREE.SRGBColorSpace; // Shadowsrenderer.shadowMap.enabled = true;renderer.shadowMap.type = THREE.PCFSoftShadowMap; // Clear colorrenderer.setClearColor(0x000000, 1); // Renderrenderer.render(scene, camera);``` ### Object3D Base class for all 3D objects. Mesh, Group, Light, Camera all extend Object3D. ```javascriptconst obj = new THREE.Object3D(); // Transformobj.position.set(x, y, z);obj.rotation.set(x, y, z); // Euler angles (radians)obj.quaternion.set(x, y, z, w); // Quaternion rotationobj.scale.set(x, y, z); // Local vs World transformsobj.getWorldPosition(targetVector);obj.getWorldQuaternion(targetQuaternion);obj.getWorldDirection(targetVector); // Hierarchyobj.add(child);obj.remove(child);obj.parent;obj.children; // Visibilityobj.visible = false; // Layers (for selective rendering/raycasting)obj.layers.set(1);obj.layers.enable(2);obj.layers.disable(0); // Traverse hierarchyobj.traverse((child) => {  if (child.isMesh) child.material.color.set(0xff0000);}); // Matrix updatesobj.matrixAutoUpdate = true; // Default: auto-update matricesobj.updateMatrix(); // Manual matrix updateobj.updateMatrixWorld(true); // Update world matrix recursively``` ### Group Empty container for organizing objects. ```javascriptconst group = new THREE.Group();group.add(mesh1);group.add(mesh2);scene.add(group); // Transform entire groupgroup.position.x = 5;group.rotation.y = Math.PI / 4;``` ### Mesh Combines geometry and material. ```javascriptconst mesh = new THREE.Mesh(geometry, material); // Multiple materials (one per geometry group)const mesh = new THREE.Mesh(geometry, [material1, material2]); // Useful propertiesmesh.geometry;mesh.material;mesh.castShadow = true;mesh.receiveShadow = true; // Frustum cullingmesh.frustumCulled = true; // Default: skip if outside camera view // Render ordermesh.renderOrder = 10; // Higher = rendered later``` ## Coordinate System Three.js uses a **right-handed coordinate system**: - **+X** points right- **+Y** points up- **+Z** points toward viewer (out of screen) ```javascript// Axes helperconst axesHelper = new THREE.AxesHelper(5);scene.add(axesHelper); // Red=X, Green=Y, Blue=Z``` ## Math Utilities ### Vector3 ```javascriptconst v = new THREE.Vector3(x, y, z);v.set(x, y, z);v.copy(otherVector);v.clone(); // Operations (modify in place)v.add(v2);v.sub(v2);v.multiply(v2);v.multiplyScalar(2);v.divideScalar(2);v.normalize();v.negate();v.clamp(min, max);v.lerp(target, alpha); // Calculations (return new value)v.length();v.lengthSq(); // Faster than length()v.distanceTo(v2);v.dot(v2);v.cross(v2); // Modifies vv.angleTo(v2); // Transformv.applyMatrix4(matrix);v.applyQuaternion(q);v.project(camera); // World to NDCv.unproject(camera); // NDC to world``` ### Matrix4 ```javascriptconst m = new THREE.Matrix4();m.identity();m.copy(other);m.clone(); // Build transformsm.makeTranslation(x, y, z);m.makeRotationX(theta);m.makeRotationY(theta);m.makeRotationZ(theta);m.makeRotationFromQuaternion(q);m.makeScale(x, y, z); // Compose/decomposem.compose(position, quaternion, scale);m.decompose(position, quaternion, scale); // Operationsm.multiply(m2); // m = m * m2m.premultiply(m2); // m = m2 * mm.invert();m.transpose(); // Camera matricesm.makePerspective(left, right, top, bottom, near, far);m.makeOrthographic(left, right, top, bottom, near, far);m.lookAt(eye, target, up);``` ### Quaternion ```javascriptconst q = new THREE.Quaternion();q.setFromEuler(euler);q.setFromAxisAngle(axis, angle);q.setFromRotationMatrix(matrix); q.multiply(q2);q.slerp(target, t); // Spherical interpolationq.normalize();q.invert();``` ### Euler ```javascriptconst euler = new THREE.Euler(x, y, z, "XYZ"); // Order matters!euler.setFromQuaternion(q);euler.setFromRotationMatrix(m); // Rotation orders: 'XYZ', 'YXZ', 'ZXY', 'XZY', 'YZX', 'ZYX'``` ### Color ```javascriptconst color = new THREE.Color(0xff0000);const color = new THREE.Color("red");const color = new THREE.Color("rgb(255, 0, 0)");const color = new THREE.Color("#ff0000"); color.setHex(0x00ff00);color.setRGB(r, g, b); // 0-1 rangecolor.setHSL(h, s, l); // 0-1 range color.lerp(otherColor, alpha);color.multiply(otherColor);color.multiplyScalar(2);``` ### MathUtils ```javascriptTHREE.MathUtils.clamp(value, min, max);THREE.MathUtils.lerp(start, end, alpha);THREE.MathUtils.mapLinear(value, inMin, inMax, outMin, outMax);THREE.MathUtils.degToRad(degrees);THREE.MathUtils.radToDeg(radians);THREE.MathUtils.randFloat(min, max);THREE.MathUtils.randInt(min, max);THREE.MathUtils.smoothstep(x, min, max);THREE.MathUtils.smootherstep(x, min, max);``` ## Common Patterns ### Proper Cleanup ```javascriptfunction dispose() {  // Dispose geometries  mesh.geometry.dispose();   // Dispose materials  if (Array.isArray(mesh.material)) {    mesh.material.forEach((m) => m.dispose());  } else {    mesh.material.dispose();  }   // Dispose textures  texture.dispose();   // Remove from scene  scene.remove(mesh);   // Dispose renderer  renderer.dispose();}``` ### Clock for Animation ```javascriptconst clock = new THREE.Clock(); function animate() {  const delta = clock.getDelta(); // Time since last frame (seconds)  const elapsed = clock.getElapsedTime(); // Total time (seconds)   mesh.rotation.y += delta * 0.5; // Consistent speed regardless of framerate   requestAnimationFrame(animate);  renderer.render(scene, camera);}``` ### Responsive Canvas ```javascriptfunction onWindowResize() {  const width = window.innerWidth;  const height = window.innerHeight;   camera.aspect = width / height;  camera.updateProjectionMatrix();   renderer.setSize(width, height);  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));}window.addEventListener("resize", onWindowResize);``` ### Loading Manager ```javascriptconst manager = new THREE.LoadingManager(); manager.onStart = (url, loaded, total) => console.log("Started loading");manager.onLoad = () => console.log("All loaded");manager.onProgress = (url, loaded, total) => console.log(`${loaded}/${total}`);manager.onError = (url) => console.error(`Error loading ${url}`); const textureLoader = new THREE.TextureLoader(manager);const gltfLoader = new GLTFLoader(manager);``` ## Performance Tips 1. **Limit draw calls**: Merge geometries, use instancing, atlas textures2. **Frustum culling**: Enabled by default, ensure bounding boxes are correct3. **LOD (Level of Detail)**: Use `THREE.LOD` for distance-based mesh switching4. **Object pooling**: Reuse objects instead of creating/destroying5. **Avoid `getWorldPosition` in loops**: Cache results ```javascript// Merge static geometriesimport { mergeGeometries } from "three/examples/jsm/utils/BufferGeometryUtils.js";const merged = mergeGeometries([geo1, geo2, geo3]); // LODconst lod = new THREE.LOD();lod.addLevel(highDetailMesh, 0);lod.addLevel(medDetailMesh, 50);lod.addLevel(lowDetailMesh, 100);scene.add(lod);``` ## See Also - `threejs-geometry` - Geometry creation and manipulation- `threejs-materials` - Material types and properties- `threejs-lighting` - Light types and shadows