드로우 콜(Draw Call)이란?

드로우 콜은 CPU가 GPU에게 Rendering을 위한 명령을 내리는 것 의미한다. 즉, 렌더링 API를 통해 호출되는 Draw Command인 것이다
렌더링 상태는 다음과 같은 요소들을 포함한다
- 정점 버퍼와 인덱스 버퍼
- 정점 쉐이더와 픽셀 쉐이더 프로그램
- 모든 쉐이더 입력(재질, 빛의 색상 등)
이러한 데이터는 RAM에 저장되어 있다가 렌더링 과정 중 GPU의 메모리로 옮겨지며 CPU는 GPU 메모리에서 이 데이터를 가져와 화면에 그린다
CPU Bound와 GPU Bound
드로우 콜이 많아지는 문제는 CPU에서 발생하며 이를 CPU Bound라고 한다
GPU에서 발생하는 문제는 GPU Bound라고 한다
드로우 콜을 최적화 해야 하는 이유

드로우 콜은 한 프레임에서 여러 번 발생할 수 있다. 그런데 드로우 콜이 발생할 때마다 렌더링 상태 변경이 일어난다고 하지 않았는가?
렌더링 상태 변경은 매우 비용이 많이 드는 연산이다. CPU가 내린 명령을 GPU가 이해하기 위해서는 번역 작업이 필요하기 때문인데, 이 번역 작업은 그래픽 드라이버가 수행한다. 그리고 이 때 병목 현상이 발생하는 것이 문제다
그렇다면 드로우 콜을 명령을 내리는 CPU의 명령 횟수를 줄이는 것이 궁극적인 목표일 것이다
Command Buffer
드로우 콜은 커맨드 버퍼를 이용해 처리되며, 선입선출 구조로 작동한다. GPU가 여유가 있을 때는 미리 호출할 수 있지만, 많은 작업이 누적되어 있다면 드로우 콜이 밀릴 수 있다
드로우 콜의 상한선
플랫폼에 따라 다르다
- 일반적으로 콘솔 게임에서는 2000~3000
- PC에서는 1000
- 모바일에서는 100 정도로 간주
프로덕트를 만들 때 대상이 되는 플랫폼의 드로우 콜의 한계를 파악하고, Frame Rate를 유지하도록 노력해야 한다
드로우 콜이 발생하는 경우
- 하나의 Mesh에 하나의 Material이 적용될 때
- 하나의 Mesh에 여러 개의 Material이 적용된 경우 → 머티리얼 개수만큼 발생
- 서로 다른 Material 또는 Shader를 사용하는 오브젝트를 렌더링할 때
- Multi-Pass Shader를 사용하는 경우 → Pass 수만큼 드로우 콜 발생
- Render Queue가 다른 오브젝트 간 렌더링
- Light가 추가되며 여러 Pass가 필요한 경우 (특히 Forward Rendering)
- Reflection Probe, Shadow Pass, Depth Pass 등 추가 렌더링 과정이 있을 때
- GPU Instancing이 적용되지 않은 동일 Mesh 반복 렌더링
- Post-Processing에서 여러 Pass를 사용하는 효과 적용 시
- 서로 다른 텍스처를 사용하는 오브젝트를 렌더링할 때 (Unity는 이를 서로 다른 머티리얼로 간주함)
드로우콜 최적화 기법들
Occlusion Culling
카메라의 시야에는 있지만 다른 오브젝트에 가려져 보이지 않는 오브젝트를 렌더링하지 않는 기법이다


LOD (Level of Detail)
멀리 있는 오브젝트는 간단한 메시로 교체하는 기법이다

Frustum Culling

카메라의 시야에 포함되지 않은 오브젝트를 렌더링하지 않는 기법이다
오클루전 컬링과 의미가 미세하게 다르기 때문에 주의하자
Realtime Light보다 Baked Light 사용

실시간 라이트는 매 프레임마다 조명 연산을 수행한다. 이는 CPU, GPU의 부담이 늘어나는 것을 의미한다
반면 Baked Light는 조명 정보를 Lightmap으로 미리 계산하여 텍스처에 저장하여 드로우 콜이 줄어든다
움직이지 않는 오브젝트에 Static Object 체크

Unity에서 Static 오브젝트는 아래 기능에 대해 미리 계산된 결과를 사용한다
- Batching (Static Batching 가능)
- Lightmap 적용
- Occlusion Culling
- Reflection Probe 사용
따라서 움직이지 않는 오브젝트는 반드시 Static 세팅을 해주어야 한다
Light 개수 줄이기
Mesh뿐만 아니라 Light도 Draw Call의 발생을 유발한다. 따라서 Light 개수를 줄여야 한다
그림자 품질 조절 (Shadow Quality Setting)

실시간 그림자 렌더링은 GPU 부하가 매우 큰 연산이다. 실질적인 드로우 콜 자체는 변화가 없지만 연산량 감소로 FPS 향상을 꾀할 수 있다
Reflection Probes 최소 사용

Reflection Probe는 게임 씬에 있는 오브젝트가 주변 환경을 어떻게 반영하는지를 계산하는 데 사용되는 컴포넌트다
큐브맵을 기반으로 리플렉션 이미지를 만들어, 씬의 반사광을 표현한다. 특히 Realtime Reflection Probe는 고비용이다
아틀라스(Atlas) 사용

여러 개의 텍스처를 하나의 큰 텍스처로 합치는 기법이다
일반적으로 유니티는 하나의 텍스처에 하나의 드로우 콜을 발행하기 때문에 여러 하나의 텍스처로 만들어 드로우 콜을 줄이는 기법이다
Batching Draw Call
여러 드로우 콜이 일어날 수 있는 상황을 하나의 드로우 콜로 묶어 렌더링하는 방식이다
Unity에서는 Static, Dynamic 두 가지 방식이 있다
Static Batching
움직이지 않는 게임 오브젝트를 합쳐 하나의 큰 메시로 만들어 한 번의 드로우 콜로 처리하는 방법
다만 하나의 메시로 합치는 것이기 때문에 GPU로 가져가서 렌더링하는 데 추가적인 메모리를 사용한다
또한 메시의 일부가 화면에 보여도 전체가 처리되어 GPU 부하가 커질 수 있다
Dynamic Batching
메시가 충분히 작은 경우 이 기법을 사용하면 CPU에서 메시의 정점이 변형되고, 유사한 메시가 그룹화 된다
Unity에서는 동일한 머티리얼을 사용하고, 특정 조건을 만족하는 오브젝트들에 대하여 자동 배칭이 이루어지기도 한다
GPU Instancing

동일한 메시를 사용하는 다수의 오브젝트를 하나의 드로우 콜로 처리할 수 있도록 하는 기술이다
Unity URP에서 제공하는 Standard Shader들은 기본적으로 기능을 제공한다
배칭과 유사하게 한 번의 드로우 콜로 여러 오브젝트를 한번에 처리하는 개념이지만, 인스턴싱은 동일한 메시의 복사본을 만들지 않아 런타임 오버헤드를 줄여준다
마무리
드로우 콜은 GPU 렌더링의 핵심 과정이며, 최적화는 퍼포먼스 확보에 필수적이다
게임의 타겟 플랫폼에 따라 드로우 콜 수를 고려해 설계하고, 배칭, 인스턴싱, 컬링, 조명 처리 등 다양한 기법을 상황에 맞게 적용해보자
Reference
게임 아티스트를 위한 CG 최적화 이론: 드로우 콜 - Youtube
Introduction to optimizing draw calls - Unity Doc
Static GameObjects - Unity Doc
Troubleshooting shadows - Unity Doc
Introduction to batching draw calls - Unity Doc
Introduction to static batching - Unity Doc
Introduction to dynamic batching
How Unity batches moving GameObjects - Unity Doc
GPU 인스턴싱(GPU instancing) - Unity Doc
'프로그래밍 > Unity' 카테고리의 다른 글
| Unity의 Scripting Backend, Mono와 IL2CPP 빌드 차이 (0) | 2025.03.24 |
|---|---|
| 렌더링 파이프라인(Rendering Pipeline) (0) | 2025.03.22 |
| UniRx에 대해 (0) | 2025.03.20 |
| 유니티 가비지 컬렉터와 .NET 가비지 컬렉터의 차이 (0) | 2025.03.20 |
| Unity FixedUpdate (0) | 2025.03.12 |