# [[Three.js 렌더링 성능 최적화]]

## 📌 Brief Summary
Three.js 렌더링 성능 최적화는 브라우저 환경에서 3D 씬을 부드럽게 렌더링하기 위해 CPU와 GPU 간의 병목 현상을 줄이고 하드웨어 자원의 효율성을 극대화하는 일련의 기법을 의미합니다. 가장 핵심적인 목표는 CPU 오버헤드를 유발하는 드로우 콜(Draw Call) 횟수를 프레임당 100회 미만으로 유지하는 것이며, 이를 위해 인스턴싱(Instancing)과 배칭(Batching) 같은 기술이 필수적으로 사용됩니다 [1-5]. 또한, 에셋 압축, 메모리 관리, 셰이더 및 시야 절두체 컬링(Frustum Culling) 조정, WebGPU와 컴퓨트 셰이더의 도입 등을 통해 전반적인 연산 부하를 다각도로 최적화합니다 [1, 6-8].

## 📖 Core Content
* **드로우 콜(Draw Call) 최적화**
  * **InstancedMesh:** 동일한 기하학적 구조(Geometry)와 재질(Material)을 가진 수천 개의 객체를 단 한 번의 드로우 콜로 렌더링하여 CPU-GPU 간 명령 발행 오버헤드를 대폭 감소시킵니다 [2, 9-11]. 하지만 기본적으로 전체 인스턴스를 하나로 묶어 단일 시야 절두체 컬링을 수행하므로 화면 밖의 객체까지 연산할 수 있으며, 깊이 정렬이 자동 지원되지 않아 오버드로우(Overdraw)로 인한 프래그먼트 셰이더 병목을 유발할 수 있습니다 [12-15].
  * **BatchedMesh:** 재질은 동일하지만 기하학적 구조가 다른 여러 객체를 하나의 드로우 콜로 묶어 렌더링할 수 있는 객체입니다 [16-19]. 복잡하고 이질적인 부품이 많은 모델에 유용하지만, 정렬(Sorting) 및 개별 객체 컬링을 수행하는 과정과 멀티 드로우(`multiDrawElementsWEBGL`) API의 오버헤드로 인해 정점 수가 매우 많은 상황에서는 CPU 점유율이 40~60%까지 치솟고 프레임률이 급락하는 성능 저하가 발생할 수 있습니다 [19-22].
  * **지오메트리 병합 (Geometry Merging):** 움직이지 않는 정적인 객체들은 로딩 시점에 `BufferGeometryUtils`를 사용하여 하나의 메쉬로 병합함으로써 드로우 콜을 1회로 줄일 수 있습니다 [16, 23-25]. 하지만 이는 메모리 사용량을 크게 증가시키고 개별 객체의 제어나 컬링이 불가능해지는 단점이 있습니다 [23-25].

* **에셋 압축 및 메모리 관리**
  * 모델의 기하학적 용량을 90-95% 줄여주는 Draco 압축과, VRAM 내에서 압축 상태를 유지해 텍스처 메모리 사용량을 대폭 줄여주는 KTX2 또는 Basis Universal 텍스처 포맷 사용이 강력히 권장됩니다 [3, 26-29].
  * Three.js는 GPU 리소스를 자동으로 가비지 컬렉트하지 않으므로, 사용이 끝난 `geometry`, `material`, `texture` 및 렌더 타겟에 대해 반드시 `.dispose()`를 호출하여 메모리 누수를 방지해야 합니다 [30-33].

* **시각적 최적화 및 셰이더 기법**
  * **LOD (Level of Detail):** 카메라와의 거리에 따라 객체를 단순한 폴리곤 버전을 사용하거나 임포스터(Billboard Impostor)로 교체하여 프래그먼트 연산 비용과 삼각형 수를 극적으로 줄일 수 있습니다 [7, 34-37]. 단, LOD는 드로우 콜 자체를 줄여주지는 않으므로 병목의 원인에 맞춰 사용해야 합니다 [38].
  * 다수의 텍스처 바인딩 비용을 줄이기 위해 여러 텍스처를 한 이미지에 담는 텍스처 아틀라스(Texture Atlas)나 최신의 데이터 배열 텍스처(Data Array Textures)를 활용하여 상태 변경(State Change)을 최소화합니다 [39-42].
  * 연산량이 많은 조명과 그림자는 정적 씬의 경우 라이트맵이나 주변 차폐 맵(AO Maps)으로 사전에 구워(Baking) 연산을 완전히 대체해야 합니다 [43-45]. 모바일 환경에서는 셰이더 변수 정밀도를 `mediump`로 낮춰 성능을 2배가량 향상시킬 수 있습니다 [46].

* **WebGPU 시대의 도래 (2026년 기준)**
  * Three.js r171부터 도입된 WebGPURenderer는 무거운 드로우 콜 환경이나 수백만 개의 파티클 연산에 컴퓨트 셰이더(Compute Shaders)를 적용하여 CPU의 단일 스레드 한계를 극복하고 100배 이상의 성능 향상을 가능하게 합니다 [8, 47-49].
  * TSL (Three Shader Language)을 사용하면 WGSL(WebGPU)과 GLSL(WebGL) 양쪽 모두에서 호환되는 크로스 플랫폼 커스텀 셰이더를 구축할 수 있습니다 [50, 51].

## 🔗 Knowledge Connections
- **Related Topics:** [[드로우 콜 (Draw Call)]], [[InstancedMesh]], [[BatchedMesh]], [[LOD (Level of Detail)]], [[WebGPU]]
- **Projects/Contexts:** [[Three.js r171 WebGPU 도입]], [[IFC.js Fragment 아키텍처]], [[InstancedMesh2 라이브러리]]
- **Contradictions/Notes:** 다양한 지오메트리를 한 번에 렌더링하기 위해 제안된 `BatchedMesh`는 드로우 콜 최적화의 훌륭한 대안으로 소개되지만[18], 다른 소스에서는 1,000만 개가 넘는 트라이앵글 환경에서 인스턴싱 또는 일반 `Merged Mesh`보다 CPU 점유율을 비정상적으로 높이고 프레임률을 크게 떨어뜨리는 심각한 구조적 오버헤드가 있음을 상반되게 지적하고 있습니다[19-22]. 또한 `InstancedMesh` 역시 만능이 아니며 정렬의 부재로 인해 발생하는 심각한 오버드로우(Overdraw) 때문에 일반 메쉬 렌더링보다 느려지는 병목 사례가 보고되고 있습니다[13, 14].

---
*Last updated: 2026-04-19*