1. 개요
출력 병합기(OM)는 그래픽스 파이프라인의 마지막 단계이다. Fixed-Function 유닛으로, 셰이더 코드로 프로그래밍할 수 없다.
OM 스테이지의 목적은 PS가 계산을 완료한 Fragment를 입력받아, 이들을 '프레임버퍼(Framebuffer)'(최종 렌더링 이미지)의
픽셀(Pixel)로 병합(Merge)하는 것이다.
이 과정에서 "이 프래그먼트가 화면에 최종적으로 그려져야 하는지 결정하는 다양한 테스트를 수행하며, 반투명 효과를 위한 블렌딩(Blending) 작업을 처리한다.
2. OM 스테이지의 주요 기능 (작동 순서)
픽셀 셰이더가 프래그먼트의 최종 색상(SV_Target)을 출력하면, OM은 이 프래그먼트를 받아 다음과 같은 테스트와 작업을 순차적으로 실행한다.
3. Depth Test (Z-Test)
이것은 OM 단계의 가장 중요하고 기본적인 기능으로, 3D 공간의 가려짐(Occlusion) 문제를 해결한다.
- 목적: 현재 그리려는 픽셀이 이미 그려진 픽셀보다 '앞에' 있는지 '뒤에' 있는지 판별한다.
- 필요한 버퍼: 깊이 버퍼(Depth Buffer / Z-Buffer).
- 이 버퍼는 화면의 모든 픽셀에 대해 "현재까지 그려진 것 중 가장 카메라에 가까운 픽셀의 깊이(Z) 값"을 저장하고 있다.

- 작동 메커니즘:
- OM은 PS로부터 새로운 프래그먼트의 깊이 값(Z_new)을 받는다.
- OM은 프레임버퍼의 같은 (x, y) 위치에 있는 깊이 버퍼의 값(Z_buffer)을 읽어온다.
- 두 값을 비교한다. (일반적인 설정: Z_new < Z_buffer)
- 테스트 통과 (Pass): 새 프래그먼트가 더 가깝다 (Z_new < Z_buffer).
- 이 프래그먼트는 다음 단계(스텐실 테스트)로 진행된다.
- 깊이 버퍼의 값은 Z_new로 갱신(Write)된다.
- 테스트 실패 (Fail): 새 프래그먼트가 더 멀다 (Z_new >= Z_buffer).
- 이 프래그먼트는 즉시 폐기(Discard)된다.
- 픽셀 셰이더가 열심히 계산한 색상 값은 그대로 버려진다.

4. 스텐실 테스트 (Stencil Test)
깊이 테스트와 함께 수행되는 선택적인 '마스킹(Masking)' 테스트이다.
- 목적: 깊이 값 외에 개발자가 정의한 추가적인 규칙을 사용하여 픽셀을 선별적으로 그리거나 그리지 않도록 제어한다.
- 필요한 버퍼: 스텐실 버퍼(Stencil Buffer).
- 깊이 버퍼와 마찬가지로 픽셀당 값을 저장하는 버퍼이다. (보통 깊이 버퍼와 결합되어 'Depth-Stencil Buffer'로 존재한다.)
- 작동 메커니즘:
- 개발자는 "스텐실 버퍼의 값이 1일 때만 그려라" 또는 "그린 다음 스텐실 버퍼의 값을 2로 바꿔라" 같은 복잡한 규칙을 설정할 수 있다.
- 프래그먼트가 이 테스트를 통과하지 못하면, 깊이 테스트와 마찬가지로 폐기(Discard)된다.
- 주요 용도: 아웃라인(Outline) 렌더링, 거울 반사 영역 제한, 그림자(Shadow Volume) 구현 등 복잡한 시각 효과에 사용된다.

5. Color Blending, Alpha Blending

프래그먼트가 깊이 테스트와 스텐실 테스트를 모두 통과했을 때, 반투명(Translucency) 효과를 처리하는 마지막 단계이다.
- 목적: 유리, 물, 연기, 불꽃처럼 뒤가 비치는 '반투명' 객체를 구현한다.
- 작동 메커니즘:
- 이 단계는 프래그먼트를 폐기하는 것이 아니라, '섞는(Blend)' 과정이다.
- OM은 PS가 출력한 새 색상(Source Color)과 프레임버퍼에 이미 그려져 있던 기존 색상(Destination Color)을 수학적으로 혼합한다.
- 가장 일반적인 알파 블렌딩 공식은 다음과 같다. FinalColor = (SourceColor * SourceAlpha) + (DestColor * (1 - SourceAlpha))
- (여기서 SourceAlpha는 PS가 출력한 새 색상의 투명도 값이다.)

- 불투명(Opaque) 객체의 경우:
- 일반적인 3D 객체는 블렌딩이 비활성화(Disabled)된다.
- 이 경우, FinalColor = SourceColor가 되어, 프레임버퍼의 기존 색상을 단순히 덮어쓴다(Overwrite).



6. 최종 쓰기 (Final Write)
모든 테스트와 블렌딩이 완료된 FinalColor 값은 렌더 타겟(Render Target) (즉, 프레임버퍼의 컬러 버퍼)의 해당 (x, y) 픽셀에 최종적으로 기록(Write)된다.
6.1 Render Target, Frame Buffer
Render Target
- 정의: GPU가 그리기 명령을 실행할 수 있는 대상이 되는 모든 리소스(메모리)를 의미합니다. 일종의 도화지 역할.
- 역할:
- GPU는 렌더링 결과를 화면에 즉시 출력하는 대신, 이 '도화지'에 먼저 그릴 수 있습니다.
- 이 '도화지'는 화면에 표시될 백 버퍼(Back Buffer)일 수도 있고, 섀도우 맵, 반사 텍스처 등 중간 계산을 위한 화면 외 버퍼(Off-screen Buffer)일 수도 있다.
프레임 버퍼 (Frame Buffer)
- 정의: 렌더링된 프레임의 최종 픽셀 색상 데이터를 저장하는 특정 메모리 영역을 말한다.
6.2 더블 버퍼링 (Double Buffering)
3. 프론트 버퍼 (Front Buffer)
- 정의 : 현재 모니터가 읽어서 화면에 표시하고 있는 프레임 버퍼.
- 역할: 사용자가 지금 보고 있는 최종 이미지. GPU는 이 버퍼에 직접 그리지 않는다.
4. 백 버퍼 (Back Buffer)
- 정의 : GPU가 현재 다음 프레임을 그리고 있는 프레임 버퍼.
- 역할: 사용자의 눈에 보이지 않는 뒤(Back)에서 렌더링 작업이 일어나는 "현재의 도화지"입니다. 따라서 백 버퍼는 현재 파이프라인의 주 렌더 타겟이 된다.
5. 스와핑 과정
- GPU는 백 버퍼(렌더 타겟)에 다음 프레임을 그린다.
- 이 시간 동안, 모니터(사용자)는 프론트 버퍼의 이전 프레임 이미지를 계속 보고 있다.
- GPU가 백 버퍼 그리기를 완료하면, 시스템에 "교체(Swap)" 신호를 보낸다.
- 시스템은 프론트 버퍼와 백 버퍼의 역할을 바꾼다.
- (구) 백 버퍼 ➔ (새) 프론트 버퍼가 되어 화면에 표시된다.
- (구) 프론트 버퍼 ➔ (새) 백 버퍼가 되어 GPU가 다음 프레임을 그릴 새 도화지가 된다.
- 이 과정이 매 프레임 반복된다.
- 현대 그래픽스에서는 화면이 찢어지는 현상(Screen Tearing)을 방지하기 위해, 프레임 버퍼를 두 개 두고 교체하는 더블 버퍼링 기술을 표준으로 사용한다.
7. 요약
출력 병합기(OM)는 파이프라인의 최종 단계이다. 픽셀 셰이더가 계산한 모든 후보, Fragment들을 받아, 깊이(Z)와 스텐실 규칙에 따라 '폐기'시킬지 '통과'시킬지 결정하며, 통과된 픽셀들을 프레임버퍼에 '혼합(Blend)'하거나 '덮어쓰는' 모든 마무리 작업을 담당한다.
'그래픽스' 카테고리의 다른 글
| 스키닝과 애니메이션 (0) | 2025.11.05 |
|---|---|
| 08. Pixel Shader - Alpha test (0) | 2025.11.05 |
| 08. Pixel Shader - Lighting (0) | 2025.11.04 |
| 08. Pixel Shader - Normal Mapping (0) | 2025.11.04 |
| 08. Pixel Shader - Image Texturing (0) | 2025.11.04 |