threejs-skills
Build 3D graphics and interactive visual experiences using Three.js.
Install
mkdir -p .claude/skills/threejs-skills && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/833" && unzip -o skill.zip -d .claude/skills/threejs-skills && rm skill.zipInstalls to .claude/skills/threejs-skills
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Create 3D scenes, interactive experiences, and visual effects using Three.js. Use when user requests 3D graphics, WebGL experiences, 3D visualizations, animations, or interactive 3D elements.Key capabilities
- →Initialize a Three.js scene with camera and renderer
- →Create 3D objects using basic geometries like BoxGeometry or SphereGeometry
- →Apply materials such as MeshBasicMaterial or MeshStandardMaterial
- →Add lighting to a scene with AmbientLight or DirectionalLight
- →Implement animation loops for continuous rendering
- →Handle window resizing for responsive 3D experiences
How it works
The skill sets up core Three.js components including scene, camera, and renderer, then defines objects, materials, and lighting, concluding with an animation loop and responsiveness handling.
Inputs & outputs
When to use threejs-skills
- →Create a 3D rotating object
- →Initialize a WebGL scene
- →Add 3D model interaction to a webpage
- →Create particle system visual effects
About this skill
Three.js Skills
Systematically create high-quality 3D scenes and interactive experiences using Three.js best practices.
When to Use
- Requests 3D visualizations or graphics ("create a 3D model", "show in 3D")
- Wants interactive 3D experiences ("rotating cube", "explorable scene")
- Needs WebGL or canvas-based rendering
- Asks for animations, particles, or visual effects
- Mentions Three.js, WebGL, or 3D rendering
- Wants to visualize data in 3D space
Core Setup Pattern
1. Essential Three.js Imports
Use ES module import maps for modern Three.js (r183+):
<script type="importmap">
{
"imports": {
"three": "https://cdn.jsdelivr.net/npm/[email protected]/build/three.module.js",
"three/addons/": "https://cdn.jsdelivr.net/npm/[email protected]/examples/jsm/"
}
}
</script>
<script type="module">
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
</script>
For production with npm/vite/webpack:
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
2. Scene Initialization
Every Three.js artifact needs these core components:
// Scene - contains all 3D objects
const scene = new THREE.Scene();
// Camera - defines viewing perspective
const camera = new THREE.PerspectiveCamera(
75, // Field of view
window.innerWidth / window.innerHeight, // Aspect ratio
0.1, // Near clipping plane
1000, // Far clipping plane
);
camera.position.z = 5;
// Renderer - draws the scene
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
3. Animation Loop
Use renderer.setAnimationLoop() (preferred) or requestAnimationFrame:
// Preferred: setAnimationLoop (handles WebXR compatibility)
renderer.setAnimationLoop(() => {
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.01;
renderer.render(scene, camera);
});
// Alternative: manual requestAnimationFrame
function animate() {
requestAnimationFrame(animate);
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.01;
renderer.render(scene, camera);
}
animate();
Systematic Development Process
1. Define the Scene
Start by identifying:
- What objects need to be rendered
- Camera position and field of view
- Lighting setup required
- Interaction model (static, rotating, user-controlled)
2. Build Geometry
Choose appropriate geometry types:
Basic Shapes:
BoxGeometry- cubes, rectangular prismsSphereGeometry- spheres, planetsCylinderGeometry- cylinders, tubesPlaneGeometry- flat surfaces, ground planesTorusGeometry- donuts, rings
CapsuleGeometry is available (stable since r142):
new THREE.CapsuleGeometry(0.5, 1, 4, 8); // radius, length, capSegments, radialSegments
3. Apply Materials
Choose materials based on visual needs:
Common Materials:
MeshBasicMaterial- unlit, flat colors (no lighting needed)MeshStandardMaterial- physically-based, realistic (needs lighting)MeshPhongMaterial- shiny surfaces with specular highlightsMeshLambertMaterial- matte surfaces, diffuse reflection
const material = new THREE.MeshStandardMaterial({
color: 0x00ff00,
metalness: 0.5,
roughness: 0.5,
});
4. Add Lighting
If using lit materials (Standard, Phong, Lambert), add lights:
// Ambient light - general illumination
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);
// Directional light - like sunlight
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
directionalLight.position.set(5, 5, 5);
scene.add(directionalLight);
Skip lighting if using MeshBasicMaterial - it's unlit by design.
5. Handle Responsiveness
Always add window resize handling:
window.addEventListener("resize", () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
Common Patterns
Rotating Object
function animate() {
requestAnimationFrame(animate);
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.01;
renderer.render(scene, camera);
}
OrbitControls
With import maps or build tools, OrbitControls works directly:
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
// Update in animation loop
renderer.setAnimationLoop(() => {
controls.update();
renderer.render(scene, camera);
});
Custom Camera Controls (Alternative)
For lightweight custom controls without importing OrbitControls:
let isDragging = false;
let previousMousePosition = { x: 0, y: 0 };
renderer.domElement.addEventListener("mousedown", () => {
isDragging = true;
});
renderer.domElement.addEventListener("mouseup", () => {
isDragging = false;
});
renderer.domElement.addEventListener("mousemove", (event) => {
if (isDragging) {
const deltaX = event.clientX - previousMousePosition.x;
const deltaY = event.clientY - previousMousePosition.y;
// Rotate camera around scene
const rotationSpeed = 0.005;
camera.position.x += deltaX * rotationSpeed;
camera.position.y -= deltaY * rotationSpeed;
camera.lookAt(scene.position);
}
previousMousePosition = { x: event.clientX, y: event.clientY };
});
// Zoom with mouse wheel
renderer.domElement.addEventListener("wheel", (event) => {
event.preventDefault();
camera.position.z += event.deltaY * 0.01;
camera.position.z = Math.max(2, Math.min(20, camera.position.z)); // Clamp
});
Raycasting for Object Selection
Detect mouse clicks and hovers on 3D objects:
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
const clickableObjects = []; // Array of meshes that can be clicked
// Update mouse position
window.addEventListener("mousemove", (event) => {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
});
// Detect clicks
window.addEventListener("click", () => {
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObjects(clickableObjects);
if (intersects.length > 0) {
const clickedObject = intersects[0].object;
// Handle click - change color, scale, etc.
clickedObject.material.color.set(0xff0000);
}
});
// Hover effect in animation loop
function animate() {
requestAnimationFrame(animate);
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObjects(clickableObjects);
// Reset all objects
clickableObjects.forEach((obj) => {
obj.scale.set(1, 1, 1);
});
// Highlight hovered object
if (intersects.length > 0) {
intersects[0].object.scale.set(1.2, 1.2, 1.2);
document.body.style.cursor = "pointer";
} else {
document.body.style.cursor = "default";
}
renderer.render(scene, camera);
}
Particle System
const particlesGeometry = new THREE.BufferGeometry();
const particlesCount = 1000;
const posArray = new Float32Array(particlesCount * 3);
for (let i = 0; i < particlesCount * 3; i++) {
posArray[i] = (Math.random() - 0.5) * 10;
}
particlesGeometry.setAttribute(
"position",
new THREE.BufferAttribute(posArray, 3),
);
const particlesMaterial = new THREE.PointsMaterial({
size: 0.02,
color: 0xffffff,
});
const particlesMesh = new THREE.Points(particlesGeometry, particlesMaterial);
scene.add(particlesMesh);
User Interaction (Mouse Movement)
let mouseX = 0;
let mouseY = 0;
document.addEventListener("mousemove", (event) => {
mouseX = (event.clientX / window.innerWidth) * 2 - 1;
mouseY = -(event.clientY / window.innerHeight) * 2 + 1;
});
function animate() {
requestAnimationFrame(animate);
camera.position.x = mouseX * 2;
camera.position.y = mouseY * 2;
camera.lookAt(scene.position);
renderer.render(scene, camera);
}
Loading Textures
const textureLoader = new THREE.TextureLoader();
const texture = textureLoader.load("texture-url.jpg");
const material = new THREE.MeshStandardMaterial({
map: texture,
});
Best Practices
Performance
- Reuse geometries and materials when creating multiple similar objects
- Use
BufferGeometryfor custom shapes (more efficient) - Limit particle counts to maintain 60fps (start with 1000-5000)
- Dispose of resources when removing objects:
geometry.dispose(); material.dispose(); texture.dispose();
Visual Quality
- Always set
antialias: trueon renderer for smooth edges - Use appropriate camera FOV (45-75 degrees typical)
- Position lights thoughtfully - avoid overlapping multiple bright lights
- Add ambient + directional lighting for realistic scenes
Code Organization
- Initialize scene, camera, renderer at the top
- Group related objects (e.g., all particles in one group)
- Keep animation logic in the animate function
- Separate object creation into functions for complex scenes
Common Pitfalls to Avoid
- ❌ Using
outputEncodinginstead ofoutputColorSpace(renamed in r152) - ❌ Forgetting to add objects to scene with
scene.add() - ❌ Using lit materials without adding lights
- ❌ Not handling window resize
- ❌ Forgetting to call
renderer.render()in animation loop - ❌ Using
THREE.Clockwithout consideringTHREE.Timer(recommended in r183)
Example Workflow
User: "Create an interactive 3D sphere that responds to mouse movement"
- Setup: Import Three.js, create scene/camera/renderer
- Geometry: Create
SphereGeometry(1, 32, 32)for smooth sphere - Material: Use
MeshStandardMaterialfor realistic look - Lighting: A
Content truncated.
How it compares
This skill provides a systematic development process for Three.js, guiding through scene definition, geometry, materials, and lighting, which differs from ad-hoc 3D web graphics.
Compared to similar skills
threejs-skills side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| threejs-skills (this skill) | 61 | 4mo | No flags | Intermediate |
| 3d-graphics | 33 | 6mo | No flags | Advanced |
| threejs-shaders | 4 | 6mo | No flags | Advanced |
| gsap | 3 | 8mo | Review | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by sickn33
View all by sickn33 →You might also like
3d-graphics
samhvw8
3D web graphics with Three.js (WebGL/WebGPU). Capabilities: scenes, cameras, geometries, materials, lights, animations, model loading (GLTF/FBX), PBR materials, shadows, post-processing (bloom, SSAO, SSR), custom shaders, instancing, LOD, physics, VR/XR. Actions: create, build, animate, render 3D scenes/models. Keywords: Three.js, WebGL, WebGPU, 3D graphics, scene, camera, geometry, material, light, animation, GLTF, FBX, OrbitControls, PBR, shadow mapping, post-processing, bloom, SSAO, shader, instancing, LOD, WebXR, VR, AR, product configurator, data visualization, architectural walkthrough, interactive 3D, canvas. Use when: creating 3D visualizations, building WebGL/WebGPU apps, loading 3D models, adding animations, implementing VR/XR, creating interactive graphics, building product configurators.
threejs-shaders
CloudAI-X
Three.js shaders - GLSL, ShaderMaterial, uniforms, custom effects. Use when creating custom visual effects, modifying vertices, writing fragment shaders, or extending built-in materials.
gsap
martinholovsky
GSAP animations for JARVIS HUD transitions and effects
threejs-animation
CloudAI-X
Three.js animation - keyframe animation, skeletal animation, morph targets, animation mixing. Use when animating objects, playing GLTF animations, creating procedural motion, or blending animations.
threejs-lighting
CloudAI-X
Three.js lighting - light types, shadows, environment lighting. Use when adding lights, configuring shadows, setting up IBL, or optimizing lighting performance.
threejs-interaction
CloudAI-X
Three.js interaction - raycasting, controls, mouse/touch input, object selection. Use when handling user input, implementing click detection, adding camera controls, or creating interactive 3D experiences.