Files
2nd/10_Wiki/Topics/Threejs WebGL 렌더링 최적화.md
T

6.0 KiB

id, category, confidence_score, tags, last_reinforced, github_commit
id category confidence_score tags last_reinforced github_commit
P-REINFORCE-AUTO-FE50FB 10_Wiki/💡 Topics/AI 0.90
auto-reinforced
2026-04-20 [P-Reinforce] Continuous Worker - Threejs WebGL 렌더링 최적화

Threejs WebGL 렌더링 최적화

📌 한 줄 통찰 (The Karpathy Summary)

Three.js WebGL 렌더링 최적화는 주로 CPU와 GPU 간의 통신 병목 현상을 유발하는 드로우 콜(Draw Call)을 줄이고, 메모리 및 렌더링 연산 효율을 극대화하는 일련의 과정입니다 [1-6]. 이를 위해 인스턴싱(Instancing), 배칭(Batching), 기하학적 병합, 텍스처/모델 압축 및 LOD(Level of Detail)와 같은 다양한 기법이 복합적으로 적용됩니다 [7-12]. 최적화를 통해 렌더링 프레임 속도를 방어할 수 있으나, 각 기법은 절두체 컬링(Frustum Culling) 정밀도 저하나 오버드로우(Overdraw) 유발과 같은 구조적 한계와 트레이드오프를 가지므로 씬(Scene)의 특성에 맞는 전략적 접근이 필수적입니다 [13-17].

📖 구조화된 지식 (Synthesized Content)

드로우 콜(Draw Call) 최소화 전략

  • 드로우 콜의 병목: 드로우 콜은 CPU가 GPU에 렌더링 상태를 설정하고 기하학적 데이터를 그리도록 지시하는 명령으로, 원활한 60fps 성능을 위해서는 프레임당 100개 미만으로 유지하는 것이 강력히 권장됩니다 [3, 9, 18, 19]. 폴리곤 수보다 드로우 콜의 수가 CPU를 마비시키는 주된 원인이 됩니다 [5].
  • InstancedMesh: 동일한 지오메트리와 재질을 공유하는 다수의 객체를 단 한 번의 드로우 콜로 렌더링합니다 [9, 20]. 렌더링 속도와 메모리 효율을 크게 높이지만, 엔진 레벨에서 전체 인스턴스에 대한 단일 바운딩 볼륨을 사용하여 개별 객체의 시야 절두체 컬링(Frustum Culling)이 불가합니다 [13, 21]. 또한 렌더링 순서 자동 정렬이 되지 않아 픽셀 중복 연산(Overdraw)이 발생할 수 있으며 스킨드 애니메이션 적용이 매우 제한적입니다 [15, 16, 22].
  • BatchedMesh: 동일한 재질을 사용하지만 지오메트리가 서로 다른 객체들을 하나의 드로우 콜로 묶어 처리할 수 있게 합니다 [10, 23-27]. 인스턴스별 컬링 및 가시성 제어가 가능하여 다양성을 확보할 수 있으나, 내부적인 정렬(Sorting)과 컬링 과정에서 막대한 CPU 부하를 유발하여 오히려 프레임이 하락하는 사례도 존재합니다 [27-30].
  • Geometry 병합(Merging): 움직이지 않는 정적인 환경 요소는 BufferGeometryUtils를 사용하여 하나의 지오메트리로 병합하면 드로우 콜을 효과적으로 1회로 줄일 수 있습니다 [10, 31, 32].

에셋 데이터 및 메모리 관리

  • 데이터 압축: Draco 압축을 적용하여 지오메트리 파일 크기를 최대 90-95% 줄일 수 있습니다 [7, 12, 18]. 텍스처는 KTX2 및 Basis Universal 형식으로 압축하여 VRAM 메모리 점유율을 PNG 대비 약 75~90% 낮출 수 있습니다 [7, 18, 33, 34].
  • LOD (Level of Detail): 카메라와의 거리에 따라 폴리곤 수가 적은 메쉬로 교체하거나 원경의 객체를 임포스터(Billboard Impostor)로 대체하여 연산량을 크게 줄일 수 있습니다 [8, 11, 19, 35, 36].
  • 명시적 리소스 해제: Three.js는 GPU 리소스를 자동으로 가비지 컬렉팅하지 않으므로, 사용이 끝난 지오메트리, 재질, 텍스처, 렌더 타겟에 대해 반드시 .dispose()를 호출하여 GPU 메모리 누수를 방지해야 합니다 [37-40].

셰이더, 라이팅 및 포스트 프로세싱 최적화

  • 텍스처 아틀라스(Texture Atlas)나 배열 텍스처(Data Array Textures)를 사용하여 여러 재질을 하나로 통합하면, 재질 스위칭으로 인한 상태 변경 오버헤드를 대폭 줄일 수 있습니다 [26, 41-44].
  • 모바일 기기에서는 셰이더 정밀도를 mediump로 설정하여 성능을 높이고, 분기문(Branching/Conditionals) 대신 mix()step()을 활용하며, 동적 루프를 피해야 합니다 [45, 46].
  • 복잡한 씬에서는 Depth Pre-Pass 기법을 도입하여 보이지 않는 프래그먼트에 대한 무거운 셰이더 연산(오버드로우)을 사전에 차단할 수 있습니다 [47, 48].
  • 정적 씬에서는 라이트맵과 그림자를 런타임 이전에 베이크(Bake)하여 실시간 연산을 피하는 것이 좋습니다 [49].

⚠️ 모순 및 업데이트 (Contradictions & RL Update)

  • 과거 데이터와의 충돌: 자동화 엔진에 의해 매핑된 지식으로, 추후 정밀 검증 필요.
  • 정책 변화: AI 분야의 자동 자산화 수행.

🔗 지식 연결 (Graph)

  • Related Topics: 드로우 콜 (Draw Call), InstancedMesh, BatchedMesh, LOD (Level of Detail), Frustum Culling, Draco 압축, Texture Atlas, WebGPU
  • Projects/Contexts: Utsubo Three.js Optimization Tips (2026), InstancedMesh2 라이브러리, Threedium Image-To-3D WebGL 파이프라인, Three.js Roadmap: Draw Calls
  • Contradictions/Notes:
    • InstancedMesh는 드로우 콜을 혁신적으로 줄여주지만, 자동 정렬 기능이 없고 전체를 렌더링하는 특성 때문에 씬 내 객체들이 중첩될 경우 막대한 오버드로우 연산이 발생하여, 1회 드로우 콜임에도 다수의 개별 메쉬를 렌더링할 때보다 오히려 프레임률(FPS)이 낮아지는 기현상이 발생할 수 있습니다 [13-16, 50].
    • BatchedMesh는 여러 지오메트리를 하나의 드로우 콜로 모아주어 효율적인 것으로 소개되나, 객체의 가시성을 확인하고 렌더링 순서를 정렬하는 연산 비용이 커 특정 다량의 객체 렌더링 씬에서는 병합 메쉬(Merged Mesh)를 사용할 때보다 CPU 사용량을 치솟게 만들고 30~50% 더 낮은 FPS를 기록하는 성능 병목 현상이 보고되고 있습니다 [28-30, 51, 52].

Last updated: 2026-04-19