threejs-fundamentals
Skill3 starsChanged 11 days agoMITView on GitHub
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.
20 other projects use a version of this, 4 of them edited.
Adopted by
Steady: 0 new projects took it in the last 4 weeks, none the 4 weeks before.thin data
Most recently taken up by
- DaraBoth/skilljmskilltheir own version, first seen Nov 8, 2026
- OpenMontageInc/OpenMontageword for word, first seen Nov 8, 2026
- calesthio/OpenMontageword for word, first seen Nov 8, 2026
- davidanthonyn/claude-skillsword for word, first seen Oct 20, 2026
- CloudAI-X/threejs-skillstheir own version, first seen Oct 18, 2026
- pengawasmknan/claude-skillsword for word, first seen Oct 11, 2026
Used with
Projects with it also use pose-library-design, video-toolkit and 10 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
LinHao-citySkillpose-library-design
Design reusable 2D character pose libraries, action cycles, and expression states for data-driven animation.
Also in 4 projects that use this
LinHao-citySkillvideo-toolkit
Create professional videos autonomously using claude-code-video-toolkit — AI voiceovers, image generation, music, talking heads, and Remotion rendering.
Also in 4 projects that use this
GopyrSkillazure-speech-to-text
Also in 3 projects that use this
GopyrSkilldashscope
Also in 3 projects that use this
jaron-goh-centrSkillwebsite-to-video
Capture a general website/URL and turn it into a video OF the site — tour, showcase, or social clip built from captured screenshots and the site's own brand assets. Use for portfolio / blog / docs / landing-page showcases. Not a product launch or promo, even from a URL (/product-launch-video). Unclear → /hyperframes.
Also in 5 projects that use this
dAAAbSkillheygen
Also in 4 projects that use this
- +5 more from LinHao-city
Other versions20 projects use a version of this.
Word for word · 14
- calesthio/OpenMontage★ 78k100% same
- OpenMontageInc/OpenMontage★ 78k100% same
- educlopez/thegridcn-ui★ 394100% same
- quiet-node/gesture-lab★ 185100% same
- codetesla51/skills★ 32100% same
- ruloCode/hermes-os★ 16100% same
- LinHao-city/StoryMind★ 10100% same
- huangzida/skills★ 2100% same
- sumulige/sumulige-claude★ 2100% same
- patrickcohen/claude-skills-collection★ 1100% same
4 more not listed
Edited · 4
- kumaran-is/claude-code-onboarding★ 3598% same
- Adhamxon/claude-code-skills★ 285% same
- ai4brands-design/claude-skills★ 238% same
- Gopyr/gopyr-skills-hub★ 052% same
Wrote their own version · 2
- CloudAI-X/threejs-skills★ 3.7ksame name
- DaraBoth/skilljmskill★ 2same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository72 other files it gives its agents.
- workflow/AGENTS.mdAGENTS.md
- docs/llms.txtllms.txt
- llms.txtllms.txt
- ai-video-prompt-engineerSkill
- api-contract-designSkill
- api-hardeningSkill
- brainstormingSkill
- cavecrewSkill
- caveman-commitSkill
- caveman-compressSkill
- caveman-helpSkill
- caveman-reviewSkill
- cavemanSkill
- councilSkill
- database-migrationsSkill
- deep-researchSkill
- dependency-auditSkill
- deployment-patternsSkill
- e2e-testingSkill
- error-handlingSkill
- exa-searchSkill
- finishing-a-development-branchSkill
- frontend-securitySkill
- github-opsSkill
- graphifySkill
- graphyloop-wavesSkill
- graphyloop-workflowSkill
- gsap-coreSkill
- gsap-frameworksSkill
- gsap-performanceSkill
- gsap-pluginsSkill
- gsap-reactSkill
- gsap-scrolltriggerSkill
- gsap-timelineSkill
- gsap-utilsSkill
- high-end-visual-designSkill
- image-to-codeSkill
- last30daysSkill
- minimalist-uiSkill
- postgres-patternsSkill
- prisma-patternsSkill
- receiving-code-reviewSkill
- redesign-existing-projectsSkill
- remotion-video-creationSkill
- requesting-code-reviewSkill
- search-firstSkill
- secrets-hygieneSkill
- security-reviewSkill
- security-scanSkill
- short-video-productionSkill
- story-engineeringSkill
- supabase-setupSkill
- swarm-memorySkill
- systematic-debuggingSkill
- tdd-workflowSkill
- terminal-opsSkill
- threejs-animationSkill
- threejs-geometrySkill
- threejs-interactionSkill
- threejs-lightingSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
2 rules. 1 is common, 0 are distinctive, and 1 is very specific to this project.
1
Common
Most of the 3 edited versions we read keep these.
0
Distinctive
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Common: line 92
OrthographicCamera: - No perspective distortion, good for 2D/isometric.
- Very specific: line 467
LOD (Level of Detail): Use THREE.LOD for distance-based mesh switching
“Common” is measured: kept by at least 6 in 10 of the 3 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Three.js Fundamentals
Quick Start
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.
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 fogCameras
PerspectiveCamera - Most common, simulates human eye.
// 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, farOrthographicCamera - No perspective distortion, good for 2D/isometric.
// 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.
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.
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
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.
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 recursivelyGroup
Empty container for organizing objects.
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.
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 laterCoordinate System
Three.js uses a right-handed coordinate system:
- +X points right
- +Y points up
- +Z points toward viewer (out of screen)
// Axes helper
const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper); // Red=X, Green=Y, Blue=ZMath Utilities
Vector3
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 worldMatrix4
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
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
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
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
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
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
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
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);Loading Manager
const 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
- Limit draw calls: Merge geometries, use instancing, atlas textures
- Frustum culling: Enabled by default, ensure bounding boxes are correct
- LOD (Level of Detail): Use
THREE.LODfor distance-based mesh switching - Object pooling: Reuse objects instead of creating/destroying
- Avoid
getWorldPositionin loops: Cache results
// Merge static geometries
import { mergeGeometries } from "three/examples/jsm/utils/BufferGeometryUtils.js";
const merged = mergeGeometries([geo1, geo2, geo3]);
// LOD
const 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 manipulationthreejs-materials- Material types and propertiesthreejs-lighting- Light types and shadows
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

