Files
2nd/10_Wiki/Topics/Architecture/Threejs.md
T
koriweb d8a80f6272 chore(wiki): dangling 링크 canonical 정규화 (768파일/1200건)
이름만 다른(표기 변형) [[위키링크]]를 대상 문서의 canonical 제목으로 치환해
끊겼던 1,200개 링크를 연결. 제목/파일명 정규화 일치만 적용하고 별칭 매칭은
과병합 위험으로 제외(애매성 가드). 원본은 _link_reconcile_backup/ 에 백업.
도구: Datacollect/scripts/link_reconcile_apply.mjs

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 12:24:15 +09:00

6.4 KiB

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

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+)

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

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

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

Postprocessing

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)

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)

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)

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

🤖 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