Skip to main content

threejs-fundamentals

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.

Source facts

Repository
Miaoge-Ge/coding-agent-skills
Last source activity
May 31, 2026 at 14:15
Detected SKILL.md language
English
Stars
7
Forks
2

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
threejs-fundamentals
description
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 ```javascript import * as THREE from "three"; // Create scene, camera, renderer const 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 mesh const 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 light scene.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 loop function animate() { requestAnimationFrame(animate); cube.rotation.x += 0.01; cube.rotation.y += 0.01; renderer.render(scene, camera); } animate(); // Handle resize window.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. ```javascript const scene = new THREE.Scene(); scene.background = new THREE.Color(0x000000); // Solid color scene.background = texture; // Skybox texture scene.background = cubeTexture; // Cubemap scene.environment = envMap; // Environment map for PBR scene.fog = new THREE.Fog(0xffffff, 1, 100); // Linear fog scene.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. ```javascript const 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. ```javascript const cubeRenderTarget = new THREE.WebGLCubeRenderTarget(256); const cubeCamera = new THREE.CubeCamera(0.1, 1000, cubeRenderTarget); scene.add(cubeCamera); // Use for reflections material.envMap = cubeRenderTarget.texture; // Update each frame (expensive!) cubeCamera.position.copy(reflectiveMesh.position); cubeCamera.update(renderer, scene); ``` ### WebGLRenderer ```javascript const 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 mapping renderer.toneMapping = THREE.ACESFilmicToneMapping; renderer.toneMappingExposure = 1.0; // Color space (Three.js r152+) renderer.outputColorSpace = THREE.SRGBColorSpace; // Shadows renderer.shadowMap.enabled = true; renderer.shadowMap.type = THREE.PCFSoftShadowMap; // Clear color renderer.setClearColor(0x000000, 1); // Render renderer.render(scene, camera); ``` ### Object3D Base class for all 3D objects. Mesh, Group, Light, Camera all extend Object3D. ```javascript const obj = new THREE.Object3D(); // Transform obj.position.set(x, y, z); obj.rotation.set(x, y, z); // Euler angles (radians) obj.quaternion.set(x, y, z, w); // Quaternion rotation obj.scale.set(x, y, z); // Local vs World transforms obj.getWorldPosition(targetVector); obj.getWorldQuaternion(targetQuaternion); obj.getWorldDirection(targetVector); // Hierarchy obj.add(child); obj.remove(child); obj.parent; obj.children; // Visibility obj.visible = false; // Layers (for selective rendering/raycasting) obj.layers.set(1); obj.layers.enable(2); obj.layers.disable(0); // Traverse hierarchy obj.traverse((child) => { if (child.isMesh) child.material.color.set(0xff0000); }); // Matrix updates obj.matrixAutoUpdate = true; // Default: auto-update matrices obj.updateMatrix(); // Manual matrix update obj.updateMatrixWorld(true); // Update world matrix recursively ``` ### Group Empty container for organizing objects. ```javascript const group = new THREE.Group(); group.add(mesh1); group.add(mesh2); scene.add(group); // Transform entire group group.position.x = 5; group.rotation.y = Math.PI / 4; ``` ### Mesh Combines geometry and material. ```javascript const mesh = new THREE.Mesh(geometry, material); // Multiple materials (one per geometry group) const mesh = new THREE.Mesh(geometry, [material1, material2]); // Useful properties mesh.geometry; mesh.material; mesh.castShadow = true; mesh.receiveShadow = true; // Frustum culling mesh.frustumCulled = true; // Default: skip if outside camera view // Render order mesh.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 helper const axesHelper = new THREE.AxesHelper(5); scene.add(axesHelper); // Red=X, Green=Y, Blue=Z ``` ## Math Utilities ### Vector3 ```javascript const 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 v v.angleTo(v2); // Transform v.applyMatrix4(matrix); v.applyQuaternion(q); v.project(camera); // World to NDC v.unproject(camera); // NDC to world ``` ### Matrix4 ```javascript const m = new THREE.Matrix4(); m.identity(); m.copy(other); m.clone(); // Build transforms m.makeTranslation(x, y, z); m.makeRotationX(theta); m.makeRotationY(theta); m.makeRotationZ(theta); m.makeRotationFromQuaternion(q); m.makeScale(x, y, z); // Compose/decompose m.compose(position, quaternion, scale); m.decompose(position, quaternion, scale); // Operations m.multiply(m2); // m = m * m2 m.premultiply(m2); // m = m2 * m m.invert(); m.transpose(); // Camera matrices m.makePerspective(left, right, top, bottom, near, far); m.makeOrthographic(left, right, top, bottom, near, far); m.lookAt(eye, target, up); ``` ### Quaternion ```javascript const q = new THREE.Quaternion(); q.setFromEuler(euler); q.setFromAxisAngle(axis, angle); q.setFromRotationMatrix(matrix); q.multiply(q2); q.slerp(target, t); // Spherical interpolation q.normalize(); q.invert(); ``` ### Euler ```javascript const 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 ```javascript const 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 range color.setHSL(h, s, l); // 0-1 range color.lerp(otherColor, alpha); color.multiply(otherColor); color.multiplyScalar(2); ``` ### MathUtils ```javascript THREE.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 ```javascript function 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 ```javascript const 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 ```javascript function 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); ```
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub