🚀 들어가며
이번 글에서는 GPU 렌더링 병목의 원인과 최적화 방법을 정리해보겠습니다.
- GPU Bound 상태란 무엇인지
- 필레이트(Fill Rate)
- 메모리 대역폭(Memory Bandwidth)
- 정점 프로세싱(Vertex Processing)
특히 모바일 환경에서는 아래 내용이 성능에 매우 큰 영향을 줍니다.
- 필레이트 문제
- 오버드로우
- 텍스처 메모리 사용량
🧠 렌더링과 관련없는 메인 쓰레드 작업
렌더링과 관련되지 않은 CPU 작업 역시 메인 쓰레드에서 처리된다는 점을 이해하는 것이 중요합니다.
즉, 메인 쓰레드가 CPU Bound 상태라면, 렌더링과 무관한 CPU 작업 역시 성능 병목의 원인이 될 수 있습니다.
예를 들어,
- 무거운 렌더링 작업
- 사용자 스크립트 처리
가 동시에 메인 쓰레드에서 수행되면 CPU Bound 상태가 발생할 수 있습니다.
이미 렌더링 최적화를 충분히 진행한 상태라면,
스크립트 처리 비용을 줄이는 것만으로도 성능 향상을 기대할 수 있습니다.
🎯 게임이 GPU Bound인 경우
GPU 병목 문제는 단순히 Draw Call만의 문제가 아닙니다.
실제로는 필레이트, 메모리 대역폭, 오버드로우, 정점 처리 비용 등 여러 요소가 함께 영향을 주게 됩니다.
전체 구조를 그림으로 정리해보면 다음과 같습니다.

위 구조처럼 GPU 병목은
- 픽셀 처리 문제(Fill Rate)
- 메모리 접근 문제(Memory Bandwidth)
- 정점 처리 문제(Vertex Processing)
로 크게 나눌 수 있습니다.
즉, 단순히 렌더링 비용을 줄이는 것이 아니라 “어디에서 병목이 발생하는지 정확히 파악하는 것”이 렌더링 최적화의 핵심이라고 볼 수 있습니다.
특히, 모바일 장치에서는 필레이트 문제가 자주 발생합니다.
🔥 필레이트(Fill Rate)
필레이트는 GPU가 초당 화면에 렌더링할 수 있는 픽셀 수를 의미합니다.
게임이 GPU가 처리 가능한 양보다 더 많은 픽셀을 매 프레임 그리려고 하면, 필레이트 병목이 발생합니다.
🎯 필레이트 문제 확인 방법
필레이트 문제 여부는 비교적 간단하게 확인할 수 있습니다.
- 게임을 프로파일링해서 GPU 시간을 확인합니다.
- Player Settings에서 화면 해상도를 낮춥니다.
- 다시 프로파일링해서 성능 변화를 확인합니다.
해상도를 낮췄을 때 성능이 향상된다면 필레이트 문제가 원인일 가능성이 높습니다.
🧠 필레이트 문제의 대표 원인
대표 원인은 다음과 같습니다.
- 복잡한 Fragment Shader
- 오버드로우(Overdraw)
- 과도한 Image Effect
🎮 Fragment Shader 최적화
프래그먼트 쉐이더(Fragment Shader)는 GPU에게 픽셀을 어떻게 그릴지 알려주는 코드입니다.
모든 픽셀마다 실행되기 때문에, 쉐이더가 복잡하면 성능 문제가 빠르게 발생할 수 있습니다.
복잡한 Fragment Shader는 가장 흔한 필레이트 병목 원인 중 하나입니다.
✅ Unity 내장 쉐이더 사용 시
가능하면 단순하고 최적화된 쉐이더 사용을 목표로 하는 것이 좋습니다.
특히, Unity의 모바일 쉐이더는 고도로 최적화되어 있습니다.
프로젝트 비주얼 품질을 유지할 수 있다면 논-모바일 프로젝트에서도 모바일 쉐이더를 사용하는 것이 가능합니다.
✅ Standard Shader 사용 시
Unity의 Standard Shader는 재질(Material) 설정에 따라 필요한 기능만 컴파일됩니다.
예를 들어
- Detail Map 제거
- 불필요한 기능 비활성화
만으로도 Fragment Shader 복잡도를 크게 줄일 수 있습니다.
즉, Material 설정 최적화만으로도 성능 향상이 가능합니다.
✅ 커스텀 쉐이더 사용 시
직접 제작한 쉐이더를 사용하는 경우, 최대한 최적화하는 것이 중요합니다.
쉐이더 최적화는 매우 복잡한 주제이므로, Unity 매뉴얼의 Shader Performance 문서를 참고하는 것이 좋습니다.
🔥 오버드로우(Overdraw)
오버드로우는 동일한 픽셀이 여러 번 그려지는 현상을 의미합니다.
대표적으로 아래 나열한 오브젝트 등에서 자주 발생합니다.
- 투명 오브젝트
- 겹치는 UI
- 파티클
🧠 왜 발생할까?
Unity는 렌더 큐(Render Queue)를 기반으로 오브젝트를 렌더링합니다.
예를 들어
- Geometry Queue → Front-to-Back 정렬
- Transparent Queue → Back-to-Front 정렬
을 수행합니다.
특히, Transparent Queue는 시각적 효과를 위해 뒤에서 앞으로 정렬되므로, 오버드로우가 매우 심해질 수 있습니다.
🎯 오버드로우 확인 방법
Unity Scene View의 Draw Mode를 사용하면 오버드로우를 시각적으로 확인할 수 있습니다.
이를 통해, 오버드로우를 발생시키는 오브젝트를 찾을 수 있습니다.
- 겹치는 오브젝트
- 과도한 투명 UI
- 비효율적인 파티클
🎮 Image Effect 최적화
Image Effect는 필레이트 문제를 매우 쉽게 발생시킬 수 있습니다.
특히, 여러 Image Effect를 동시에 사용하는 경우 문제가 커집니다.
예:
- Bloom
- Blur
- Color Grading
✅ 해결 방법
- 최적화된 버전 사용
- 효과 개수 줄이기
- 쉐이더 패스 최소화
예를 들어, 아래와 같이 변경하는 것만으로도 효과를 볼 수 있습니다.
Bloom → Bloom(Optimized)
저사양 장치에서는 Image Effect 자체를 비활성화하는 것도 고려해볼 수 있습니다.
🧠 메모리 대역폭(Memory Bandwidth)
메모리 대역폭은 GPU가 메모리를 읽고 쓰는 속도를 의미합니다.
보통 아래의 상황이 원인이 됩니다.
- 너무 큰 텍스처
- 과도한 텍스처 메모리 사용
🎯 메모리 대역폭 문제 확인 방법
- GPU 시간을 프로파일링합니다.
- Texture Quality를 낮춥니다.
- 다시 GPU 시간을 확인합니다.
성능이 향상되었다면, 메모리 대역폭 문제가 원인일 가능성이 높습니다.
🔥 텍스처 압축(Texture Compression)
텍스처 압축은 디스크와 메모리 모두에서 텍스처 크기를 줄여줍니다.
즉, 메모리 대역폭 문제 완화에 매우 효과적입니다.
가능하다면 텍스처 압축 사용을 권장합니다.
🎮 밉맵(Mipmap)
밉맵은 거리 먼 오브젝트를 위한 저해상도 텍스처입니다.
즉, 멀리 있는 오브젝트에 고해상도 텍스처를 사용하지 않도록 합니다.
이를 통해, 메모리 사용량 감소 / 메모리 대역폭 감소 효과를 얻을 수 있습니다.
🧠 정점 프로세싱(Vertex Processing)
정점 프로세싱은 GPU가 메쉬 정점을 처리하는 작업입니다.
정점 프로세싱의 비용은 다음에 의해 결정됩니다.
- 정점 수
- 정점당 처리 비용
즉, 정점이 많을수록 GPU 부담이 커집니다.
🎯 정점 프로세싱 문제인 경우
게임이 GPU Bound 상태인데
- 필레이트 문제도 아니고
- 메모리 대역폭 문제도 아니라면
정점 프로세싱이 원인일 가능성이 높습니다.
🔥 메쉬 복잡도 줄이기
불필요하게 복잡한 메쉬는 GPU 부담을 증가시킵니다.
대표적으로,
- 과도한 폴리곤
- 비효율적인 모델링
- 불필요한 정점 데이터
등이 문제입니다.
정점 비용을 줄이는 가장 좋은 방법은 👉 메쉬 제작 단계에서 최적화하는 것입니다.
🎮 노멀 매핑(Normal Mapping)
노멀 매핑은 복잡한 메쉬 구조를 텍스처 기반으로 표현하는 기법입니다.
즉, 실제 폴리곤 수를 줄이면서 디테일을 유지할 수 있습니다.
대부분의 경우, 정점 수를 줄이는 효과 때문에 성능상 이득을 볼 수 있습니다.
🔥 Vertex Tangent 비활성화
노멀 매핑을 사용하지 않는 경우 Vertex Tangent 데이터를 제거할 수 있습니다.
이렇게 하면, GPU로 전달되는 정점 데이터 양이 감소합니다.
🎮 LOD(Level of Detail)
LOD는 카메라에서 멀리 있는 메쉬의 복잡도를 낮추는 기술입니다.
즉, 멀리 있는 오브젝트에 불필요하게 많은 정점을 사용하지 않도록 합니다.
이를 통해
- GPU 정점 처리 감소
- 렌더링 비용 감소
효과를 얻을 수 있습니다.
🧠 Vertex Shader 최적화
Vertex Shader는 각 정점을 어떻게 처리할지 GPU에 전달하는 코드입니다.
따라서 Vertex Shader가 복잡할수록 정점 처리 비용이 증가합니다.
가능하면
- 단순한 쉐이더 사용
- 모바일 쉐이더 활용
- 커스텀 쉐이더 최적화
를 목표로 하는 것이 좋습니다.
🎯 핵심 정리
- GPU 병목은 크게 필레이트, 메모리 대역폭, 정점 프로세싱으로 나뉩니다.
- 필레이트 문제는 해상도와 오버드로우의 영향을 크게 받습니다.
- 투명 UI, 파티클, Image Effect는 오버드로우를 증가시킵니다.
- 텍스처 압축과 밉맵은 메모리 대역폭 문제 해결에 도움이 됩니다.
- LOD와 메쉬 최적화는 정점 처리 비용을 줄여줍니다.
🧩 마무리
지금까지 아래 내용을 살펴봤습니다.
- GPU 병목의 종류
- 렌더링 성능 문제의 원인
- Unity에서의 최적화 방법
렌더링 최적화는 단순히 “Draw Call 줄이기” 만의 문제가 아닙니다.
실제로는 다양한 요소가 함께 영향을 줍니다.
- 필레이트
- 텍스처 메모리
- 쉐이더 복잡도
- 오버드로우
- 정점 처리 비용
즉, 프로파일링을 통해 병목 원인을 먼저 정확히 파악하는 것이 가장 중요합니다.
📚 참고 자료
- Unity Learn: A guide to optimizing Unity UI
- Unity Knowledge Base: Static batching
- A trip through the graphics pipeline
- Render hell
- Forward vs Deferred Rendering
- Reducing Draw Calls
- Optimizing SkinnedMeshRenderers
- Reducing SetPass Calls
내용 끝까지 읽어주셔서 감사합니다.