숏컷 코드
같은 mesh/material을 많이 그린다
-> batching / instancing 가능성 확인
겹쳐 그리는 픽셀이 많다
-> overdraw 확인문법과 예시
draw call 숫자 자체보다 CPU-GPU 사이의 상태 변경 비용이 진짜 병목이다
draw call은 CPU가 GPU에 "이 geometry를 그려라"고 전달하는 명령 단위입니다. 숫자가 많으면 CPU 제출(submission) 비용이 커지지만, 단순히 숫자만으로 성능을 단정할 수 없습니다. 실제 비용은 draw call 사이에 발생하는 render state 변경 횟수에 크게 달려 있습니다. 다른 material, 다른 texture, 다른 shader로 전환할 때마다 GPU는 상태를 재설정해야 하고, 이 비용이 draw call 수보다 훨씬 클 수 있습니다. 같은 draw call 수라도 material 종류가 적으면 실제 비용은 훨씬 낮습니다.
// 나쁜 패턴: 100개 오브젝트, 100개 다른 material
draw call 100개, state change 100회
// 좋은 패턴: 100개 오브젝트, 같은 material
draw call 100개지만 state change 1회 -> batching 가능batching과 instancing은 목적은 같지만 작동 방식이 다르다
batching은 여러 메시의 정점 데이터를 하나로 합쳐 단일 draw call로 만드는 방식입니다. static batching은 씬 빌드 시점에 합치고, dynamic batching은 런타임에 조건을 만족할 때 합칩니다. instancing은 mesh와 material은 동일하게 유지하면서 위치, 색, 스케일 같은 per-instance 데이터만 한 번에 GPU에 보내 반복 렌더링을 최적화합니다. 나무, 바위, 파티클처럼 같은 모양이 많이 배치되는 경우 instancing이 적합합니다. batching은 다양한 메시를 합칠 수 있지만 정점 수 제한, UV/lightmap 충돌, dynamic object 처리 제약이 있습니다.
// instancing이 적합한 상황
forest: 나무 메시 1종, 배치 위치 1000개
-> GPU instancing -> draw call 1~수개
// static batching이 적합한 상황
환경 소품들이 씬에 고정 배치, material 동일
-> 빌드 시 합쳐서 단일 draw calloverdraw는 GPU fragment cost의 숨겨진 주범이다
overdraw는 같은 픽셀을 여러 번 덮어 그리는 현상입니다. 투명 파티클, 반투명 UI 레이어, 풀숲(foliage), 후처리(post-processing) 패스가 겹치는 경우 GPU가 같은 픽셀에 대해 fragment shader를 수십 번 실행할 수 있습니다. 이는 draw call 수와 무관하게 GPU fragment 파이프라인을 포화시킵니다. 특히 모바일처럼 fill rate가 제한된 GPU에서는 overdraw 2~3배만 되어도 심각한 성능 저하가 생깁니다. early-z rejection, 불투명 오브젝트 앞에서부터 뒤로 그리기(front-to-back), 파티클 수 제한, UI 레이어 최소화가 주요 해결 방향입니다.
병목이 CPU submission인지 GPU fragment인지 먼저 구분해야 한다
최적화 방향이 완전히 달라지기 때문에 CPU 병목과 GPU 병목을 먼저 분리해야 합니다. CPU가 느리다면 draw call 수 줄이기, batching, culling 강화가 도움이 됩니다. GPU가 느리다면 overdraw 줄이기, shader 복잡도 낮추기, texture memory bandwidth 최적화가 먼저입니다. 프로파일러에서 CPU frame time과 GPU frame time을 비교하는 것이 출발점입니다. draw call 숫자만 낮추는 최적화는 GPU 병목 상황에서 효과가 없습니다.
렌더링 비용을 읽을 때 핵심
| 상황 | 적합한 선택 |
|---|---|
| 같은 메시가 씬에 대량 배치됨 | GPU instancing |
| 정적 소품, 동일 material | static batching |
| 투명 오브젝트, 파티클 많음 | overdraw 분석 후 수 제한 또는 레이어 통합 |
| CPU frame time이 GPU보다 높음 | draw call / state change 줄이기 |
| GPU frame time이 CPU보다 높음 | overdraw, shader 복잡도, fill rate 최적화 |
| draw call은 적은데 모바일에서 여전히 느릴 때 | fill rate와 overdraw를 먼저 의심 |
특이 케이스와 주의할 점
흔한 실패는 draw call 숫자만 줄였는데 실제 병목은 투명 UI와 파티클 overdraw여서 성능이 그대로인 경우입니다. 반대로 material을 지나치게 합쳐 state 관리가 꼬일 수도 있습니다. 최적화 전에 CPU submission 병목인지, GPU fragment 병목인지부터 분리하세요.
참고 링크
3 sources