---
title: "드로우 콜을 줄였는데 느려졌다면"
description: "드로우 콜과 SetPass Call 은 다른 것을 셉니다. 드로우 콜이 524 에서 765 로 늘었는데 오히려 빨라진 실측이 있습니다."
author: "유니얼"
pubDate: 2026-09-09
category: "game-dev/unity/rendering"
tags: ["Unity", "최적화", "Batching", "렌더링"]
canonical: https://blog.unialgames.com/posts/unity-drawcall-setpass/
---
2D 게임이 모바일에서 버벅입니다. 검색하면 첫 줄에 "드로우 콜을 줄이세요" 가 나옵니다.
Stats 창을 열어 보니 700 이 넘습니다. 이것저것 손봐서 500 으로 줄였습니다.

**그런데 더 느려졌습니다.**

이런 일이 실제로 생깁니다. 드로우 콜은 렌더링 비용을 재는 숫자가 아니기 때문입니다.
정확히는, 렌더링 비용을 재는 숫자가 **하나가 아니기** 때문입니다.

## GPU 는 상태 기계다

GPU 에게 "이 사각형을 그려라" 라고만 말하면 아무것도 안 그려집니다.
어떤 텍스처로, 어떤 셰이더로, 어떻게 섞어서, 어디에 그릴지를 전부 먼저 세팅해 줘야 합니다.
GPU 는 그렇게 세팅된 상태를 들고 있다가, 그리라고 하면 그 상태 그대로 그립니다.

<x-steps>
<script type="application/json">
{
  "steps": [
    { "tag": "1", "title": "무엇으로 그릴지 정한다", "text": "텍스처를 물리고, 셰이더와 패스를 고르고, 블렌드 모드를 정하고, 렌더 타겟을 지정합니다." },
    { "tag": "2", "title": "값을 올린다", "text": "변환 행렬과 머티리얼 상수를 GPU 로 보냅니다. 여기까지가 SetPass Call 한 번으로 세어집니다." },
    { "tag": "3", "title": "그린다", "text": "이제야 그리라고 말합니다. 이것이 드로우 콜 한 번입니다." },
    { "tag": "4", "title": "다음 오브젝트", "text": "상태가 다르면 1번부터 전부 다시 합니다. 같으면 3번만 반복하면 됩니다." }
  ]
}
</script>
</x-steps>

여기서 두 숫자가 갈립니다.

| | 무엇을 세는가 | 언제 늘어나는가 |
| --- | --- | --- |
| **드로우 콜** | "지금 그려라" 라는 명령 자체 | 그리는 덩어리가 늘어날 때 |
| **SetPass Call** | 그 앞에 붙는 **상태 변경**을 묶은 단위 | 앞 오브젝트와 상태가 다를 때 |

같은 상태로 이어서 그릴 수 있으면 드로우 콜만 늘고 SetPass Call 은 안 늡니다.
반대로 오브젝트마다 텍스처가 다르고 셰이더가 다르면 둘이 나란히 늡니다.

그리고 **실무에서 더 아픈 쪽은 대개 SetPass Call** 입니다.
1번과 2번이 CPU 가 명령을 만들어 드라이버에 넘기는 일이고, 3번은 그에 비하면 짧습니다.
모바일에서 발열의 상당 부분이 여기서 나옵니다.

## 숫자 두 개를 같이 본 실측

Unity 의 2D 데모 프로젝트인 Happy Harvest 를 Galaxy Tab S7 에서 돌리고
설정 하나만 바꿔서 잰 결과가 있습니다.

<x-compare>
<script type="application/json">
{
  "tabs": [
    { "label": "SRP Batcher 끔", "text": "여러 메시를 CPU 가 하나로 합쳐서 그리는 방식만 쓴 상태입니다.", "stats": [["Draw Calls", "524"], ["SetPass Calls", "517"]], "tone": "bad" },
    { "label": "SRP Batcher 켬", "text": "메시는 안 합칩니다. 대신 상태가 같은 드로우 콜을 이어 붙입니다.", "stats": [["Draw Calls", "765"], ["SetPass Calls", "300"]], "tone": "good" }
  ]
}
</script>
</x-compare>

드로우 콜은 **524 에서 765 로 늘었습니다.** 46퍼센트 증가입니다.
그런데 SetPass Call 은 517 에서 300 으로 떨어졌고, 총 CPU 시간은 줄었습니다.

> 드로우 콜 500 에 SetPass 500 은 재앙이고, 드로우 콜 700 에 SetPass 300 은 그보다 빠릅니다.

앞의 "드로우 콜을 줄였더니 느려졌다" 는 이 표의 화살표를 거꾸로 밟은 것입니다.
메시를 합치느라 CPU 를 더 쓰면서 드로우 콜 숫자만 예뻐진 상태입니다.

## 그래서 무엇을 봐야 하나

Stats 창에서 **두 숫자를 같이 봅니다.** 그리고 비율을 봅니다.

- SetPass 가 드로우 콜에 거의 붙어 있다 → 오브젝트마다 상태가 다르다는 뜻입니다.
  텍스처와 셰이더를 합칠 여지가 남아 있습니다
- SetPass 가 드로우 콜의 절반 이하다 → 상태가 잘 이어지고 있습니다.
  이때부터는 드로우 콜을 더 줄여도 얻는 게 적습니다
- 둘 다 낮은데 여전히 느리다 → **CPU 문제가 아닙니다.**
  픽셀을 칠하는 쪽, 즉 GPU 를 봐야 합니다

마지막 줄이 2D 에서 특히 중요합니다. 2D 는 반투명 스프라이트가 겹겹이 쌓이는 구조라
같은 픽셀을 여러 번 칠하는 일이 흔하고, 그건 드로우 콜을 아무리 줄여도 안 줄어듭니다.

## 이 시리즈가 갈 길

정리하면 프레임을 먹는 자리가 크게 둘입니다.

| | 무엇이 비싼가 | 무엇으로 줄이는가 |
| --- | --- | --- |
| **CPU** | 명령을 만들어 넘기는 시간 | 배칭, 아틀라스, 셰이더 통일 |
| **GPU** | 픽셀을 칠하는 시간 | 오버드로우 줄이기, 라이트 수, 해상도 |

이 둘을 섞어서 이야기하면 답이 안 나옵니다.
"라이트를 줄이면 배칭이 좋아진다" 같은 말이 절반만 맞는 이유가 그것입니다.
라이트 배칭은 CPU 쪽이고 라이트 버퍼와 그림자는 GPU 쪽이라, 같은 설정 하나가
두 축을 동시에 건드립니다.

그러니 무엇을 고치든 **어느 쪽 숫자가 움직였는지 확인하면서** 가야 합니다.