🚀 들어가며
– 원문 링크 – (참고: 원문 링크가 접속이 불가하네요…)
이번 글에서는
- 유니티가 프레임을 렌더링할 때 내부에서 어떤 일이 벌어지는지
- 렌더링 과정에서 어떤 성능 문제가 발생할 수 있는지
- 렌더링 성능 문제를 어떤 방식으로 접근해야 하는지
를 정리해보겠습니다.
렌더링 최적화를 공부할 때 가장 먼저 이해해야 하는 점은 “모든 문제를 해결하는 단 하나의 최적화 방법은 없다”는 것입니다.
렌더링 성능은 굉장히 많은 요소의 영향을 받습니다.
- 게임 구조
- 오브젝트 수
- 쉐이더 복잡도
- 하드웨어 성능
- 운영체제
즉, 단순히 Draw Call 하나만 줄인다고 모든 문제가 해결되지는 않습니다.
🧠 가장 중요한 것은 프로파일링
렌더링 최적화에서 가장 중요한 것은 문제를 정확히 분석하는 것입니다.
즉,
문제를 조사하고,
실험하고,
프로파일링을 통해 병목 원인을 파악해야 합니다.
이 글은
- 렌더링 성능 문제의 기본 개념
- 렌더링 파이프라인 구조
- 자주 등장하는 용어
를 이해하는 데 초점을 맞추고 있습니다.
물론, 실제 프로젝트에서 발생하는 모든 문제를 다 다루지는 못합니다.
하지만, 렌더링 최적화를 이해하기 위한 기반 지식으로는 충분히 도움이 될 것입니다.
🎯 렌더링(Rendering)이란?
렌더링은 화면에 게임 화면을 그리는 과정입니다.
유니티에서는 매 프레임마다 CPU와 GPU가 협력해서 화면을 완성합니다.
기본 흐름은 다음과 같습니다.
- CPU가 무엇을 그릴지 결정한다
- CPU가 GPU에 명령을 전달한다
- GPU가 실제 화면을 그린다
즉, CPU와 GPU는 서로 역할이 다릅니다.
🧠 렌더링 파이프라인(Rendering Pipeline)
렌더링을 설명할 때 자주 등장하는 용어가 Rendering Pipeline입니다.
쉽게 말하면 CPU와 GPU 사이에서 렌더링 정보가 흐르는 전체 과정이라고 이해하면 됩니다.
그리고 렌더링 최적화의 핵심은 이 정보 흐름을 최대한 효율적으로 유지하는 것입니다.
🎮 CPU는 어떤 작업을 할까?
매 프레임마다 CPU는 렌더링 준비 작업을 수행합니다.
대표적으로 다음 작업들이 있습니다.
🔥 1. 어떤 오브젝트를 그릴지 결정
CPU는 씬(Scene)의 모든 오브젝트를 검사합니다.
그리고 렌더링해야 하는 오브젝트만 선택합니다.
예를 들어, 카메라 밖에 있는 오브젝트는 보이지 않으므로 렌더링할 필요가 없습니다.
즉,
카메라에 보임 → 렌더링
카메라 밖 → 렌더링 안함
이런 방식입니다.
렌더링하지 않는 오브젝트는 Cull 처리된다고 표현합니다.
🎯 프러스텀 컬링(Frustum Culling)
카메라가 볼 수 있는 범위를 View Frustum이라고 부릅니다.
즉, 카메라 시야 안에 있는 오브젝트만 렌더링하는 과정이 Frustum Culling입니다.
이는 렌더링 비용을 줄이는 매우 중요한 최적화입니다.
🔥 2. Draw Call 생성
CPU는 렌더링할 오브젝트 정보를 수집합니다.
그리고 Draw Call이라는 명령 단위로 정리합니다.
Draw Call에는
- 어떤 메쉬를 그릴지
- 어떤 머티리얼을 사용할지
- 어떤 텍스처를 사용할지
같은 정보가 포함됩니다.
즉, GPU에게 보내는 렌더링 명령이라고 생각하면 됩니다.
🎮 배칭(Batching)
특정 조건에서는 여러 오브젝트를 하나의 Draw Call로 합칠 수 있습니다.
이 과정을 Batching이라고 부릅니다.
배칭은 렌더링 최적화에서 굉장히 중요한 개념입니다.
왜냐하면 Draw Call 수를 줄일 수 있기 때문입니다.
🔥 3. Batch 생성
CPU는 Draw Call을 포함한 Batch라는 데이터 패킷을 생성합니다.
일반적으로 Batch는 GPU에 전달되는 렌더링 단위라고 생각하면 됩니다.
🧠 SetPass Call이란?
CPU는 Draw Call을 전달하기 전에 GPU 상태(Render State)를 먼저 설정해야 합니다.
예
- 어떤 Shader를 사용할지
- 어떤 Texture를 사용할지
- Blend 상태는 무엇인지
이 설정 변경 명령을 SetPass Call이라고 부릅니다.
🎯 왜 중요한가?
SetPass Call은 CPU 비용이 높은 작업 중 하나입니다.
즉, SetPass Call이 많아질수록 성능이 떨어질 가능성이 높아집니다.
특히, 머티리얼이 자주 바뀌는 경우 문제가 커질 수 있습니다.
🎮 Draw Call 전달
SetPass Call 이후 CPU는 GPU에 Draw Call을 전달합니다.
그러면 GPU는 현재 설정된 Render State를 사용해서 메쉬를 렌더링합니다.
즉 흐름은
SetPass Call
↓
Draw Call
↓
GPU 렌더링
형태로 진행됩니다.
🧠 Pass란?
Shader에는 여러 개의 Pass가 존재할 수 있습니다.
Pass는 Shader 코드의 렌더링 단계라고 생각하면 됩니다.
문제는 Pass가 늘어날수록 SetPass Call도 증가할 수 있다는 점입니다.
즉, 복잡한 Shader는 CPU와 GPU 모두에 부담을 줄 수 있습니다.
🎮 GPU는 어떤 작업을 할까?
CPU가 렌더링 명령을 준비했다면, 이제 GPU가 실제 화면을 그립니다.
GPU는 CPU가 전달한 순서대로 작업을 처리합니다.
🔥 SetPass Call 처리
현재 작업이 SetPass Call이라면 GPU는 Render State를 변경합니다.
즉, 다음 Draw Call 렌더링 준비를 수행합니다.
🔥 Draw Call 처리
현재 작업이 Draw Call이라면 GPU는 실제 메쉬를 렌더링합니다.
이 과정에서 Shader 코드가 실행됩니다.
🧠 Vertex Shader와 Fragment Shader
Shader 내부에는 여러 단계가 존재합니다.
대표적으로
- Vertex Shader
- Fragment Shader
가 있습니다.
🎯 Vertex Shader
Vertex Shader는 정점(Vertex)을 처리합니다.
예
- 위치 계산
- 회전
- 변형
같은 작업을 수행합니다.
🎯 Fragment Shader
Fragment Shader는 픽셀(Pixel)을 처리합니다.
예
- 색상 계산
- 조명 계산
- 텍스처 적용
같은 작업을 수행합니다.
즉, 화면 최종 색상을 계산하는 단계입니다.
🎮 전체 렌더링 흐름 정리
지금까지 설명한 Unity Rendering Pipeline 구조를 그림으로 정리해보면 다음과 같습니다.
핵심은 CPU와 GPU가 서로 다른 역할을 수행하면서, 하나의 프레임을 함께 완성한다는 점입니다.

지금까지 내용을 간단히 정리하면
CPU
↓
Cull 처리
↓
Draw Call 생성
↓
Batch 생성
↓
SetPass Call 전달
↓
Draw Call 전달
↓
GPU
↓
Vertex Shader 실행
↓
Fragment Shader 실행
↓
화면 출력
형태로 진행됩니다.
따라서, 렌더링 최적화는 단순 GPU 문제만이 아니라, CPU와 GPU 전체 흐름을 함께 이해하는 것이 중요합니다.
🎯 핵심 정리
- 렌더링은 CPU와 GPU가 협력해서 처리한다
- CPU는 무엇을 그릴지 결정하고 GPU에 명령을 전달한다
- GPU는 실제 화면을 렌더링한다
- Draw Call과 SetPass Call은 렌더링 성능에 큰 영향을 준다
- Batching은 Draw Call 감소를 위한 중요한 최적화 기법이다
- Vertex Shader와 Fragment Shader는 GPU 렌더링의 핵심 단계다
🧩 마무리
렌더링 최적화를 공부하다 보면 처음에는 Draw Call이나 Shader만 보게 되는 경우가 많습니다.
하지만 실제로는 CPU와 GPU 사이에서 어떤 흐름이 발생하는지 이해하는 것이 훨씬 중요합니다.
즉, 아래의 내용을 이해해야 렌더링 병목 문제를 제대로 분석할 수 있습니다.
- CPU는 무엇을 하는지
- GPU는 무엇을 하는지
- Draw Call은 왜 비싼지
- SetPass Call은 왜 중요한지
다음 글에서는
렌더링 과정에서 발생하는 CPU Bound / GPU Bound 문제와,
실제 병목이 어떻게 발생하는지에 대해서 조금 더 자세히 살펴보겠습니다.