---
id: wiki-2026-0508-threejs
title: Three.js
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Three.js, three, 3D web, WebGL library]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [3d, webgl, webgpu, graphics, threejs]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
  language: typescript
  framework: three.js-r170
---

# Three.js

## 매 한 줄
> **"매 web 의 de-facto 3D library — WebGL/WebGPU 의 high-level wrapper"**. 매 scene graph + materials + lights + cameras + loaders. 2026 r170+ — WebGPURenderer stable, TSL (Three Shading Language), node-based materials. React 통합은 `@react-three/fiber`.

## 매 핵심

### 매 core entities
- **Scene**: 매 graph root.
- **Camera**: Perspective / Orthographic.
- **Renderer**: WebGLRenderer / WebGPURenderer.
- **Mesh** = Geometry + Material.
- **Light**: Ambient / Directional / Point / Spot.

### 매 render loop
- `requestAnimationFrame` → update → renderer.render(scene, camera).
- 매 r3f 는 자동 loop.

### 매 응용
1. Product configurator (3D customization).
2. Data visualization (graph, scatter).
3. WebXR (VR/AR).
4. Game / interactive art.

## 💻 패턴

### Vanilla minimal
```typescript
import * as THREE from 'three';

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
  75, window.innerWidth / window.innerHeight, 0.1, 1000,
);
camera.position.z = 5;

const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);

const geo = new THREE.BoxGeometry(1, 1, 1);
const mat = new THREE.MeshStandardMaterial({ color: 0x6699ff });
const cube = new THREE.Mesh(geo, mat);
scene.add(cube);

scene.add(new THREE.AmbientLight(0xffffff, 0.4));
const dir = new THREE.DirectionalLight(0xffffff, 1);
dir.position.set(5, 5, 5);
scene.add(dir);

renderer.setAnimationLoop(() => {
  cube.rotation.x += 0.01;
  cube.rotation.y += 0.01;
  renderer.render(scene, camera);
});
```

### WebGPU renderer (r170+)
```typescript
import * as THREE from 'three/webgpu';
import { color, normalLocal } from 'three/tsl';

const renderer = new THREE.WebGPURenderer({ antialias: true });
await renderer.init();

const mat = new THREE.MeshBasicNodeMaterial();
mat.colorNode = color('#6699ff').mul(normalLocal.length());
```

### React Three Fiber
```tsx
import { Canvas, useFrame } from '@react-three/fiber';
import { OrbitControls, Environment } from '@react-three/drei';
import { useRef } from 'react';
import type { Mesh } from 'three';

function Box() {
  const ref = useRef<Mesh>(null);
  useFrame((_, dt) => {
    if (ref.current) ref.current.rotation.y += dt;
  });
  return (
    <mesh ref={ref}>
      <boxGeometry args={[1, 1, 1]} />
      <meshStandardMaterial color="#6699ff" />
    </mesh>
  );
}

export default function App() {
  return (
    <Canvas camera={{ position: [3, 3, 3] }}>
      <Environment preset="city" />
      <Box />
      <OrbitControls />
    </Canvas>
  );
}
```

### GLTF model loading
```typescript
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';

const draco = new DRACOLoader();
draco.setDecoderPath('https://www.gstatic.com/draco/v1/decoders/');

const loader = new GLTFLoader();
loader.setDRACOLoader(draco);

const gltf = await loader.loadAsync('/model.glb');
scene.add(gltf.scene);
```

```tsx
// r3f
import { useGLTF } from '@react-three/drei';
function Model() {
  const { scene } = useGLTF('/model.glb');
  return <primitive object={scene} />;
}
```

### Postprocessing
```typescript
import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js';
import { RenderPass } from 'three/addons/postprocessing/RenderPass.js';
import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js';

const composer = new EffectComposer(renderer);
composer.addPass(new RenderPass(scene, camera));
composer.addPass(new UnrealBloomPass(
  new THREE.Vector2(window.innerWidth, window.innerHeight),
  0.8, 0.4, 0.85,
));

renderer.setAnimationLoop(() => composer.render());
```

### Instanced rendering (10k+ objects)
```typescript
const count = 10_000;
const mesh = new THREE.InstancedMesh(geo, mat, count);
const dummy = new THREE.Object3D();
for (let i = 0; i < count; i++) {
  dummy.position.set(
    (Math.random() - 0.5) * 100,
    (Math.random() - 0.5) * 100,
    (Math.random() - 0.5) * 100,
  );
  dummy.updateMatrix();
  mesh.setMatrixAt(i, dummy.matrix);
}
scene.add(mesh);
```

### Disposal (memory)
```typescript
function dispose(obj: THREE.Object3D) {
  obj.traverse((child) => {
    if ((child as THREE.Mesh).isMesh) {
      const m = child as THREE.Mesh;
      m.geometry.dispose();
      const mats = Array.isArray(m.material) ? m.material : [m.material];
      mats.forEach((mat) => mat.dispose());
    }
  });
}
```

### WebXR (VR)
```typescript
renderer.xr.enabled = true;
import { VRButton } from 'three/addons/webxr/VRButton.js';
document.body.appendChild(VRButton.createButton(renderer));
```

## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 React app | `@react-three/fiber` + drei |
| 매 vanilla / lib | three.js direct |
| 매 GPU compute / advanced shader | WebGPURenderer + TSL |
| 매 game | Babylon.js / PlayCanvas (more game-oriented) |
| 매 declarative UI integration | r3f (preferred) |

**기본값**: 매 React → r3f + drei. 매 그 외 → three.js + addons.

## 🔗 Graph
- 부모: [[3D_Web]] · [[WebGL]]
- 변형: [[Babylon_js]]
- 응용: [[React_Three_Fiber]] · [[drei]] · [[WebXR]]
- Adjacent: [[Shader]] · [[WebGPU]]

## 🤖 LLM 활용
**언제**: 매 scene scaffold, 매 shader translate, 매 r3f component generation.
**언제 X**: 매 production shader optimization — 매 hand-tune 필요.

## ❌ 안티패턴
- **Forgetting dispose**: 매 GPU memory leak.
- **`new THREE.X` in render loop**: 매 GC pressure.
- **No `setPixelRatio`**: 매 retina blurry.
- **Many individual meshes**: 매 instancing 의 사용.
- **Direct DOM rerender on every frame**: 매 r3f 의 자동 loop 무시.

## 🧪 검증 / 중복
- Verified (three.js r170 docs, react-three/fiber docs, mrdoob, 2026).
- 신뢰도 A.

## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Three.js r170 with WebGPU, TSL, r3f, instancing |
