Unity에서 화면을 렌더링할 때 성능을 떨어뜨리는 대표적인 원인 중 하나가 오버드로우다.
오버드로우는 특히 반투명 스프라이트, 파티클, 복잡한 UI, 포스트 프로세싱이 많은 장면에서 자주 발생한다.
오버드로우가 심해지면 GPU가 실제 화면에 보이는 픽셀 수보다 훨씬 많은 픽셀을 반복해서 처리하게 된다.
이러한 상태가 지속되면 GPU 처리 시간이 증가하고, 결국 GPU Bound 현상으로 이어질 수 있다.
이번 글에서는 오버드로우가 무엇인지, 왜 발생하는지, Unity의 배치 처리와는 어떤 관계가 있는지, 그리고 어떤 방법으로 최적화할 수 있는지 정리해보았다.
오버드로우란 무엇인가
오버드로우는 한 프레임을 렌더링하는 과정에서 동일한 화면 픽셀이 두 번 이상 그려지는 현상이다.
예를 들어 화면의 특정 픽셀에 배경이 먼저 그려지고, 그 위에 캐릭터가 그려지고, 다시 그 위에 반투명 이펙트가 그려졌다면 해당 픽셀은 여러 번 처리된 것이다.
최종적으로 화면에 표시되는 색상은 하나지만, GPU는 그 색상을 만들기 위해 여러 번의 픽셀 연산을 수행하게 된다.
특히 투명하거나 반투명한 오브젝트에서 오버드로우가 자주 발생한다.
불투명 오브젝트는 깊이 테스트를 통해 뒤쪽의 픽셀 처리를 줄일 수 있다.
하지만 반투명 오브젝트는 뒤에 있는 화면과 색상을 섞어야 하기 때문에 뒤쪽 오브젝트를 먼저 그린 뒤, 그 위에 반투명 오브젝트를 다시 그려야 한다.
즉, 반투명 오브젝트가 화면에 겹쳐질수록 같은 픽셀을 반복해서 처리할 가능성이 높아진다.
과거에 알파 텍스처가 적용된 오브젝트를 약 3만 개 정도 씬에 배치한 적이 있었다.
게임 로직을 거의 실행하지 않았음에도 장면 성능이 급격히 저하되었다.
오브젝트 수 자체도 문제였지만, 많은 알파 텍스처가 화면에서 서로 겹치면서 매우 높은 오버드로우가 발생한 것이 주요 원인이었다.
포스트 프로세싱도 오버드로우와 유사한 형태의 픽셀 비용을 발생시킨다.
색보정과 같은 비교적 단순한 효과도 화면 전체를 대상으로 처리되기 때문에, 최소한 화면의 모든 픽셀에 한 번 이상의 추가 연산이 발생한다.
여러 개의 후처리 효과를 순차적으로 적용하면 전체 화면을 여러 번 다시 처리하게 될 수 있다.
오버드로우가 발생하는 대표적인 원인
Unity에서 오버드로우를 발생시키는 대표적인 요소는 다음과 같다.
- 반투명 스프라이트
- 파티클 시스템
- 화면 전체를 덮는 UI 이미지
- 여러 단계로 겹쳐진 UI 패널
- 투명 영역이 큰 스프라이트
- 반투명 머티리얼
- 화면 전체에 적용되는 포스트 프로세싱
- 서로 겹치는 데칼과 이펙트
- 넓은 영역을 차지하는 투명 셰이더
이 중에서도 파티클과 UI는 실제 프로젝트에서 오버드로우를 발생시키는 경우가 많다.
파티클은 하나의 작은 효과처럼 보이더라도 실제로는 여러 개의 투명 사각형이 겹쳐서 표현되는 경우가 많다.
UI 역시 화면을 기준으로 여러 이미지가 겹치는 구조이기 때문에 계층이 복잡해질수록 동일한 픽셀이 반복해서 그려질 수 있다.
오버드로우의 문제점
한 픽셀을 여러 번 그린다는 것은 GPU가 최종 화면에 보이는 픽셀 수보다 더 많은 픽셀을 처리한다는 의미다.
예를 들어 해상도가 1920×1080이라면 화면에는 약 207만 개의 픽셀이 존재한다.
모든 픽셀이 한 번씩만 그려진다면 약 207만 개의 픽셀 처리가 필요하다.
하지만 평균적으로 각 픽셀이 4번씩 그려진다면 GPU는 약 829만 개에 가까운 픽셀 연산을 수행하게 된다.
여기에 복잡한 프래그먼트 셰이더, 조명 계산, 텍스처 샘플링, 블렌딩이 포함되면 실제 비용은 더욱 증가할 수 있다.
CPU와 GPU의 렌더링 처리 과정
화면을 렌더링할 때 CPU와 GPU는 서로 다른 역할을 담당한다.
CPU에서는 주로 다음과 같은 작업이 수행된다.
게임 로직 실행
→ 카메라 기준 오브젝트 선별
→ 렌더링 순서 정렬
→ 드로우 콜 생성
→ GPU 명령 큐에 전달
GPU에서는 전달받은 렌더링 명령을 이용해 다음과 같은 과정을 수행한다.
버텍스 데이터 읽기
→ 버텍스 셰이더 실행
→ 삼각형 조립
→ 클리핑과 컬링
→ 래스터라이제이션
→ 보간
→ 프래그먼트 셰이더 실행
→ 깊이 테스트
→ 블렌딩
→ 렌더 타깃 저장
→ 포스트 프로세싱
→ 화면 표시
오버드로우와 직접적인 관련이 큰 부분은 프래그먼트 셰이더, 깊이 테스트, 블렌딩, 렌더 타깃 저장 과정이다.
같은 픽셀이 여러 번 그려지면 이 과정이 반복해서 수행된다.
특히 투명 오브젝트는 블렌딩이 필요하기 때문에 단순히 픽셀을 덮어쓰는 것이 아니라, 기존에 그려진 색상과 새로 그릴 색상을 조합해야 한다.
따라서 투명 오브젝트가 많이 겹치는 장면에서는 GPU의 픽셀 처리 비용이 빠르게 증가할 수 있다.
이러한 상태에서 GPU가 한 프레임을 처리하는 시간이 CPU보다 길어지면 GPU Bound 상태가 된다.
불투명 오브젝트와 투명 오브젝트의 차이
불투명 오브젝트는 일반적으로 깊이 버퍼를 사용한다.
앞쪽에 있는 오브젝트가 먼저 깊이 값을 기록하면, 뒤쪽에 있는 픽셀은 깊이 테스트에서 제거될 수 있다.
이 과정 덕분에 보이지 않는 픽셀에 대해 불필요한 프래그먼트 연산을 줄일 수 있다.
반면 투명 오브젝트는 상황이 다르다.
투명 오브젝트는 뒤쪽에 있는 색상과 현재 오브젝트의 색상을 혼합해야 한다.
따라서 일반적으로 뒤쪽 오브젝트를 먼저 그리고 앞쪽의 투명 오브젝트를 나중에 그리는 방식으로 처리된다.
예를 들어 다음과 같은 순서로 그려질 수 있다.
배경
→ 불투명 오브젝트
→ 반투명 파티클
→ 반투명 UI
→ 포스트 프로세싱
이 경우 화면의 특정 픽셀은 배경, 오브젝트, 파티클, UI, 후처리 단계에서 여러 번 처리될 수 있다.
Unity에서 오버드로우 확인하기
Unity에서는 Scene View의 렌더링 디버그 모드를 이용해 오버드로우를 확인할 수 있다.
Unity 버전과 렌더 파이프라인에 따라 메뉴 이름은 다를 수 있지만, Scene View의 Draw Mode 또는 Rendering Debugger에서 Overdraw 관련 모드를 선택할 수 있다.
오버드로우 모드에서는 동일한 픽셀이 많이 그려질수록 더 밝게 표시된다.
대략적으로 다음과 같이 해석할 수 있다.
어두운 영역
→ 픽셀이 적은 횟수로 그려짐
밝은 영역
→ 동일한 픽셀이 여러 번 그려짐
매우 밝거나 흰 영역
→ 오버드로우가 매우 높음
다만 오버드로우 시각화 결과만으로 실제 성능 문제를 단정해서는 안 된다.
오버드로우가 높아도 셰이더가 매우 단순하다면 비용이 크지 않을 수 있다.
반대로 오버드로우가 비교적 낮더라도 프래그먼트 셰이더가 복잡하다면 높은 GPU 비용이 발생할 수 있다.
따라서 최종적으로는 GPU Profiler, Frame Debugger, RenderDoc 등의 도구를 함께 사용하는 것이 좋다.
Unity 배치 처리와 오버드로우
배치 처리는 여러 개의 렌더링 작업을 묶어 드로우 콜 수를 줄이는 기법이다.
Unity에서는 다음과 같은 방식으로 배치 처리가 이루어질 수 있다.
- Static Batching
- Dynamic Batching
- GPU Instancing
- SRP Batcher
- Canvas Batching
배치 처리는 CPU가 GPU에 전달하는 드로우 콜 수를 줄이는 데 효과적이다.
하지만 드로우 콜 수를 줄이는 것과 오버드로우를 줄이는 것은 서로 다른 최적화 문제다.
배치가 잘 이루어져 드로우 콜 수가 줄어들더라도, 화면에서 많은 오브젝트가 겹쳐 있다면 오버드로우는 그대로 발생할 수 있다.
경우에 따라서는 배치로 인해 렌더링 순서를 세밀하게 조정하기 어려워져 오버드로우가 증가할 수도 있다.
여러 오브젝트가 하나의 배치로 묶이면 Unity가 각 오브젝트를 개별적으로 정렬하거나 드로우 순서를 변경하기 어려워질 수 있다.
특히 투명 오브젝트나 정렬이 중요한 구조에서는 배치 결과에 따라 화면에 그려지는 순서가 달라질 수 있다.
예를 들어 맵에 동일한 오브젝트를 여러 개 배치하고 오버드로우를 확인하면, 오브젝트가 배치로 묶였을 때와 개별적으로 렌더링될 때 오버드로우 결과가 다르게 나타나는 경우가 있다.
이는 배치 자체가 항상 문제라는 의미는 아니다.
배치로 줄어드는 CPU 비용과 렌더링 순서 변화로 발생하는 GPU 비용을 함께 비교해야 한다.
아래 사진은 160개의 쿼드를 겹쳐서 만들고 해당 쿼드를 Batch로 묶었을때와 묶지 않았을때를 비교한 모습이다.

1번의 경우에는 Render Opaques 아래에 Draw Mesh가 여러개 보입니다. 이상태에서는 Unity가 Renderer 단위로 정렬할 수 있다.

2번의 경우에는 Draw Mesh가 한개뿐입니다. 여기서는 Unity가 내부 쿼드 순서를 다시 정렬할 수 없다.
배치를 해제하면 항상 해결되는가
오버드로우 문제가 있는 오브젝트의 배치를 비활성화하면 렌더 순서를 더 세밀하게 제어할 수 있다.
이로 인해 앞쪽의 불투명 오브젝트가 먼저 그려지고, 뒤쪽의 픽셀이 깊이 테스트에서 제거되도록 만들 수 있다.
하지만 배치를 무조건 해제하는 것은 좋은 해결 방법이 아니다.
배치를 해제하면 드로우 콜이 증가하고 CPU 렌더링 비용이 커질 수 있다.
즉, 다음과 같은 교환 관계가 발생한다.
배치 사용
→ 드로우 콜 감소
→ CPU 비용 감소 가능
→ 렌더 순서 제어 제한 가능
배치 해제
→ 렌더 순서 제어 가능
→ 오버드로우 감소 가능
→ 드로우 콜 증가
→ CPU 비용 증가 가능
따라서 배치 사용 여부는 CPU와 GPU 프로파일링 결과를 함께 확인한 뒤 결정해야 한다.
Render Queue를 이용한 렌더 순서 조정
Unity 머티리얼은 Render Queue 값을 기준으로 렌더링 순서를 결정할 수 있다.
대표적인 큐 값은 다음과 같다.
Background : 1000
Geometry : 2000
AlphaTest : 2450
Transparent : 3000
Overlay : 4000
불투명 오브젝트는 일반적으로 Geometry 영역에서 렌더링된다.
투명 오브젝트는 Transparent 영역에서 렌더링된다.
특정 오브젝트가 너무 늦게 그려지거나, 불필요하게 많은 픽셀을 덮어쓰는 경우 Render Queue를 조정해 렌더 순서를 변경할 수 있다.
예를 들어 머티리얼의 렌더 큐를 코드에서 변경할 수 있다.
Renderer targetRenderer = GetComponent<Renderer>();
if (targetRenderer != null)
{
targetRenderer.material.renderQueue = 2001;
}
다만 Render Queue를 변경할 때는 투명도 정렬, 깊이 버퍼, 블렌딩 결과가 달라질 수 있다.
특히 투명 머티리얼의 Render Queue를 불투명 영역으로 강제로 이동하면 기대한 투명 결과가 나오지 않을 수 있다.
따라서 Render Queue는 오브젝트의 셰이더 설정과 깊이 기록 여부를 함께 확인한 뒤 조정해야 한다.
오버드로우 최적화 방법
1. 투명 오브젝트 사용 줄이기
투명 오브젝트는 뒤쪽 화면과 블렌딩해야 하므로 오버드로우 비용이 크다.
가능한 경우 투명 머티리얼 대신 불투명 머티리얼이나 알파 클리핑 방식을 고려할 수 있다.
다음과 같은 오브젝트를 우선적으로 확인하는 것이 좋다.
- 반투명 바닥
- 투명한 장식 오브젝트
- 중첩된 유리 표현
- 넓은 범위를 덮는 투명 이펙트
- 화면 전체 크기의 반투명 UI
투명 표현이 반드시 필요하지 않다면 불투명 방식으로 교체하는 것이 가장 확실한 최적화 방법이다.
2. 파티클 크기와 개수 줄이기
파티클은 오버드로우를 발생시키는 대표적인 요소다.
파티클 하나는 일반적으로 카메라를 바라보는 사각형 형태로 렌더링된다.
파티클 이미지에서 실제로 보이는 영역이 작더라도 사각형 전체가 픽셀 처리 대상이 될 수 있다.
파티클을 최적화할 때는 다음 항목을 확인할 수 있다.
- 최대 파티클 개수
- 파티클 크기
- 파티클 수명
- 생성 빈도
- 파티클의 화면 점유 면적
- 동시에 겹치는 파티클 수
- 텍스처의 투명 영역
- 셰이더의 복잡도
큰 파티클 여러 개가 화면 중앙에서 겹치는 효과는 적은 개수라도 높은 오버드로우를 발생시킬 수 있다.
반대로 작은 파티클은 개수가 많더라도 실제 화면 점유 면적이 작다면 비용이 상대적으로 낮을 수 있다.
따라서 단순히 파티클 개수만 줄이기보다 화면에서 차지하는 픽셀 면적을 함께 확인해야 한다.
3. UI 계층 정리하기
Unity UI는 여러 이미지가 겹치는 구조로 만들어지는 경우가 많다.
예를 들어 하나의 팝업 UI가 다음과 같이 구성될 수 있다.
전체 화면 반투명 배경
→ 팝업 배경 이미지
→ 장식 이미지
→ 버튼 배경
→ 버튼 아이콘
→ 텍스트
이 구조가 여러 개 겹치면 같은 화면 픽셀이 반복해서 그려진다.
UI 최적화를 위해서는 다음 항목을 확인할 수 있다.
- 보이지 않는 UI 오브젝트 비활성화
- 알파 값만 0으로 설정된 오브젝트 제거
- 불필요한 전체 화면 이미지 제거
- 중복된 배경 이미지 통합
- Mask와 RectMask2D 사용 범위 점검
- 복잡한 UI 계층 단순화
- 여러 Canvas의 사용 목적 분리
- 화면 밖 UI 비활성화
알파 값을 0으로 설정했다고 해서 항상 렌더링 비용이 사라지는 것은 아니다.
오브젝트가 활성화되어 있고 렌더링 대상에 포함되어 있다면 불필요한 처리 비용이 발생할 수 있다.
보이지 않는 UI는 가능하면 GameObject를 비활성화하거나 CanvasRenderer의 컬링 상태를 확인하는 것이 좋다.
4. 스프라이트의 투명 영역 줄이기
스프라이트 텍스처에 투명한 여백이 많으면 실제로 보이는 이미지보다 더 넓은 영역이 렌더링될 수 있다.
예를 들어 작은 원형 이펙트가 1024×1024 텍스처 중앙에만 존재하고 나머지 영역이 모두 투명하다면, 화면에서는 거의 보이지 않는 영역까지 큰 사각형으로 렌더링될 수 있다.
이 문제를 줄이기 위해 다음 방법을 사용할 수 있다.
- 스프라이트 투명 여백 제거
- Sprite Editor에서 메시 타입 조정
- Tight Mesh 사용 검토
- 파티클 텍스처 크롭
- 여러 작은 이미지를 아틀라스로 정리
- 실제 보이는 영역에 가까운 메시 사용
다만 Tight Mesh는 버텍스 수를 증가시킬 수 있다.
버텍스 비용과 픽셀 비용 중 어느 쪽이 더 큰지 확인한 뒤 적용하는 것이 좋다.
모바일 환경이나 투명 스프라이트가 큰 화면 영역을 차지하는 경우에는 Tight Mesh가 효과적일 수 있다.
5. 포스트 프로세싱 효과 조절하기
포스트 프로세싱은 화면 전체를 대상으로 수행되는 경우가 많다.
따라서 효과 하나를 추가할 때마다 화면 전체 픽셀을 다시 처리할 수 있다.
대표적인 후처리 효과는 다음과 같다.
- Bloom
- Color Grading
- Depth of Field
- Motion Blur
- Vignette
- Chromatic Aberration
- Screen Space Ambient Occlusion
- Full Screen Blur
간단해 보이는 효과도 전체 화면에 적용되기 때문에 해상도가 높을수록 비용이 증가한다.
특히 여러 효과를 동시에 사용하면 중간 렌더 텍스처 생성과 전체 화면 패스가 반복될 수 있다.
모바일이나 저사양 디바이스에서는 필요하지 않은 효과를 비활성화하고 품질 옵션에 따라 효과 단계를 조절하는 것이 좋다.
6. 렌더링 순서와 레이어 구조 점검하기
불투명 오브젝트는 앞쪽 오브젝트를 먼저 렌더링할수록 뒤쪽 픽셀이 깊이 테스트에서 제거될 가능성이 높아진다.
Unity는 일반적으로 불투명 오브젝트를 앞에서 뒤 방향으로 정렬해 오버드로우를 줄이려고 한다.
반면 투명 오브젝트는 블렌딩 결과를 위해 뒤에서 앞 방향으로 정렬되는 경우가 많다.
렌더링 순서가 잘못 설정되어 있으면 불필요한 픽셀 처리가 증가할 수 있다.
다음 항목을 확인해볼 수 있다.
- Material Render Queue
- Sorting Layer
- Order in Layer
- Canvas Sorting Order
- 카메라 Depth
- Renderer Priority
- 투명 오브젝트의 정렬 축
- 불필요한 Overlay 렌더링
렌더링 순서를 변경할 때는 화면 결과가 달라지지 않는지도 함께 확인해야 한다.
오버드로우는 줄었지만 투명 오브젝트의 앞뒤 관계가 잘못 표시된다면 올바른 최적화라고 보기 어렵다.
7. 포스트 프로세싱을 저해상도에서 처리하기
블러, Bloom, 왜곡 효과처럼 픽셀 단위 계산이 많은 후처리는 저해상도 렌더 텍스처에서 처리하면 비용을 크게 줄일 수 있다.
예를 들어 원본 화면이 1920×1080인 경우 절반 해상도는 960×540이다.
가로와 세로가 각각 절반이 되면 전체 픽셀 수는 약 4분의 1로 감소한다.
1920 × 1080 = 2,073,600 픽셀
960 × 540 = 518,400 픽셀
동일한 셰이더를 실행하더라도 처리해야 하는 픽셀 수가 크게 줄어든다.
저해상도 처리 방식은 다음과 같다.
원본 화면 렌더링
→ 저해상도 렌더 텍스처로 다운샘플링
→ 저해상도에서 효과 처리
→ 원본 해상도로 업샘플링
→ 최종 화면과 합성
다만 해상도를 지나치게 낮추면 블러 경계가 깨지거나 이미지가 흐릿해질 수 있다.
효과의 특성과 목표 디바이스에 따라 적절한 해상도를 선택해야 한다.
8. LOD와 거리 컬링 적용하기
멀리 있는 오브젝트는 화면에서 차지하는 크기가 작다.
하지만 투명 파티클이나 복잡한 머티리얼을 그대로 유지하면 거리에 비해 높은 렌더링 비용이 발생할 수 있다.
거리 기반 최적화 방법으로는 다음과 같은 방식을 사용할 수 있다.
- LOD Group 적용
- 일정 거리 이상 파티클 비활성화
- 작은 이펙트 제거
- 셰이더 단순화
- 그림자 비활성화
- 카메라별 Culling Mask 분리
- Occlusion Culling 적용
- 거리 기반 투명도 대신 즉시 비활성화 검토
투명도를 서서히 낮추는 방식은 시각적으로 자연스럽지만, 완전히 사라지기 전까지 계속 렌더링 비용이 발생한다.
성능이 중요한 상황에서는 특정 거리에서 오브젝트를 완전히 비활성화하는 방식이 더 효과적일 수 있다.
알파 블렌딩과 알파 클리핑 비교
투명 표현에는 주로 알파 블렌딩과 알파 클리핑 방식이 사용된다.
알파 블렌딩은 현재 픽셀과 배경 픽셀을 섞어 부드러운 투명 표현을 만든다.
최종 색상 = 현재 색상 × 알파 + 배경 색상 × (1 - 알파)
부드러운 투명 표현이 가능하지만, 블렌딩과 정렬이 필요하고 오버드로우 비용이 크다.
알파 클리핑은 특정 알파 값보다 낮은 픽셀을 완전히 제거한다.
clip(alpha - cutoff);
알파 클리핑은 반투명 표현은 어렵지만, 나뭇잎, 철망, 울타리처럼 보이거나 보이지 않는 형태가 명확한 오브젝트에 적합하다.
깊이 기록을 사용할 수 있기 때문에 상황에 따라 알파 블렌딩보다 오버드로우를 줄이는 데 도움이 될 수 있다.
다만 알파 클리핑도 프래그먼트 셰이더 실행 이후 픽셀이 제거될 수 있으므로 비용이 완전히 사라지는 것은 아니다.
또한 경계가 거칠게 보이거나 안티앨리어싱 문제가 발생할 수 있다.
오버드로우와 드로우 콜은 다른 문제다
오버드로우와 드로우 콜은 모두 렌더링 성능과 관련이 있지만 서로 다른 문제다.
드로우 콜은 CPU가 GPU에 렌더링 명령을 얼마나 많이 전달하는지와 관련이 있다.
오버드로우는 GPU가 같은 화면 픽셀을 얼마나 반복해서 처리하는지와 관련이 있다.
예를 들어 다음과 같은 상황이 가능하다.
드로우 콜은 적지만 오버드로우가 높은 경우
→ 큰 투명 파티클이 하나의 배치로 많이 겹쳐 있음
드로우 콜은 많지만 오버드로우가 낮은 경우
→ 작은 불투명 오브젝트가 서로 겹치지 않고 렌더링됨
따라서 배칭으로 드로우 콜을 줄였다고 해서 반드시 GPU 성능이 좋아지는 것은 아니다.
반대로 오버드로우를 줄이기 위해 배칭을 해제하면 CPU 비용이 증가할 수 있다.
최적화할 때는 현재 병목이 CPU인지 GPU인지 먼저 확인해야 한다.
오버드로우를 측정할 때 확인해야 할 항목
오버드로우를 최적화할 때는 단순히 Scene View의 색상만 확인하기보다 여러 도구를 함께 사용하는 것이 좋다.
Unity Profiler
Unity Profiler에서는 다음 항목을 확인할 수 있다.
- CPU 렌더링 시간
- GPU 렌더링 시간
- Batches
- SetPass Calls
- Triangles
- Vertices
- UI 렌더링 비용
- 포스트 프로세싱 비용
GPU 시간이 높고, 투명 오브젝트나 파티클이 많은 장면에서 성능이 떨어진다면 오버드로우를 의심할 수 있다.
Frame Debugger
Frame Debugger를 사용하면 한 프레임이 어떤 순서로 그려지는지 확인할 수 있다.
이를 통해 다음 내용을 확인할 수 있다.
- 어떤 오브젝트가 먼저 그려지는지
- 특정 오브젝트가 몇 번 렌더링되는지
- 배치가 어떻게 묶이는지
- Render Queue가 어떻게 적용되는지
- 중간 렌더 텍스처가 몇 번 생성되는지
- 포스트 프로세싱 패스가 몇 번 실행되는지
GPU Profiler와 RenderDoc
GPU Profiler나 RenderDoc을 사용하면 실제 GPU 패스별 실행 시간을 확인할 수 있다.
오버드로우가 높아 보이더라도 특정 패스의 실행 시간이 낮다면 우선순위가 낮을 수 있다.
반대로 단순한 전체 화면 효과처럼 보이더라도 실제 GPU 시간이 높게 측정된다면 우선적으로 최적화해야 한다.
플랫폼에 따라 오버드로우 비용이 달라질 수 있다
오버드로우 비용은 모든 플랫폼에서 동일하지 않다.
데스크톱 GPU는 높은 메모리 대역폭과 강력한 픽셀 처리 성능을 가지고 있어 어느 정도의 오버드로우를 감당할 수 있다.
반면 모바일 GPU는 전력과 발열, 메모리 대역폭에 제한이 있다.
특히 고해상도 모바일 디바이스에서는 작은 화면에 많은 픽셀이 존재하기 때문에 전체 화면 효과와 투명 UI의 비용이 크게 나타날 수 있다.
VR 환경에서도 오버드로우는 중요하다.
VR은 좌우 눈에 대해 화면을 각각 렌더링해야 하고 높은 프레임을 유지해야 하기 때문에 동일한 오버드로우가 일반 화면보다 더 큰 부담이 될 수 있다.
따라서 오버드로우 최적화는 다음과 같은 환경에서 특히 중요하다.
- 모바일 게임
- VR과 AR
- 고해상도 디바이스
- 파티클이 많은 게임
- UI 중심의 게임
- 저사양 GPU 지원 프로젝트
정리
오버드로우는 한 프레임에서 같은 화면 픽셀이 두 번 이상 그려지는 현상이다.
반투명 스프라이트, 파티클, 복잡한 UI, 포스트 프로세싱은 오버드로우를 발생시키는 대표적인 원인이다.
동일한 픽셀이 반복해서 그려질수록 GPU는 실제 화면에 보이는 픽셀 수보다 더 많은 프래그먼트 연산과 블렌딩을 처리해야 한다.
이로 인해 GPU 렌더링 시간이 증가하고 GPU Bound 현상으로 이어질 수 있다.
배치 처리는 드로우 콜을 줄여 CPU 비용을 낮추는 데 효과적이지만, 오버드로우를 직접 줄여주는 기능은 아니다.
경우에 따라 배치로 인해 렌더링 순서 제어가 제한되면서 오버드로우가 증가할 수도 있다.
하지만 배치를 해제하면 드로우 콜이 증가할 수 있으므로, CPU와 GPU 비용을 함께 비교해야 한다.
오버드로우를 줄이기 위해서는 투명 오브젝트 사용을 줄이고, 파티클의 크기와 개수를 조절하며, UI 계층과 투명 여백을 정리해야 한다.
포스트 프로세싱은 필요에 따라 비활성화하거나 저해상도에서 처리하는 방법을 사용할 수 있다.
또한 렌더링 순서, Render Queue, Sorting Layer, LOD, 거리 컬링을 함께 점검해야 한다.
가장 중요한 것은 단순히 화면이 밝게 보이는 영역을 줄이는 것이 아니다.
Unity Profiler, Frame Debugger, GPU Profiler를 이용해 실제 병목이 어디에서 발생하는지 확인하고, 드로우 콜과 오버드로우 사이의 균형을 맞추는 것이 중요하다.
참고자료
https://thegamedev.guru/unity-gpu-performance/overdraw-optimization/
Unity Overdraw: Improving the GPU Performance of Your Game | TheGamedev.Guru
A single thing has killed the GPU performance of thousands of mobile games: the famous Unity Overdraw. Do you know what overdraw is doing to you?
thegamedev.guru
https://thegamedev.guru/ramblings/overdraw-2d/
Is GPU Overdraw Worse in 2D Games? | TheGamedev.Guru
Are my student emails like this one justified?
thegamedev.guru
https://ronniej.sfuhost.com/unity-overdraw-optimization/
유니티 Overdraw 최적화 | GPU 성능이 떨어지는 진짜 이유
유니티 Overdraw 많으면 왜 성능이 떨어질까요? GPU Bound 상황에서 발생하는 픽셀 처리 병목과 Overdraw 최적화 방법을 실제 사례 중심으로 쉽게 정리했습니다.
ronniej.sfuhost.com
'Unity(C#)' 카테고리의 다른 글
| Unity 게임 최적화는 코드보다 데이터에서 시작하는 걸까? (0) | 2026.09.01 |
|---|---|
| Unity Mono, IL2CPP,CoreCLR 을 알아보자 (0) | 2026.07.29 |
| Unity UI OBB 충돌 검사와 Burst를 이용한 최적화 (0) | 2026.07.07 |
| Unity GC를 호출했는데 왜 메모리가 바로 줄어들지 않을까? (0) | 2026.06.19 |
| Unity Update에서 LINQ와 람다식 사용을 조심해야 하는 이유 (0) | 2026.06.16 |