3D 게임의 렌더링 품질이 높아질수록, 화면에 보이는 객체 뒤에 가려져 보이지 않는 수많은 폴리곤과 픽셀을 어떻게 효율적으로 처리하느냐가 성능의 핵심이 됩니다. 만약 눈에 보이지 않는 객체의 픽셀 셰이더 연산까지 모두 수행한다면, 이는 고스란히 성능 낭비(Overdraw)로 이어집니다.
이 문제를 해결하기 위해 현대 그래픽스 파이프라인은 Z-버퍼링과 한 단계 더 발전된 얼리 Z-테스트 기술을 사용합니다. 이 글에서는 두 기술의 내부 동작 메커니즘을 픽셀 셰이더와 메모리 대역폭 관점에서 소스 코드와 함께 상세히 분석해 보겠습니다.
1. Z-버퍼링 (Z-Buffering)
Z-버퍼링은 화면에 그려질 각 픽셀의 깊이(Depth, Z값) 정보를 기록하는 Z-버퍼(Depth Buffer)를 사용하여, 카메라에서 가장 가까운 픽셀만 최종 프레임 버퍼에 기록하는 기술입니다. 출력 병합(Output Merger) 단계에서 수행되는 이 수학적 검사 과정은 보이지 않는 객체의 픽셀을 효과적으로 제거합니다.
동작 원리 및 수식
Z-버퍼는 0.0(근평면)부터 1.0(원평면)까지의 값을 가집니다. 새로운 픽셀이 그려지려 할 때, GPU는 현재 Z-버퍼에 저장된 해당 픽셀 위치의 값($Z_{buffer}$)과 새로운 픽셀의 Z값($Z_{pixel}$)을 비교합니다.

즉, 새로운 픽셀이 더 가까울 때만 그려지고 Z-버퍼가 업데이트됩니다.
HLSL 코드 레벨 분석
Z-버퍼 검사 자체는 그래픽스 하드웨어가 수행하지만, 셰이더에서는 임의로 픽셀을 버리기 위해 clip() 함수를 활용하여 심도 검사를 시뮬레이션할 수 있습니다.
High-level shader language
// Z-버퍼링을 시뮬레이션하는 clip() 사용 예시 (HLSL)
float _DepthThreshold; // 깊이 임계값
float4 frag(v2f i) : SV_Target {
float4 col = tex2D(_MainTex, i.uv);
// Z값과 임계값을 비교하여 픽셀을 버림 (심도 검사 실패 시뮬레이션)
clip(_DepthThreshold - i.depth);
return col;
}
- 장점: 카메라에서 가려진 피사체를 완벽하게 판별하여 오버드로우 부하를 제거.
- 단점: 검사가 출력 병합 단계에서 이루어지므로, 검사에 실패한 픽셀도 이미 무거운 픽셀 셰이더 연산(라이팅, 텍스처링 등)을 전부 마친 상태여서 연산 낭비가 발생.
2. 얼리 Z-테스트 (Early Z-Test)
얼리 Z-테스트는 Z-버퍼링의 단점을 획기적으로 개선한 기술입니다. 심도 검사를 출력 병합 단계가 아닌, 픽셀 셰이더 연산 직전으로 앞당겨 수행하는 기술입니다.
이를 통해 심도 검사에 실패한 픽셀은 픽셀 셰이더 연산 자체를 생략하므로, 필레이트(Fill-rate) 및 픽셀 셰이더 연산 부하를 비약적으로 줄일 수 있습니다.
동작 원리 및 HLSL 분석
얼리 Z-테스트는 그래픽스 하드웨어 차원에서 자동으로 지원되며, 최적화 효율을 극대화하기 위해서는 불투명(Opaque) 객체들을 카메라에서 가까운 순서대로 그리는 Front-to-Back 정렬이 필수적입니다.
High-level shader language
// 얼리 Z-테스트를 위한 Front-to-Back 정렬 셰이더 예시 (HLSL)
// (별도의 얼리 Z 코드는 없으나, 정렬된 그리기와 clip/discard 미사용이 핵심)
float4 frag(v2f i) : SV_Target {
// 얼리 Z-테스트에 의해 가려진 픽셀은 이 연산 자체가 수행되지 않음!
float4 col = tex2D(_MainTex, i.uv);
return col;
}
- 장점: 픽셀 셰이더 연산을 사전에 생략하여 성능 향상 효과가 극대화됨.
- 주의점: 만약 픽셀 셰이더 내부에서
discard나clip(), 혹은 알파 테스트를 수행하면 하드웨어는 얼리 Z-테스트를 비활성화할 수도 있으므로(Z-killing 방지), 최적화 시 주의가 필요합니다.
3. 핵심 비교 및 성능 영향
두 기술은 렌더링 파이프라인에서 심도 검사를 수행하는 시점이 완전히 다릅니다.
| 구분 | Z-버퍼링 (Z-Buffering) | 얼리 Z-테스트 (Early Z-Test) |
| 검사 시점 | 출력 병합 (Output Merger) 단계 | 픽셀 셰이더 (Pixel Shader) 직전 단계 |
| 픽셀 셰이더 연산 | 검사 실패 픽셀도 연산 수행함 | 검사 실패 픽셀은 연산 생략함 |
| 성능 부하 지점 | 픽셀 셰이더 연산량 & 필레이트 | Z-버퍼 메모리 대역폭 (검사 효율적) |
| 주의 사항 | 오버드로우 연산 낭비 발생 | clip, discard 사용 시 비활성화 주의 |
요약 및 결론
Z-버퍼링은 가려진 피사체를 판별하는 기본 기술이지만, 얼리 Z-테스트는 픽셀 셰이더 연산을 사전에 절약하는 차세대 최적화 기술입니다.
고성능 3D 게임을 개발할 때는 불투명 객체들의 Front-to-Back 정렬을 철저히 지키고, 픽셀 셰이더 최적화를 방해하는 clip이나 discard 사용을 최소화하여 얼리 Z-테스트의 혜택을 극대화해야 합니다. 이것이 곧 복잡한 씬에서도 안정적인 프레임을 유지하는 기술적 비결입니다.