Files
2nd/10_Wiki/Topics/Architecture/InstancedMesh.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

199 lines
6.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: wiki-2026-0508-instancedmesh
title: InstancedMesh
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [InstancedMesh, GPU Instancing, three.js InstancedMesh]
duplicate_of: none
source_trust_level: A
confidence_score: 0.95
verification_status: applied
tags: [threejs, webgl, gpu-instancing, rendering, performance]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: JavaScript/TypeScript
framework: three.js
---
# InstancedMesh
## 매 한 줄
> **"매 thousands of meshes 매 single draw call"**. `THREE.InstancedMesh` 매 same-geometry+material 매 N copies 매 GPU instancing 매 single draw — 매 forest, crowd, particle, voxel 의 standard pattern. 2026 매 r170+ 매 BatchedMesh (multi-geometry instancing) 매 추가됨.
## 매 핵심
### 매 InstancedMesh vs alternatives
- **Mesh × N**: 매 N draw calls. 매 simple, 매 slow at >100.
- **InstancedMesh**: 매 1 draw call, 매 same geom/material, 매 per-instance matrix + color.
- **BatchedMesh** (r150+): 매 1 draw call, 매 different geom 가능, 매 same material.
- **Custom shader InstancedBufferGeometry**: 매 full control, 매 boilerplate.
### 매 Per-instance attributes
- **`setMatrixAt(i, matrix)`** — 매 position/rotation/scale.
- **`setColorAt(i, color)`** — 매 per-instance tint (requires instanceColor).
- **Custom `InstancedBufferAttribute`** — 매 임의 per-instance data (HP, age, type).
### 매 응용
1. **Forest/foliage**: 10k 매 trees 매 60fps.
2. **Crowd simulation**: 매 NPCs 매 unique pose 매 transform.
3. **Voxel terrain**: 매 cube instance 매 chunk.
4. **Particle system**: 매 GPU-driven particle.
5. **Bullet patterns**: 매 bullet hell 매 thousands of bullets.
## 💻 패턴
### Basic InstancedMesh
```javascript
import * as THREE from 'three';
const count = 10000;
const geom = new THREE.BoxGeometry(1, 1, 1);
const mat = new THREE.MeshStandardMaterial({ color: 0x44aa88 });
const mesh = new THREE.InstancedMesh(geom, mat, count);
const m = new THREE.Matrix4();
for (let i = 0; i < count; i++) {
m.setPosition(
(Math.random() - 0.5) * 100,
(Math.random() - 0.5) * 100,
(Math.random() - 0.5) * 100
);
mesh.setMatrixAt(i, m);
}
mesh.instanceMatrix.needsUpdate = true;
scene.add(mesh);
```
### Per-instance color
```javascript
mesh.instanceColor = new THREE.InstancedBufferAttribute(
new Float32Array(count * 3), 3
);
const c = new THREE.Color();
for (let i = 0; i < count; i++) {
c.setHSL(i / count, 0.7, 0.5);
mesh.setColorAt(i, c);
}
mesh.instanceColor.needsUpdate = true;
```
### Dynamic update (animated swarm)
```javascript
const dummy = new THREE.Object3D();
function tick(time) {
for (let i = 0; i < count; i++) {
dummy.position.set(
Math.sin(time + i) * 10,
Math.cos(time * 0.5 + i * 0.3) * 5,
Math.sin(time * 0.3 + i) * 10
);
dummy.rotation.y = time + i;
dummy.updateMatrix();
mesh.setMatrixAt(i, dummy.matrix);
}
mesh.instanceMatrix.needsUpdate = true;
}
```
### Custom per-instance attribute (shader)
```javascript
const hpAttr = new THREE.InstancedBufferAttribute(new Float32Array(count), 1);
geom.setAttribute('aHp', hpAttr);
mat.onBeforeCompile = (shader) => {
shader.vertexShader = shader.vertexShader
.replace('#include <common>', `
#include <common>
attribute float aHp;
varying float vHp;
`)
.replace('#include <begin_vertex>', `
#include <begin_vertex>
vHp = aHp;
`);
shader.fragmentShader = shader.fragmentShader
.replace('#include <common>', `
#include <common>
varying float vHp;
`)
.replace('#include <dithering_fragment>', `
gl_FragColor.rgb = mix(vec3(1,0,0), gl_FragColor.rgb, vHp);
#include <dithering_fragment>
`);
};
```
### Frustum culling per instance (CPU side)
```javascript
const frustum = new THREE.Frustum().setFromProjectionMatrix(
new THREE.Matrix4().multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse)
);
let visible = 0;
for (let i = 0; i < total; i++) {
if (frustum.containsPoint(positions[i])) {
visibleMesh.setMatrixAt(visible++, matrices[i]);
}
}
visibleMesh.count = visible;
visibleMesh.instanceMatrix.needsUpdate = true;
```
### BatchedMesh (r150+, multi-geometry)
```javascript
const batch = new THREE.BatchedMesh(maxInstances, maxVerts, maxIndices, mat);
const treeId = batch.addGeometry(treeGeom);
const rockId = batch.addGeometry(rockGeom);
for (let i = 0; i < 5000; i++) batch.addInstance(i % 2 === 0 ? treeId : rockId);
```
### Raycasting against InstancedMesh
```javascript
const raycaster = new THREE.Raycaster();
raycaster.setFromCamera(mouse, camera);
const hits = raycaster.intersectObject(mesh);
if (hits.length) {
const i = hits[0].instanceId;
console.log('Hit instance', i);
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 same geom/material × N (>100) | InstancedMesh |
| 매 different geom × N | BatchedMesh (r150+) |
| 매 fully GPU-driven (compute-style) | InstancedBufferGeometry + WebGPU |
| 매 N < 50 | regular Mesh OK |
| 매 LOD per instance | InstancedMesh × LOD level + custom culling |
**기본값**: 매 N ≥ 100 → InstancedMesh.
## 🔗 Graph
- 부모: [[three.js]] · [[GPU-Instancing]]
- 변형: [[BatchedMesh]]
- 응용: [[Crowd-Simulation]]
- Adjacent: [[WebGPU]] · [[Frustum Culling]] · [[LOD]]
## 🤖 LLM 활용
**언제**: 매 three.js 매 thousands of repeated objects; 매 WebGL 매 draw call optimization.
**언제 X**: 매 단일 unique mesh; 매 Unity (different API); 매 native C++ engine (use API-specific instancing).
## ❌ 안티패턴
- **Per-frame full rebuild**: 매 모든 matrix 매 update — 매 변하지 않는 instance 매 skip.
- **Forgetting `needsUpdate`**: 매 setMatrixAt 후 매 GPU 매 stale.
- **InstancedMesh × different materials**: 매 불가능 — BatchedMesh or 분리.
- **Raycast against 100k instances every frame**: 매 BVH (three-mesh-bvh) 사용.
## 🧪 검증 / 중복
- Verified (three.js docs r170, official examples webgl_instancing_*, BatchedMesh PR #25556).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — full content (instancing patterns + BatchedMesh) |