안 보이는 픽셀을 몇 번 칠하고 있나
드로우 콜도 줄였고 SetPass Call 도 낮습니다. 라이트도 정리했습니다. 그런데 저사양 기기에서 여전히 느립니다.
같은 픽셀을 여러 번 칠하고 있어서 그럴 수 있습니다.
오버드로우
3D 에서는 앞에 있는 불투명 오브젝트가 뒤를 가려 주면 뒤쪽 픽셀을 안 칠합니다. 깊이 테스트가 걸러 주기 때문입니다.
2D 는 그게 잘 안 됩니다. 스프라이트는 대개 반투명으로 그려지고, 반투명은 뒤에 있는 색과 섞여야 하니까 뒤쪽도 반드시 칠해야 합니다. 그래서 겹친 층 수가 그대로 곱해집니다.
얼마나 되는지
층 수가 그대로 배수 입니다. 여기가 요점입니다. 스프라이트를 아무리 아틀라스로 합치고 드로우 콜을 줄여도 이 곱셈은 안 줄어듭니다. 칠하는 픽셀 수는 CPU 가 명령을 몇 번 보내느냐와 무관합니다.
어떻게 보나
Scene View 의 Draw Mode 를 Overdraw 로 바꾸면 겹친 만큼 밝아지는 화면이 나옵니다. 새하얗게 뜨는 자리가 범인입니다. 에디터에서 바로 되고 설정도 필요 없습니다.
숫자로 재려면 모바일 GPU 프로파일러가 필요합니다. Android 는 Android GPU Inspector 나 Arm Performance Studio, iOS 는 Xcode 의 GPU 프레임 캡처입니다. Unity 프로파일러의 GPU 항목은 에디터에서 0 으로 나오는 경우가 많아서 실기 빌드에 붙여야 의미가 있습니다.
줄이는 방법
하나. 풀스크린 반투명을 센다. 화면 전체를 덮는 반투명 한 장은 그 자체로 오버드로우 1회입니다. 안개, 비네트, 딤, 색보정 오버레이가 각각 한 장씩입니다. 넷이 겹쳐 있으면 배경을 안 그려도 이미 4겹입니다. 셋 이상 쌓이면 셰이더 하나로 합치는 것을 봅니다.
둘. 스프라이트 메시를 타이트하게. 스프라이트 임포터의 Mesh Type 을 Tight 로 두면 사각형이 아니라 알파를 따라 잘라 낸 다각형으로 그립니다. 투명한 여백을 안 칠하게 됩니다. 나뭇가지나 이펙트처럼 알파 여백이 큰 스프라이트에서 효과가 큽니다. 대신 정점이 늘어서 다이나믹 배칭 쪽에는 불리합니다. GPU 가 병목이면 Tight, CPU 가 병목이면 Full Rect 입니다.
셋. 안 보이는 것을 끈다.
카메라 밖의 레이어, 메뉴 뒤에 가려진 게임 화면, 꺼야 하는데 알파만 0으로 둔 오브젝트.
알파 0 은 그리기를 건너뛰지 않습니다. 여전히 칠합니다.
정말 안 보여야 하면 SetActive(false) 나 렌더러를 끄는 쪽입니다.
넷. Render Scale 을 낮춘다. 칠할 픽셀 수 자체를 줄이는 가장 직접적인 방법입니다. 0.8 로만 낮춰도 픽셀 수가 36퍼센트 줄어듭니다. 2D 는 선이 뭉개지면 티가 나므로 픽셀 아트라면 조심해야 하지만, 그림체가 부드러운 게임이면 저사양 기기에서 쓸 만한 카드입니다.
이건 CPU 문제가 아니다
정리하면 오버드로우는 앞의 글들과 축이 다릅니다.
| 배칭, 아틀라스 | 오버드로우 | |
|---|---|---|
| 무엇이 비싼가 | CPU 가 명령을 만드는 시간 | GPU 가 픽셀을 칠하는 시간 |
| 무엇에 비례하나 | 상태 변경 횟수 | 픽셀 수 × 겹친 층 수 |
| 해상도를 낮추면 | 안 변합니다 | 그만큼 줄어듭니다 |
그래서 진단 순서가 중요합니다. 해상도를 반으로 낮췄을 때 프레임이 확 좋아지면 GPU 문제 이고, 그대로면 CPU 문제입니다. 이 실험 하나로 어디를 봐야 할지가 정해집니다.