| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
- Addressables
- mnist
- Serialize
- graphics
- gamedev
- 알고리즘
- 유니티
- 딥러닝
- 다익스트라
- Game Development
- 게임 물리
- game dev
- Unity #Android #Build
- 뉴럴네트워크
- C++
- c#
- 게임 수학
- unity #graphics
- Programming
- Unity
- untiy
- rendering
- 게임 개발
- C
- Today
- Total
Typing diary
SRP Batcher 본문
https://typingdiary.tistory.com/61
드로우 콜(Draw Call)
드로우 콜이란?CPU가 GPU에게 특정 오브젝트를 그리게 하기 위한 단일 명령이다. 한 프레임에 여러번 호출 될 수 있으며, 호출 수가 많아질 수록 CPU와 GPU의 오버헤드가 커지기 때문에, 호출 횟수를
typingdiary.tistory.com
앞선 글에서 드로우 콜을 다루면서 Unity의 Batch와 Set Pass Call에 대해서 간단히 설명하였다. 이번 포스팅에선 Unity에서 드로우 콜을 최적화하기 위해, Unity에서 제공하는 솔루션에 대해서 포스팅해보겠다.
| 본론에 앞서, 우리는 드로우콜 최적화에 대한 중요점을 다시 짚고 넘어갈 필요가 있다. 특히, 모바일 게임 개발을 주로 이루는 Unity에선 더욱 중요하게 다뤄야할 문제이다. 모바일 게임에서 드로우 콜이 많아지면 GPU의 렌더 상태 변경이 잦아지고, 이로 인해 메모리 대역폭 사용량이 증가하며 발열과 전력 소모가 커진다. 또한 모바일 GPU는 대역폭이 제한적이기 때문에, 드로우 콜이 많을수록 성능 저하와 프레임 드랍이 발생할 수 있다. |
SRP Batcher
SRP Batcher는 GPU가 아니라 CPU의 렌더링 오버헤드를 줄이는 역할을 한다. 기존에는 Unity가 메쉬를 그릴 때마다 Material마다 GPU에 셋업해야 할 데이터(유니폼 버퍼, 셰이더 변수 등)를 매번 준비했는데, 이것은 굉장히 비효율적이다. SRP Batcher는 이 과정을 캐싱하고 배치 처리해서, CPU가 매 프레임마다 반복해서 셰이더 데이터를 세팅하지 않도록 만들어 준다.
어떻게?
SRP Batcher의 핵심 원리는 동일한 데이터 구조를 가진 머터리얼을 하나로 묶는것이다. SRP Batcher는 정해진 데이터 구조를 GPU에 버퍼 배열로 업로드 하여, GPU메모리에 캐싱한뒤, 이를 인덱싱을 통해 빠르게 접근할 수 있도록 한다.
이제 로우레벨 렌더 루프를 통해 머티리얼 데이터를 GPU 메모리 내에 유지할 수 있습니다. 머티리얼 콘텐츠가 변경되지 않는 한, 버퍼를 설정하고 GPU에 업로드할 필요가 없습니다.
(https://unity.com/kr/blog/engine-platform/srp-batcher-speed-up-your-rendering)
SRP Batcher를 사용하기 위해선 쉐이더의 데이터 구조를 정확히 명시할 필요가 있는데, 다음과 같이 쉐이더를 작성해야 한다.
CBUFFER_START(UnityPerMaterial)
float4 _MainTex_ST;
float4 _MainColor;
CBUFFER_END
쉐이더가 SRP Batcher를 지원하는데 문제가 없다면, SRP Batcher compatible 이라고 표시되는것을 확인할 수 있다.

테스트
동일한 쉐이더를 사용하는 4가지 머터리얼을 SRP Batcher를 활성화 한 경우와 비활성화 한 경우를 비교해 보았다..
| SRP Batcher OFF | SRP Batcher ON |
![]() |
![]() |
| Batch: 5 SetPass Call: 5 |
Batch: 5 SetPass Call: 2 |
SRP Batcher를 활성화 할 시 Batch수는 동일하지만, SetPass Call이 2로 감소한 것을 볼 수 있다.
RenderDoc를 활용하면 CPU가 GPU에게 어떤 명령을 내렸는지 상세한 로그를 확인할 수 있다.

해당 이미지는 앞선 사진과 동일한 상황에서 SRPBatcher를 활성화 했을때 RenderDoc로그를 확인한 것이다.
EID 875, 878, 881, 884는 각각 오브젝트 1개를 그릴때 발생한 이벤트이고 해당 이벤트를 누르면 오브젝트를 그리기 위해 GPU에 어떤 명령을 내렸는지 볼 수 있다. 또한 EID 875, 878, 881, 884는 동일한 쉐이더를 사용하여 SRP Batcher에 의해 배칭된 상태이다.
EID 860~874는 드로우 콜 이전에, 렌더링을 위한 데이터를 GPU에 업로드하고, RenderState를 설정하는 과정이다. Unity에선 이와 같은 명령들을 SetPass Call로 관리한다.
여기서 중요한 부분이 EID 868에 해당하는 Map( Buffer 47117, 0)명령이다. 앞서 이야기 했던 "SRP Batcher는 정해진 데이터 구조를 GPU에 버퍼 배열로 업로드 하여," 를 실제로 수행하는 부분이 바로 이 부분이다.
이제 다음 오브젝트를 그릴때 어떤 일이 발생하는 살펴보자.

EID 876을 보면 GPU 메모리에 캐싱 된 Buffer 47117를 그대로 사용하는 것을 볼 수 있다. 이는 이미 GPU에 올라간 데이터를 인덱싱하여 사용하기 때문에 SetPass Call에 해당하지 않는다. 그 이후로 발생한 EID 881, 884도 같이 배칭되었기 때문에 동일한 명령으로 처리된다.
그렇다면, SRP Batcher가 비활성화된 상황에선 어떻게 처리될까?

매 오브젝트를 그릴때 마다, Map명령어를 사용하여 CPU가 GPU버퍼에 접근하게 된다. 이는 대역폭 사용량이 증가하여 발열과 전력 소모가 커지는 원인이 된다.
정리
이처럼 SRP Batcher를 활용하면 같은 셰이더 구조를 가진 오브젝트를 효율적으로 처리할 수 있어, 불필요한 렌더 상태 설정과 데이터 복사를 줄일 수 있다.
결과적으로 CPU 오버헤드를 줄이고, 모바일 환경에서 발열, 배터리 소모, 프레임 드랍을 최소화하는 데 큰 도움이 된다.
이번 포스팅에선 SRP Batcher에 대해서만 다뤘지만, Unity에선 다양한 상황에서 최적의 드로우콜 최적화를 위해 Static Batching, Dynamic Batching, GPU Instancing등의 기능을 제공하고 있다. 각 기법이 어떤 조건에서 가장 효과적인지 이해하는 것이, 실제 프로젝트에서 성능 최적화를 적용하는 데 큰 도움이 될 것이다.
참고 링크
https://unity.com/kr/blog/engine-platform/srp-batcher-speed-up-your-rendering
'Unity' 카테고리의 다른 글
| Unity Android 빌드 시 Android SDK 라이선스 미동의 에러 (0) | 2025.11.15 |
|---|---|
| Unity Serializable Dictionary (스크립트 직렬화) (0) | 2024.09.10 |
| Unity Addressables localhost로 Remote번들 테스트하기 (0) | 2024.07.29 |


