Files
2nd/10_Wiki/Topics/Threejs.md
T

244 lines
32 KiB
Markdown

---
category: Unified
tags: [auto-consolidated, technical-documentation]
title: [[Three.js 렌더링 최적화|Three.js 렌더링 최적화]] (이전 배치와 동일한 내용)
last_updated: 2026-05-02
---
# [[Three.js 렌더링 최적화|Three.js 렌더링 최적화]] (이전 배치와 동일한 내용)
## 📌 Brief Summary
> 대규모 웹 환경에서 WebGL 기반 3D 씬을 구현할 때, 단순한 모델 로딩 이상의 관점에서 드로우 콜 감소, 자원 재활용, 그리고 GPU/CPU 부하 분산을 통해 성능 병목을 해결하는 것이 핵심이다.
---
> Three.js 대규모 렌더링 최적화 파이프라인은 수많은 3D 객체를 브라우저 환경에서 매끄럽게 렌더링하기 위해 CPU와 GPU 간의 통신 오버헤드, 즉 드로우 콜([[Draw Call|Draw Call]])과 메모리 병목 현상을 극복하는 일련의 기술적 아키텍처입니다 [1, 2]. 주로 InstancedMesh와 BatchedMesh를 통한 드로우 콜 최소화, Draco 및 KTX2 등을 이용한 에셋 압축, 절두체 컬링(Frustum Culling) 및 LOD 시스템을 활용하여 그래픽 자원의 낭비를 줄입니다 [3-6]. 최근에는 [[WebGPU|WebGPU]]와 컴퓨트 셰이더([[Compute Shader|Compute Shader]])가 도입되어 렌더링 제어 및 가시성 판단 연산을 GPU로 대거 이관함으로써, 더욱 막대한 규모의 씬을 유연하게 처리할 수 있는 차세대 파이프라인으로 진화하고 있습니다 [7-9].
---
> Three.js 렌더링 성능 최적화는 브라우저 환경에서 3D 씬을 부드럽게 렌더링하기 위해 CPU와 GPU 간의 병목 현상을 줄이고 하드웨어 자원의 효율성을 극대화하는 일련의 기법을 의미합니다. 가장 핵심적인 목표는 CPU 오버헤드를 유발하는 드로우 콜([[Draw Call|Draw Call]]) 횟수를 프레임당 100회 미만으로 유지하는 것이며, 이를 위해 인스턴싱(Instancing)과 배칭(Batching) 같은 기술이 필수적으로 사용됩니다 [1-5]. 또한, 에셋 압축, 메모리 관리, 셰이더 및 시야 절두체 컬링([[Frustum Culling|Frustum Culling]]) 조정, [[WebGPU|WebGPU]]와 컴퓨트 셰이더의 도입 등을 통해 전반적인 연산 부하를 다각도로 최적화합니다 [1, 6-8].
---
> Three.js 렌더링 최적화는 웹 환경에서 3D 그래픽을 부드럽고 효율적으로 구동하기 위해 CPU와 GPU 간의 병목 현상을 해소하는 일련의 기술적 과정입니다 [1-3]. 핵심 목표는 초당 프레임 수(FPS)를 안정적으로 유지하기 위해 드로우 콜([[Draw Call|Draw Call]]) 횟수를 최소화하고, 메모리 대역폭을 효율적으로 관리하는 것입니다 [4-7]. 이를 위해 인스턴싱(Instancing), 배칭(Batching), 에셋 압축, 디테일 수준(LOD) 조절 및 최신 [[WebGPU|WebGPU]] API의 도입이 필수적으로 요구됩니다 [4, 8-10].
---
> Three.js 모바일 렌더링 최적화는 제한된 컴퓨팅 파워, 메모리 대역폭 및 배터리 용량을 가진 모바일 기기 환경에서 3D 장면을 원활하게 구동하기 위한 일련의 기술적 접근이다. 이 최적화는 셰이더 정밀도 조절, 텍스처 및 폴리곤 수 제한, 드로우 콜([[Draw Call|Draw Call]]) 감소, 배터리 절약을 위한 렌더링 루프 제어 등을 포함한다 [1-4]. 이를 통해 모바일 브라우저에서도 60fps의 안정적인 프레임 속도를 유지하고 메모리 한계로 인한 애플리케이션 크래시를 방지할 수 있다 [5, 6].
---
> Three.js 성능 최적화는 CPU와 GPU 간의 통신 병목 현상을 유발하는 드로우 콜([[Draw Call|Draw Call]])을 줄이고 렌더링 파이프라인의 효율을 극대화하여 높은 프레임 속도를 유지하는 과정이다 [1-3]. 주로 `[[InstancedMesh|InstancedMesh]]` 및 `BatchedMesh`를 활용한 인스턴싱/배칭 기법, 텍스처와 지오메트리 압축, 프러스텀 컬링([[Frustum Culling|Frustum Culling]]) 및 LOD(Level of Detail) 기법이 핵심적으로 사용된다 [4-9]. 최근에는 [[WebGL|WebGL]]의 구조적 한계를 극복하기 위해 [[WebGPU|WebGPU]]와 컴퓨트 셰이더를 기반으로 한 GPU 주도 렌더링([[GPU-driven Rendering|GPU-driven Rendering]]) 기술로 발전하고 있다 [10, 11].
---
> Three.js는 [[WebGL|WebGL]] 및 [[WebGPU|WebGPU]]를 사용하여 웹 브라우저에서 애니메이션 3D 컴퓨터 그래픽스를 생성하고 표시할 수 있도록 지원하는 크로스 브라우저 자바스크립트 라이브러리이자 API이다 [1, 2]. 브라우저, GPU, 자바스크립트 간의 복잡한 상호작용을 추상화하여 개발자가 고성능의 3D 환경을 쉽게 구축할 수 있도록 돕는다 [3]. 2026년을 기점으로 프로덕션 수준의 WebGPU 렌더러와 TSL(Three Shader Language)이 도입되면서, 단순한 시각화를 넘어 수백만 개의 파티클 연산이나 대규모 CAD 모델 처리까지 가능한 고성능 플랫폼으로 진화했다 [4-7].
## 📖 Core Content
- **성능 최적화의 목표:** 웹 브라우저 환경에서 높은 프레임률(60FPS 이상)을 유지하면서 복잡한 3D 시각화를 구현하는 것이다. 주요 병목 구간은 CPU/GPU 자원 관리와 데이터 전송량에 있다.
- **핵심 기술 및 전략:** (생략 - 핵심 내용은 이미 위키화 되어있음)
1. **드로우 콜 최적화 ([[Draw Call|Draw Call]] Optimization):** Instancing, [[Batching|Batching]]을 통해 GPU 부하를 줄인다.
2. **자원 관리 (Resource [[Management|Management]]):** Dispose() 호출을 통한 메모리 누수 방지 및 효율적인 자원 재활용.
3. **렌더링 기법 개선:** LOD, Culling 등 하드웨어 기반 최적화 적용.
---
- **드로우 콜(Draw Call) 최소화 전략:** 실시간 렌더링 성능을 저하시키는 가장 결정적인 요인은 CPU가 렌더링 상태를 변경하고 GPU에 명령을 내리는 드로우 콜의 오버헤드입니다 [2, 10]. 원활한 60fps를 유지하려면 프레임당 드로우 콜을 100회 미만으로 타겟팅해야 합니다 [4, 11]. 이를 위해 동일한 기하학적 구조와 재질을 공유하는 객체는 `InstancedMesh`를 활용하여 수천 개를 단일 드로우 콜로 처리하며 [4, 5, 12], 재질은 같으나 지오메트리가 다양한 객체들은 `BatchedMesh`를 통해 최적화합니다 [13-15]. 정적인 배경이나 환경 모델은 `[[BufferGeometry|BufferGeometry]]Utils`를 사용해 하나의 지오메트리로 병합(Merging)하는 방법이 사용됩니다 [13, 16].
- **가시성 판단(Culling) 및 정렬 한계 극복:** `InstancedMesh`는 엔진 내부에서 단일 객체로 취급되기 때문에, 기본 절두체 컬링이 개별 인스턴스에는 작동하지 않는 '전부 아니면 전무' 방식의 한계를 가집니다 [17]. 이로 인해 화면 밖의 객체까지 정점 연산이 강제되고, 거리 기반 자동 정렬의 부재로 인해 막대한 오버드로우([[Overdraw|Overdraw]]) 현상을 일으킬 수 있습니다 [18, 19]. 이에 대응하기 위해 BVH(Bounding Volume Hierarchy)를 결합하여 인스턴스 단위의 개별 컬링과 정렬을 지원하는 확장 라이브러리(예: `[[InstancedMesh2|InstancedMesh2]]`)를 사용하거나 [20-22], 거리에 따라 모델 해상도를 낮추는 LOD(Level of Detail) 기법을 함께 적용하여 연산량을 제한합니다 [6, 11, 23].
- **메모리 대역폭 및 에셋 최적화:** 대형 어셈블리 모델이나 포인트 클라우드의 VRAM 고갈과 대역폭 한계를 막는 것은 파이프라인의 핵심입니다. Draco 압축을 통해 지오메트리 파일 크기를 최대 95%까지 축소시키고 [3, 24], KTX2나 Basis Universal 포맷을 적용하여 텍스처가 압축된 상태로 GPU 메모리에 상주하도록 만들어 메모리 소비를 약 10배 절감합니다 [3, 25]. 또한 다양한 재질의 텍스처를 하나의 텍스처 아틀라스([[Texture Atlas|Texture Atlas]])나 배열 텍스처([[Data Array Textures|Data Array Textures]])로 결합하면 텍스처 바인딩으로 인한 상태 변경 비용을 크게 줄일 수 있습니다 [26-29].
- **WebGPU 기반 차세대 렌더링 파이프라인:** 2026년 기준, Three.js(r171 이상)의 `WebGPURenderer` 및 TSL(Three Shader Language) 도입으로 대규모 렌더링 구조가 혁신적으로 변화했습니다 [7, 30]. 일반적인 CPU 한계를 초과하던 100만 개 이상의 파티클 연산, 물리 시뮬레이션, 복잡한 군중 애니메이션 등을 컴퓨트 셰이더(Compute Shader)를 통한 [[GPU-driven Rendering|GPU-driven Rendering]]으로 병렬 처리할 수 있게 되었습니다 [31-34]. Native WebGPU 수준에서는 `GPURenderBundles` 및 [[Indirect Draw|Indirect Draw]]ing 기술을 통해 500MB 이상의 초대형 건설/BIM 데이터셋에서도 강력한 성능 향상을 이끌어냅니다 [35, 36].
---
* **드로우 콜(Draw Call) 최적화**
* **[[InstancedMesh|InstancedMesh]]:** 동일한 기하학적 구조(Geometry)와 재질(Material)을 가진 수천 개의 객체를 단 한 번의 드로우 콜로 렌더링하여 CPU-GPU 간 명령 발행 오버헤드를 대폭 감소시킵니다 [2, 9-11]. 하지만 기본적으로 전체 인스턴스를 하나로 묶어 단일 시야 절두체 컬링을 수행하므로 화면 밖의 객체까지 연산할 수 있으며, 깊이 정렬이 자동 지원되지 않아 오버드로우([[Overdraw|Overdraw]])로 인한 프래그먼트 셰이더 병목을 유발할 수 있습니다 [12-15].
* **BatchedMesh:** 재질은 동일하지만 기하학적 구조가 다른 여러 객체를 하나의 드로우 콜로 묶어 렌더링할 수 있는 객체입니다 [16-19]. 복잡하고 이질적인 부품이 많은 모델에 유용하지만, 정렬([[Sorting|Sorting]]) 및 개별 객체 컬링을 수행하는 과정과 멀티 드로우(`multiDrawElements[[WebGL|WebGL]]`) API의 오버헤드로 인해 정점 수가 매우 많은 상황에서는 CPU 점유율이 40~60%까지 치솟고 프레임률이 급락하는 성능 저하가 발생할 수 있습니다 [19-22].
* **지오메트리 병합 ([[Geometry Merging|Geometry Merging]]):** 움직이지 않는 정적인 객체들은 로딩 시점에 `[[BufferGeometry|BufferGeometry]]Utils`를 사용하여 하나의 메쉬로 병합함으로써 드로우 콜을 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|Texture Atlas]])나 최신의 데이터 배열 텍스처(Data Array Textures)를 활용하여 상태 변경([[State|State]] Change)을 최소화합니다 [39-42].
* 연산량이 많은 조명과 그림자는 정적 씬의 경우 라이트맵이나 주변 차폐 맵(AO Maps)으로 사전에 구워(Baking) 연산을 완전히 대체해야 합니다 [43-45]. 모바일 환경에서는 셰이더 변수 정밀도를 `mediump`로 낮춰 성능을 2배가량 향상시킬 수 있습니다 [46].
* **WebGPU 시대의 도래 (2026년 기준)**
* Three.js r171부터 도입된 WebGPURenderer는 무거운 드로우 콜 환경이나 수백만 개의 파티클 연산에 컴퓨트 셰이더([[Compute Shader|Compute Shader]]s)를 적용하여 CPU의 단일 스레드 한계를 극복하고 100배 이상의 성능 향상을 가능하게 합니다 [8, 47-49].
* [[TSL (Three Shader Language)|TSL (Three Shader Language]]을 사용하면 WGSL(WebGPU)과 GLSL(WebGL) 양쪽 모두에서 호환되는 크로스 플랫폼 커스텀 셰이더를 구축할 수 있습니다 [50, 51].
---
- **드로우 콜(Draw Call)의 최소화:** 드로우 콜은 CPU가 GPU에게 렌더링을 지시하는 명령으로, 과도한 호출에 따른 오버헤드는 성능을 저하시키는 가장 큰 원인입니다 [3, 11, 12]. 원활한 60fps를 유지하기 위해서는 프레임당 드로우 콜을 100회 미만으로 유지하는 것이 권장됩니다 [5, 8, 13].
- **[[InstancedMesh|InstancedMesh]]와 BatchedMesh 활용:** 동일한 기하학적 구조와 재질을 가진 반복적인 객체(예: 나무, 군중)를 렌더링할 때는 `InstancedMesh`를 사용하여 단일 드로우 콜로 수많은 객체를 렌더링해야 합니다 [5, 14-16]. 반면, 재질은 동일하지만 지오메트리가 서로 다른 객체들을 그룹화하여 렌더링할 때는 `BatchedMesh`를 사용하는 것이 효율적입니다 [17-20].
- **에셋 및 메모리 최적화:** 지오메트리 파일 크기를 최대 95%까지 줄여주는 Draco 압축을 사용하고, VRAM 사용량을 대폭 감소시키며 GPU에서 직접 압축이 해제되는 KTX2 및 Basis Universal 텍스처 형식을 적용해야 합니다 [8, 21-23]. 또한 사용이 끝난 지오메트리, 재질, 텍스처, 렌더 타겟 등은 반드시 `.dispose()`를 호출하여 명시적으로 GPU 메모리를 해제해야 누수를 방지할 수 있습니다 [24-27].
- **LOD(Level of Detail) 및 컬링:** 카메라와의 거리에 따라 폴리곤 수가 적은 모델이나 임포스터(Impostor)로 교체하여 렌더링 연산을 줄이는 LOD 시스템을 구현해야 합니다 [13, 28-31]. 더불어 보이지 않는 객체를 렌더링에서 제외하는 절두체 컬링([[Frustum Culling|Frustum Culling]])이 올바르게 동작하도록 바운딩 박스를 관리해야 합니다 [32, 33].
- **WebGPU 및 TSL 전환:** Three.js r171 버전부터 정식 지원되는 `WebGPURenderer`는 대규모 데이터셋 처리와 컴퓨트 집약적인 효과(파티클, 물리 연산 등)에서 기존 대비 수 배에서 100배 이상의 성능 향상을 제공합니다 [34-37]. 새로운 TSL(Three Shader Language)을 사용하면 단일 코드로 작성된 셰이더를 WebGPU와 [[WebGL|WebGL]] 모두에 호환되게 배포할 수 있습니다 [38-40].
---
* **셰이더 및 정밀도 최적화**
* 모바일 GPU는 `mediump` 정밀도를 처리할 때 `highp`보다 대략 2배 빠른 속도를 내므로, 깊이 계산이나 위치 등 필수적인 경우를 제외하고는 기본적으로 `mediump`를 사용해야 한다 [1].
* 버텍스 셰이더와 프래그먼트 셰이더 사이에서 데이터를 전달하는 varying 변수의 개수를 모바일 GPU에 맞춰 3개 이하로 최소화해야 한다 [1].
* **메모리 및 텍스처 관리**
* 모바일 기기는 보통 2~4GB의 제한된 시스템 메모리를 가지며, 텍스처 메모리가 500MB를 초과하면 가비지 컬렉션(GC)으로 인한 일시 중지와 심각한 프레임 끊김이 발생한다 [5].
* 이를 해결하기 위해 Basis Universal이나 KTX2와 같은 GPU 친화적인 압축 텍스처를 사용해야 한다. 이러한 포맷은 모바일 플랫폼에 따라 ASTC(Android)나 PVRTC(iOS)로 로드 시 변환되어 메모리 사용량을 대폭 줄여준다 [7].
* 다수의 텍스처를 사용하는 대신, 텍스처 아틀라스([[Texture Atlas|Texture Atlas]])로 결합하여 텍스처 바인딩 횟수를 줄이는 것이 모바일 GPU의 렌더링 오버헤드를 크게 감소시키는 방법이다 [8, 9].
* **드로우 콜 및 지오메트리 제한**
* 프로세서 성능이 상대적으로 낮은 모바일 브라우저에서는 1,000~2,000회의 드로우 콜 한계치에 도달하면 CPU 병목으로 인한 성능 저하가 눈에 띄게 나타난다 [4].
* 모바일 브라우저(iOS Safari, [[Chrome|Chrome]] Mobile 등) 환경에서는 화면당 폴리곤 개수를 50,000~100,000개 수준으로 제한해야 매끄러운 렌더링이 보장된다 [3].
* **그림자 및 안티앨리어싱 설정 타협**
* 섀도우 맵 렌더링은 리소스 소모가 크므로, 모바일의 경우 섀도우 맵 크기를 512에서 1024 사이로 작게 설정하는 것이 바람직하다 [10].
* 렌더링 파이프라인 구성 시 고비용의 네이티브 안티앨리어싱(MSAA)을 비활성화하고, 그 대신 포스트 프로세싱인 FXAA를 사용하면 모바일 기기에서도 성능 부하를 5~10% 수준으로 낮추면서 60fps를 유지할 수 있다 [6].
* **배터리 절약 및 오류 복구(Context [[Management|Management]])**
* 정적인 씬(Static scenes)의 경우 리액트 기반 환경(R3F 등)에서 `frameloop="demand"` 옵션을 사용하여 불필요한 프레임 렌더링을 방지함으로써 모바일 기기의 배터리를 아껴야 한다 [2].
* 모바일 환경에서는 [[WebGL|WebGL]] 컨텍스트 손실(Context lost)이 발생할 수 있으므로, 리스너(`webglcontextlost`)를 등록하여 이를 감지하고 우아하게 복구하는(gracefully recover) 예외 처리가 필수적이다 [11].
---
* **드로우 콜 최적화 (Draw Call [[Optimization|Optimization]])**
* 드로우 콜은 CPU가 GPU에 렌더링 명령을 내리는 과정으로, 프레임당 100개 이하로 유지하는 것이 부하를 막는 핵심 규칙이다 [1, 2, 4].
* 동일한 지오메트리와 재질을 여러 번 렌더링할 때는 `InstancedMesh`를 사용하여 단일 드로우 콜로 처리해야 한다 [4, 6].
* 재질은 같지만 지오메트리가 다를 경우에는 여러 지오메트리를 하나의 렌더링 호출로 묶어주는 `BatchedMesh`를 사용하는 것이 효율적이다 [12-14].
* 서로 독립적으로 움직일 필요가 없는 정적인 배경이나 환경 객체는 `[[BufferGeometry|BufferGeometry]]Utils`를 사용하여 로드 시점에 하나의 메쉬로 병합(Merge)하는 것이 좋다 [12, 15].
* **에셋 및 메모리 관리 (Asset & [[memory|memory]] [[Management|Management]])**
* 형상을 유지하며 폴리곤을 줄이는 데시메이션(Decimation) 작업을 거치고, Draco 확장을 통해 지오메트리 파일 크기를 최대 95%까지 압축할 수 있다 [16-18].
* 텍스처의 경우, GPU 메모리에서 압축 상태를 유지하는 KTX2나 Basis Universal 포맷을 사용해 메모리 대역폭 점유율을 크게 낮춰야 한다 [16, 19].
* 수백 개의 텍스처가 필요할 때는 바인딩 오버헤드를 막기 위해 텍스처 아틀라스([[Texture Atlas|Texture Atlas]])나 여러 텍스처 레이어를 인덱스로 접근할 수 있는 배열 텍스처([[Data Array Textures|Data Array Textures]])를 활용해야 한다 [7, 20, 21].
* Three.js는 GPU 자원을 자동으로 가비지 컬렉션하지 않으므로, 사용이 끝난 지오메트리, 재질, 텍스처는 반드시 `.dispose()`를 명시적으로 호출해 메모리 누수를 방지해야 한다 [22, 23].
* **가시성 판단 및 LOD (Visibility & Level of Detail)**
* 카메라와의 거리에 따라 고해상도 메쉬를 저해상도 메쉬나 임포스터(Impostor)로 교체하는 LOD 기법을 통해 폴리곤 렌더링 비용을 크게 절감할 수 있다 [8, 24-26].
* Three.js의 프러스텀 컬링(Frustum Culling)은 화면 밖의 객체를 렌더링에서 제외하지만, `InstancedMesh`의 경우 개별 인스턴스가 아닌 전체 바운딩 볼륨을 기준으로 컬링하기 때문에 보이지 않는 객체까지 GPU 정점 연산을 수행하는 낭비가 발생할 수 있다 [27]. 이를 보완하기 위해 BVH(Bounding Volume Hierarchy)와 같은 공간 분할 자료구조를 사용하거나 GPU 컴퓨트 셰이더 기반의 컬링 기법이 필요하다 [28, 29].
* **WebGPU 전환 및 GPU 주도 렌더링 (WebGPU & [[Compute Shader|Compute Shader]]s)**
* 전통적인 `InstancedMesh`는 자동 정렬의 부재로 인해 깊이 오버드로우([[Overdraw|Overdraw]])가 발생하고 투명도 블렌딩 오류를 야기하며, 본(Bone) 기반 애니메이션 처리에 취약하다는 구조적 한계가 있다 [30-32].
* 이러한 병목을 해소하기 위해 Three.js는 WebGPU 렌더러와 단일 코드로 관리되는 TSL(Three Shader Language)을 전면 도입했다 [33, 34].
* 컴퓨트 셰이더를 활용하면 CPU에서 처리하던 충돌 감지, 지형 생성, 수백만 개의 파티클 업데이트 및 컬링을 GPU에서 병렬로 직접 수행할 수 있어 극적인 성능 향상을 이룰 수 있다 [35-37].
---
* **렌더링 파이프라인 및 드로우 콜([[Draw Call|Draw Call]]) 최적화:**
실시간 3D 렌더링에서 CPU가 GPU에 렌더링을 명령하는 '드로우 콜'은 시스템 오버헤드의 주된 원인으로 꼽힌다 [8-10]. Three.js는 이를 최소화하기 위해 단일 기하학(Geometry)과 재질(Material)을 공유하는 객체들을 한 번에 렌더링하는 `[[InstancedMesh|InstancedMesh]]`, 다양한 기하학적 구조를 동일한 재질 하에 하나로 묶어 처리하는 `BatchedMesh`, 그리고 정적 객체들을 로드 시점에 병합해버리는 `[[BufferGeometry|BufferGeometry]]Utils.mergeBufferGeometries` 기법을 지원한다 [11-15].
* **WebGPU와 TSL(Three Shader Language)의 도입:**
릴리즈 r171부터 도입된 WebGPURenderer는 `forceWebGL`이 필요한 상황을 제외하면 WebGL 2 자동 폴백 기능을 지원하는 "제로 설정(zero-config)" 방식으로 쉽게 적용할 수 있다 [4, 5, 16]. 새롭게 도입된 TSL은 단일 코드로 WGSL과 GLSL 양쪽 모두에 컴파일되는 노드 기반의 재질 시스템이며, 컴퓨트 셰이더([[Compute Shader|Compute Shader]]s)를 통해 물리 연산, 충돌 감지, 수백만 단위의 대규모 파티클 시스템 렌더링 등 병렬 처리를 GPU로 오프로딩할 수 있게 해준다 [5, 17-20].
* **메모리 및 애셋 관리의 중요성:**
Three.js는 GPU 리소스를 자동으로 가비지 컬렉션([[Garbage Collection|Garbage Collection]])하지 않으므로, 사용이 끝난 지오메트리, 재질, 텍스처는 반드시 `.dispose()` 메서드를 호출해 명시적으로 해제해야만 VRAM 누수를 막을 수 있다 [21, 22]. 모델 로드 시 대역폭과 메모리를 아끼기 위해 Draco 지오메트리 압축, KTX2 및 Basis Universal과 같은 GPU 네이티브 텍스처 압축 기술이 필수적이며 [23-25], 카메라 거리에 따라 다각형 수를 조절하는 LOD(Level of Detail) 기능으로 렌더링 부하를 동적으로 줄일 수 있다 [26-28].
* **인스턴싱([[Instancing|Instancing]])의 구조적 한계:**
`InstancedMesh`는 성능 향상에 필수적인 도구지만 몇 가지 한계가 있다. 엔진 수준에서 전체 인스턴스를 아우르는 하나의 경계 볼륨(Bounding Volume)을 기준으로 시야 절두체 컬링([[Frustum Culling|Frustum Culling]])을 처리하기 때문에, 시야 밖에 있는 인스턴스에 대해서도 GPU 정점 연산을 수행하는 비효율이 발생한다 [29, 30]. 또한, 객체들의 심도에 따른 자동 정렬(Depth Sorting)을 제공하지 않아, 투명한 객체가 겹쳐 있거나 복잡한 셰이더를 사용할 경우 심각한 오버드로우([[Overdraw|Overdraw]])를 유발하여 GPU 프래그먼트 처리 병목을 초래할 수 있다 [31-34].
* **사용자 입력과 레이캐스팅([[Raycasting|Raycasting]]):**
사용자의 마우스나 터치 입력을 통한 화면 상의 3D 객체 선택(피킹)은 `[[Raycaster|Raycaster]]` 객체를 통해 수행된다 [35, 36]. 하지만 `InstancedMesh`에서 개별 인스턴스의 행렬(위치/회전/축척)을 동적으로 변경할 경우, 레이캐스팅이 정상 작동하려면 변경 직후 반드시 `.computeBoundingSphere()``.computeBoundingBox()`를 호출하여 바운딩 볼륨을 갱신해야 한다 [37, 38]. 다량의 인스턴스가 존재하는 환경에서 충돌 및 선택의 속도를 높이려면 `[[three-mesh-bvh|three-mesh-bvh]]` 같은 공간 분할(Spatial Indexing) 라이브러리를 활용하는 것이 권장된다 [39, 40].
## ⚖️ Trade-offs & Caveats
- **정책 변화:** [[WebGPU|WebGPU]]의 도입은 기존 WebGL의 한계를 뛰어넘는 가장 중요한 패러다임 전환점이며, 이를 활용한 컴퓨팅 기능([[Compute Shader|Compute Shader]])이 핵심 트렌드로 부상 중이다.
---
- **과거 데이터와의 충돌:** 자동화 엔진에 의해 매핑된 지식으로, 추후 정밀 검증 필요.
- **정책 변화:** Graphics & Performance 분야의 자동 자산화 수행.
---
- **과거 데이터와의 충돌:** 자동화 엔진에 의해 매핑된 지식으로, 추후 정밀 검증 필요.
- **정책 변화:** Graphics & Performance 분야의 자동 자산화 수행.
---
- **과거 데이터와의 충돌:** 자동화 엔진에 의해 매핑된 지식으로, 추후 정밀 검증 필요.
- **정책 변화:** Graphics & Performance 분야의 자동 자산화 수행.
---
- **과거 데이터와의 충돌:** 자동화 엔진에 의해 매핑된 지식으로, 추후 정밀 검증 필요.
- **정책 변화:** Graphics & Performance 분야의 자동 자산화 수행.
---
- **과거 데이터와의 충돌:** 자동화 엔진에 의해 매핑된 지식으로, 추후 정밀 검증 필요.
- **정책 변화:** AI 분야의 자동 자산화 수행.
---
- **과거 데이터와의 충돌:** 자동화 엔진에 의해 매핑된 지식으로, 추후 정밀 검증 필요.
- **정책 변화:** Graphics & Performance 분야의 자동 자산화 수행.
## 🔗 Knowledge Connections
- Parent: [[WebGL Optimization|WebGL Optimization]]
- Related: [[InstancedMesh|InstancedMesh]] , Draw Call Optimization , [[WebGPU|WebGPU]]
---
---
- **Related Topics:** `[[InstancedMesh|InstancedMesh]]`, `BatchedMesh`, `[[WebGPU|WebGPU]]`, `Draw Call (드로우 콜)`, `Frustum Culling (절두체 컬링)`, `LOD (Level of Detail)`, `Overdraw (오버드로우)`, `Compute Shader (컴퓨트 셰이더)`
- **Projects/Contexts:** `InstancedMesh2 (agargaro)`, `Three.js r171 WebGPURenderer`, `Segments.ai`, `Fragment (IFC.js)`
- **Contradictions/Notes:**
- `InstancedMesh`는 드로우 콜을 줄여 성능을 크게 향상시키도록 설계되었으나, 불투명도 및 복잡한 셰이더 환경에서는 인스턴스 정렬 부재로 인한 심각한 오버드로우(Overdraw)를 유발해 일반 개별 Mesh(Shared attributes)를 사용할 때보다 프레임 레이트(FPS)가 오히려 낮아지는 역설적인 사례가 보고되고 있습니다 [18, 19].
- `BatchedMesh` 역시 다수의 기하학적 구조를 통합하는 유용한 기술이지만, 약 20만 개 수준의 대량 지오메트리에 적용할 시 버퍼 데이터 업로드 등의 이유로 CPU 사용량이 30~50% 급증하며 병합된 기하학(Merged Geometry)보다 현저히 성능이 하락하는 구조적 병목이 제기되고 있습니다 [37-39].
---
*Last updated: 2026-04-19*
---
---
- **Related Topics:** 드로우 콜 (Draw Call), [[InstancedMesh|InstancedMesh]], BatchedMesh, LOD (Level of Detail), [[WebGPU|WebGPU]]
- **Projects/Contexts:** Three.js r171 WebGPU 도입, IFC.js Fragment 아키텍처, [[InstancedMesh2|InstancedMesh2]] 라이브러리
- **Contradictions/Notes:** 다양한 지오메트리를 한 번에 렌더링하기 위해 제안된 `BatchedMesh`는 드로우 콜 최적화의 훌륭한 대안으로 소개되지만[18], 다른 소스에서는 1,000만 개가 넘는 트라이앵글 환경에서 인스턴싱 또는 일반 `Merged Mesh`보다 CPU 점유율을 비정상적으로 높이고 프레임률을 크게 떨어뜨리는 심각한 구조적 오버헤드가 있음을 상반되게 지적하고 있습니다[19-22]. 또한 `InstancedMesh` 역시 만능이 아니며 정렬의 부재로 인해 발생하는 심각한 오버드로우(Overdraw) 때문에 일반 메쉬 렌더링보다 느려지는 병목 사례가 보고되고 있습니다[13, 14].
---
*Last updated: 2026-04-19*
---
---
- **Related Topics:** [[Draw Call|Draw Call]], InstancedMesh, BatchedMesh, WebGPU, [[Level of Detail (LOD)|Level of Detail (LOD]], [[Texture Compression|Texture Compression]]
- **Projects/Contexts:** [[Utsubo|Utsubo]], Segments.ai, [[InstancedMesh2 library|InstancedMesh2 library]]
- **Contradictions/Notes:** `InstancedMesh`는 드로우 콜을 획기적으로 줄여주지만, 엔진 수준에서 개별 인스턴스에 대한 절두체 컬링과 깊이 정렬([[Sorting|Sorting]])이 불가능하여 오버드로우([[Overdraw|Overdraw]])가 유발됩니다. 이로 인해 픽셀 연산이 무거운 씬에서는 오히려 일반 메쉬 방식보다 프레임 레이트가 하락할 수 있다는 한계가 지적됩니다 [41-44]. 대안으로 꼽히는 `BatchedMesh` 역시 수십만 개 단위의 복잡한 기하학적 데이터와 인스턴스를 처리할 때는 심각한 CPU 병목 현상 및 성능 저하를 야기할 수 있습니다 [20, 45-48].
---
*Last updated: 2026-04-19*
---
---
- **Related Topics:** 드로우 콜 최적화 (Draw Call [[Optimization|Optimization]]), 텍스처 압축 (Texture Compression), 셰이더 정밀도 (Shader Precision), 가비지 컬렉션 ([[Garbage Collection|Garbage Collection]]
- **Projects/Contexts:** [[React Three Fiber (R3F)|React Three Fiber (R3F]], Basis Universal / KTX2
- **Contradictions/Notes:** 소스에서는 모바일 환경 구현 시 시각적 품질과 성능 간의 직접적인 타협(trade-off)을 강조한다. 데스크톱 환경에서는 다중 텍스처 파일과 MSAA, 4096 크기의 섀도우 맵 활용이 가능하지만, 모바일 기기에서는 동일한 구성을 유지할 경우 프레임 속도 저하와 발열, 메모리 부족으로 인한 강제 종료를 유발할 수 있으므로 극단적인 간소화(FXAA, 아틀라스 텍스처, 512~1024 섀도우 등)를 필수적으로 도입해야 함을 명시한다 [5, 6, 10].
---
*Last updated: 2026-04-19*
---
---
- **Related Topics:** [[InstancedMesh|InstancedMesh]], BatchedMesh, [[WebGPU|WebGPU]], 드로우 콜 (Draw Call), LOD (Level of Detail)
- **Projects/Contexts:** [[Utsubo|Utsubo]]의 WebGPU 도입 (Segments.ai 등), [[InstancedMesh2|InstancedMesh2]] 라이브러리, Three.js r171 WebGPURenderer
- **Contradictions/Notes:** 드로우 콜을 줄이기 위해 `InstancedMesh``BatchedMesh`를 도입하더라도 항상 성능이 향상되는 것은 아니다. `InstancedMesh`는 개별 컬링의 부재와 오버드로우로 인해 오히려 개별 렌더링보다 GPU FPS를 떨어뜨릴 수 있다는 점이 지적된다 [27, 30, 38]. 또한 `BatchedMesh`의 경우에도 천만 개 이상의 많은 폴리곤과 지오메트리를 처리할 때는 내부적인 다중 그리기(multi-draw) 버퍼 업로드 및 패킹 오버헤드로 인해 CPU 점유율이 40~60%까지 치솟고 프레임이 급감하는 현상이 보고되어, 상황에 따른 벤치마킹이 필수적이다 [39-43].
---
*Last updated: 2026-04-19*
---
---
- **Related Topics:** [[WebGPU|WebGPU]], InstancedMesh, BatchedMesh, TSL (Three Shader Language), [[Raycaster|Raycaster]], LOD (Level of Detail)
- **Projects/Contexts:** [[React Three Fiber (R3F)|React Three Fiber (R3F]], IFC.js, [[InstancedMesh2|InstancedMesh2]]
- **Contradictions/Notes:** 일반적으로 `InstancedMesh`는 드로우 콜을 1회로 줄여 렌더링 성능을 획기적으로 높인다고 알려져 있으나, 인스턴스의 자동 정렬 기능이 없어 오버드로우(Overdraw)가 빈번하게 발생할 경우 단일 메쉬를 분할하여 그릴 때보다 오히려 프레임 속도(FPS)가 급락할 수 있습니다 [4, 31-33]. 또한 여러 다른 지오메트리를 하나의 렌더 호출로 묶어주는 `BatchedMesh` 역시, 지나치게 많은 수의 정점과 데이터를 렌더링할 경우 패킹 및 컬링 연산 때문에 극심한 CPU 과부하와 성능 저하를 야기할 수 있다는 한계가 보고되고 있습니다 [41, 42].
---
*Last updated: 2026-04-19*
---