유니티 모바일 게임 최적화 프로파일러와 드로우 콜 배칭으로 프레임 드랍 막는 15년차 실전 노하우
- 공유 링크 만들기
- X
- 이메일
- 기타 앱
유니티 모바일 게임 최적화 프로파일러와 드로우 콜 배칭으로 프레임 드랍 막는 15년차 실전 노하우
안녕하세요. 15년 차 게임 서버 및 클라이언트 개발자이자, 서점에서 종종 보셨을 기술 서적의 저자입니다. 오늘은 제 주력 분야 중 하나인 유니티(Unity) 모바일 최적화에 대해 이야기해보려 합니다.
사실 최적화라는 주제는 개발자에게 있어 '애증'의 관계와도 같습니다. 게임을 기획하고 기능을 구현할 때는 창의적인 즐거움에 빠져 정신이 없지만, 막상 출시를 앞두고 알파 테스트 빌드를 저사양 보급형 폰(갤럭시 A 시리즈나 구형 아이폰 등)에 올렸을 때 뚝뚝 끊기는 화면을 보면 등골이 서늘해지고 식은땀이 흐르죠. 저도 신입 시절, 화려한 파티클과 포스트 프로세싱으로 무장한 액션 RPG를 만들었다가 갤럭시 S3에서 프레임이 5까지 떨어지는 참사를 겪고, 3일 밤을 새워 텍스처를 1/4로 깎고 쉐이더를 걷어냈던 뼈아픈 기억이 있습니다.
많은 주니어 개발자분들이 "요즘 폰 성능 좋은데, 그냥 좋은 폰 쓰면 되는 거 아니에요?"라고 묻곤 합니다. 하지만 한국 시장만 볼 것이 아니라면, 글로벌 시장, 특히 동남아나 남미 시장까지 고려했을 때 최적화는 선택이 아니라 생존의 문제입니다. 매출의 상당 부분은 중저가형 기기를 사용하는 유저들에게서 나오기 때문입니다. 오늘은 그중에서도 가장 기본이자 핵심인 프로파일러 활용법과 드로우 콜(Draw Call) 배칭을 통해 프레임 드랍을 막는 실전 노하우를 아주 깊이 있게, 그리고 뼛속까지 파헤쳐 보겠습니다. 커피 한 잔 진하게 준비하시고, 시작해볼까요? ☕
1. 모바일 프레임 예산과 병목(Bottleneck)의 정밀 분석
최적화를 시작하기 전에 우리가 가진 '자원'이 얼마나 되는지 철저하게 계산해볼 필요가 있습니다. 보통 모바일 게임의 목표는 30FPS(초당 30프레임) 혹은 60FPS입니다. 60FPS를 달성하려면 1초(1000ms)를 60으로 나눈 값, 즉 16.6ms 안에 모든 처리를 끝내야 합니다. 만약 30FPS가 목표라면 33.3ms의 여유가 생깁니다. 이 짧은 시간 안에 CPU는 게임 로직을 돌리고, 물리 연산을 하고, AI를 처리한 뒤 GPU에게 "이거 그려줘"라고 명령을 보내야 합니다. 그리고 GPU는 그 명령을 받아 화면에 수백만 개의 픽셀을 찍어내야 하죠.
문제는 모바일 환경이 PC와는 차원이 다르게 가혹하다는 점입니다. PC는 거대한 쿨링 팬과 수랭 쿨러가 맹렬하게 돌아가며 열을 식혀주지만, 스마트폰은 밀폐된 작은 기계 덩어리입니다. CPU와 GPU가 열심히 일해서 열이 발생하면, 기기는 자체 보호를 위해 성능을 강제로 낮추는 '스로틀링(Throttling)'을 겁니다. 제가 겪었던 최악의 시나리오는 화려한 오프닝 씬에서 기기 온도가 5분 만에 43도를 넘어가면서, 프레임이 60에서 20으로 수직 낙하하는 경우였습니다. 따라서 우리는 단순히 16.6ms를 맞추는 것을 넘어, 칩셋이 '놀 수 있는 시간(Idle Time)'을 3~4ms 정도 확보해주어 발열을 관리해야 합니다.
병목(Bottleneck)은 크게 두 곳에서 발생합니다. CPU가 너무 많은 스크립트를 처리하거나 너무 많은 그리기 명령(Draw Call)을 보내느라 GPU를 기다리게 하는 'CPU 바운드(CPU Bound)' 상태, 그리고 CPU는 명령을 다 보냈는데 GPU가 화려한 쉐이더나 너무 많은 픽셀을 처리하느라 늦어지는 'GPU 바운드(GPU Bound)' 상태입니다. 오늘 우리가 집중할 드로우 콜 배칭은 바로 CPU 바운드를 해결하는 핵심 열쇠입니다.
| 구분 | CPU 바운드 (CPU Bound) | GPU 바운드 (GPU Bound) |
|---|---|---|
| 주요 증상 | 물리 연산 과다, 드로우 콜 폭발, 복잡한 스크립트 로직 | 해상도 과다, 무거운 쉐이더, 필라이트(Fill-rate) 문제 |
| 프로파일러 신호 | Gfx.WaitForPresent 대기 시간이 긺(GPU가 CPU를 기다림) |
Gfx.PresentFrame 혹은 렌더링 파이프라인 시간이 긺 |
| 해결 전략 | 배칭(Batching), 물리 주기 조절, 코드 최적화 | 해상도 조절(DPI), 쉐이더 경량화, 오버드로우 감소 |
| 목표 수치 (모바일) | Draw Call 200 미만, SetPass 80 미만 권장 | Overdraw 3x 미만, 버텍스 수 100k~200k 이하 |
드로우 콜(Draw Call)과 SetPass Call의 정체
드로우 콜이란 쉽게 말해 CPU가 GPU에게 "이 모델을, 이 재질(Material)로 그려라"라고 명령하는 행위입니다. 비유를 들어보겠습니다. 여러분이 화가(GPU)에게 그림을 그리라고 시키는 조수(CPU)라고 가정해봅시다. 조수가 "빨간 붓으로 사과 그려"라고 말하면 화가는 붓을 씻고, 빨간 물감을 묻혀 사과를 그립니다. 그다음 "파란 붓으로 하늘 그려"라고 하면 또 붓을 씻고 파란 물감을 묻혀야 하죠. 이 '붓을 씻고 물감을 바꾸는 과정'이 바로 상태 변경(Render State Change)이며, 유니티에서는 이를 SetPass Call이라고 부릅니다.
초보 개발자분들이 흔히 하는 착각 중 하나가 "폴리곤이 많으면 느려진다"는 것입니다. 물론 아주 틀린 말은 아니지만, 현대의 GPU는 수만 개의 폴리곤을 그리는 것보다, 재질(Material)을 한 번 바꾸는 것을 더 힘들어합니다. 예를 들어, 100개의 나무가 있는데 이 나무들이 모두 다른 텍스처와 재질을 사용한다면 CPU는 100번의 드로우 콜과 100번의 SetPass Call을 발생시
💬 여러분의 경험을 들려주세요!
✨ 이 방법을 시도해보셨나요? 댓글로 공유해주세요!
📌 도움이 되셨다면 저장하고 주변에도 알려주세요.
🔔 더 많은 개발 팁을 받고 싶다면 구독해주세요!
이 글이 도움되셨나요? 공유해주세요!
아래 링크를 통해 구매 시 운영자에게 일정 수수료가 발생할 수 있습니다.
'유니티(Unity) 모바일 게임 최적화를 위해 프로파일러(Profiler)로 병목 구간을 찾고 드로우 콜(Draw Call) 배칭으로 프레임 드랍 막는 법' 관련 상품을 쿠팡에서 확인해 보세요.
상품 보러가기 →- 공유 링크 만들기
- X
- 이메일
- 기타 앱
댓글
댓글 쓰기