Threejs Fundamentals

calesthio/OpenMontage/.agents/skills/threejs-fundamentals

作者 calesthio9327439db69021ab4b0e2776729bf3b58fdb5a87無授權條款65K 個星標收錄於 2026年10月9日更新於 2026年10月9日儲存庫5 天前更新

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.

AI 產生的概覽

Three.js 場景設定、相機、渲染器、Object3D 階層與座標系統的參考指南。

功能
這個技能是一份 Three.js 基礎知識的教學參考。內容記錄了場景、相機與渲染器的設定,Object3D 階層與變換,右手座標系統,Vector3、Matrix4、Quaternion、Euler、Color 等數學工具,以及清理、動畫時鐘、響應式畫布和載入管理器等常見模式。它也列出效能最佳化建議,並指向幾何體、材質與光照等相關技能。
適用情境
適用於設定 3D 場景、建立相機、設定渲染器、管理物件階層或在 Three.js 中處理變換的情況。適合需要快速查閱 Three.js 核心類別與常用模式的開發者。
執行需求
不包含指令碼,僅為說明文件。程式碼範例假定專案中已安裝 three 套件,部分範例還引用了 GLTFLoader、BufferGeometryUtils 等選用附加模組。

Three.js Fundamentals

Quick Start

javascript
import * 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.

javascript
const 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.

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 reflectionsmaterial.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 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.

javascript
const 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.

javascript
const 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.

javascript
const 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

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 vv.angleTo(v2);
// Transformv.applyMatrix4(matrix);v.applyQuaternion(q);v.project(camera); // World to NDCv.unproject(camera); // NDC to world

Matrix4

javascript
const 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

javascript
const 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

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 rangecolor.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);

Loading Manager

javascript
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

  1. Limit draw calls: Merge geometries, use instancing, atlas textures
  2. Frustum culling: Enabled by default, ensure bounding boxes are correct
  3. LOD (Level of Detail): Use THREE.LOD for distance-based mesh switching
  4. Object pooling: Reuse objects instead of creating/destroying
  5. 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

來源與署名

來源:calesthio/OpenMontage位於.agents/skills/threejs-fundamentals提交9327439

授權條款: 無授權條款

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架