threejs-fundamentals

Three.js Fundamentals

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "threejs-fundamentals" with this command: npx skills add toilahuongg/shopify-agents-kit/toilahuongg-shopify-agents-kit-threejs-fundamentals

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 fog

Cameras

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, far

OrthographicCamera - 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 recursively

Group

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 later

Coordinate 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=Z

Math 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 world

Matrix4

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.LOD for distance-based mesh switching

  • Object pooling: Reuse objects instead of creating/destroying

  • Avoid getWorldPosition in 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 manipulation

  • threejs-materials

  • Material types and properties

  • threejs-lighting

  • Light types and shadows

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

shopify-api

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

shopify-extensions

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

shopify-functions

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

shopify-metafields

No summary provided by upstream source.

Repository SourceNeeds Review