# [[Three.js|Three.js]]

## 📌 Brief Summary
Three.js는 WebGL 및 WebGPU를 사용하여 웹 브라우저에서 애니메이션 3D 컴퓨터 그래픽스를 생성하고 표시할 수 있도록 지원하는 크로스 브라우저 자바스크립트 라이브러리이자 API이다 [1, 2]. 브라우저, GPU, 자바스크립트 간의 복잡한 상호작용을 추상화하여 개발자가 고성능의 3D 환경을 쉽게 구축할 수 있도록 돕는다 [3]. 2026년을 기점으로 프로덕션 수준의 WebGPU 렌더러와 TSL(Three Shader Language)이 도입되면서, 단순한 시각화를 넘어 수백만 개의 파티클 연산이나 대규모 CAD 모델 처리까지 가능한 고성능 플랫폼으로 진화했다 [4-7].

## 📖 Core Content

*   **렌더링 파이프라인 및 드로우 콜(Draw Call) 최적화:** 
    실시간 3D 렌더링에서 CPU가 GPU에 렌더링을 명령하는 '드로우 콜'은 시스템 오버헤드의 주된 원인으로 꼽힌다 [8-10]. Three.js는 이를 최소화하기 위해 단일 기하학(Geometry)과 재질(Material)을 공유하는 객체들을 한 번에 렌더링하는 `InstancedMesh`, 다양한 기하학적 구조를 동일한 재질 하에 하나로 묶어 처리하는 `BatchedMesh`, 그리고 정적 객체들을 로드 시점에 병합해버리는 `BufferGeometryUtils.mergeBufferGeometries` 기법을 지원한다 [11-15].
*   **WebGPU와 TSL(Three Shader Language)의 도입:** 
    릴리즈 r171부터 도입된 WebGPURenderer는 `forceWebGL`이 필요한 상황을 제외하면 WebGL 2 자동 폴백 기능을 지원하는 "제로 설정(zero-config)" 방식으로 쉽게 적용할 수 있다 [4, 5, 16]. 새롭게 도입된 TSL은 단일 코드로 WGSL과 GLSL 양쪽 모두에 컴파일되는 노드 기반의 재질 시스템이며, 컴퓨트 셰이더(Compute Shaders)를 통해 물리 연산, 충돌 감지, 수백만 단위의 대규모 파티클 시스템 렌더링 등 병렬 처리를 GPU로 오프로딩할 수 있게 해준다 [5, 17-20].
*   **메모리 및 애셋 관리의 중요성:** 
    Three.js는 GPU 리소스를 자동으로 가비지 컬렉션(Garbage Collection)하지 않으므로, 사용이 끝난 지오메트리, 재질, 텍스처는 반드시 `.dispose()` 메서드를 호출해 명시적으로 해제해야만 VRAM 누수를 막을 수 있다 [21, 22]. 모델 로드 시 대역폭과 메모리를 아끼기 위해 Draco 지오메트리 압축, KTX2 및 Basis Universal과 같은 GPU 네이티브 텍스처 압축 기술이 필수적이며 [23-25], 카메라 거리에 따라 다각형 수를 조절하는 LOD(Level of Detail) 기능으로 렌더링 부하를 동적으로 줄일 수 있다 [26-28].
*   **인스턴싱(Instancing)의 구조적 한계:**
    `InstancedMesh`는 성능 향상에 필수적인 도구지만 몇 가지 한계가 있다. 엔진 수준에서 전체 인스턴스를 아우르는 하나의 경계 볼륨(Bounding Volume)을 기준으로 시야 절두체 컬링(Frustum Culling)을 처리하기 때문에, 시야 밖에 있는 인스턴스에 대해서도 GPU 정점 연산을 수행하는 비효율이 발생한다 [29, 30]. 또한, 객체들의 심도에 따른 자동 정렬(Depth Sorting)을 제공하지 않아, 투명한 객체가 겹쳐 있거나 복잡한 셰이더를 사용할 경우 심각한 오버드로우(Overdraw)를 유발하여 GPU 프래그먼트 처리 병목을 초래할 수 있다 [31-34].
*   **사용자 입력과 레이캐스팅(Raycasting):**
    사용자의 마우스나 터치 입력을 통한 화면 상의 3D 객체 선택(피킹)은 `Raycaster` 객체를 통해 수행된다 [35, 36]. 하지만 `InstancedMesh`에서 개별 인스턴스의 행렬(위치/회전/축척)을 동적으로 변경할 경우, 레이캐스팅이 정상 작동하려면 변경 직후 반드시 `.computeBoundingSphere()` 및 `.computeBoundingBox()`를 호출하여 바운딩 볼륨을 갱신해야 한다 [37, 38]. 다량의 인스턴스가 존재하는 환경에서 충돌 및 선택의 속도를 높이려면 `three-mesh-bvh` 같은 공간 분할(Spatial Indexing) 라이브러리를 활용하는 것이 권장된다 [39, 40].

## 🔗 Knowledge Connections
- **Related Topics:** [[WebGPU|WebGPU]], [[InstancedMesh|InstancedMesh]], [[BatchedMesh|BatchedMesh]], [[TSL (Three Shader Language)|TSL (Three Shader Language)]], [[Raycaster|Raycaster]], [[가변적 LOD(Level of Detail) 시스템|LOD (Level of Detail)]]
- **Projects/Contexts:** [[React Three Fiber (R3F)|React Three Fiber (R3F)]], [[IFC.js|IFC.js]], [[InstancedMesh2|InstancedMesh2]]
- **Contradictions/Notes:** 일반적으로 `InstancedMesh`는 드로우 콜을 1회로 줄여 렌더링 성능을 획기적으로 높인다고 알려져 있으나, 인스턴스의 자동 정렬 기능이 없어 오버드로우(Overdraw)가 빈번하게 발생할 경우 단일 메쉬를 분할하여 그릴 때보다 오히려 프레임 속도(FPS)가 급락할 수 있습니다 [4, 31-33]. 또한 여러 다른 지오메트리를 하나의 렌더 호출로 묶어주는 `BatchedMesh` 역시, 지나치게 많은 수의 정점과 데이터를 렌더링할 경우 패킹 및 컬링 연산 때문에 극심한 CPU 과부하와 성능 저하를 야기할 수 있다는 한계가 보고되고 있습니다 [41, 42].

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