OM Stage
- Scissor Test
- Depth-Stencil Test
- Color Blending
Output Merger(OM)은 아래를 이용하여 최종 렌더링 색을 결정한다
- pipeline state의 조합
- pixel shader에 의해 생긴 pixel 정보
- render target의 정보
- depth/stencil buffer의 정보
Pipeline state
- Pipeline state는 렌더링을 위해 GPU 입력 정보를 어떻게 해석하고 처리할지 결정하는 하드웨어 설정
- rasterizer state, blend state, depth-stencil state 같은 설정 뿐 아니라 주어진 기하 정보와 shader state의 primitive topology type도 정할 수 있음
- Direct3D 12에서는 많은 그래픽 pipeline state가 Pipeline State Objects에 의해 설정되고, 대부분 PSO는 초기화 시간에 생성됨.
- 렌더링 시간에 빠르게 렌더링을 위해 다른 pipeline state로 바꿈
Render target
- 도화지 느낌, drawing commands를 받아 render target에 렌더될 수 있다.
- back buffer에 되기 전에 먼저 렌더링 되는 임시 중간 버퍼
framebuffer
- color 정보를 저장하는 RAM의 부분을 말함
back buffer
- 현재 표시되고 있는 framebuffer를 통상 front buffer나 primary buffer
- 우리가 그릴 frambuffer를 back buffer 혹은 secondary buffer
Scissor Test
- 필수는 아닌데, 렌더링 성능 최적화 및 특정한 이펙트 효과를 줄 수 있어서 사용함(화면의 특정한 사각형 밖에 있는 pixel이나 fragment를 제거함)
Performance Optimization : 특정한 영역으로 렌더링을 제한함으로써 GPU가 영역 밖에 있는 pixel 처리를 안 해도 됨. viewport에서 일정 부분만 보이게 하고 싶을 때 특히 효과적
UI rendering : 스크롤이나 창 화면 같은 요소가 특정 경계 안에서만 렌더링 되면 됨
Special Effect : 직사각형 방식으로 일부를 드러내거나 없앨 수 있고 분할 화면, spotlight 효과를 줄 수도 있음
Depth-stencil Test
- depth-stencil buffer는 detph 정보와 stencil 정보를 모두 포함함
- depth 데이터는 어떤 pixel 카메라에 제일 가깝게 놓일지 결정할 수 있고, stencil 데이터는 업데이트 될 수 있는 pixel이 mask할 때 결정
- OM stage에서 위 데이터들이 사용되고 pixel이 그려질지 말지 결정된다

Depth Test
Depth buffering: depth buffer가 어떤 픽셀을 그릴지 결정하는 과정(z-buffering 이라고도 함)
- OM stage에서 PS나 보간으로 값이 들어옴 그리고 아래와 같은 식으로 클램핑된다.
z=min(Viewport.MaxDepth,max(Viewport.MinDepth, z))
- 클램핑 이후 depth 값은 현재 depth-stencil buffer와 비교함
- per-sample operation 작동
- 어떤 pixel이 보일지 안 보일지 결정
- 스크린 위에 오브젝트 투영시, 생성된 pixel의 depth와 현재 depth-stencil buffer 값과 비교
- buffer 값보다 생성된 pixel depth 값이 작으면, 생성된 pixel이 앞에 있는 것이므로, color buffer와 depth buffer의 값을 현재 pixel 값으로 변경함.
- pixel depth 값이 크면 숨겨져 있는 것으로 표시X

- Example 1
- 빨간 삼각형 이후 파란 삼각형이 렌더링시
- 파란 삼각형의 depth가 더 작으므로 파란색이 앞에 있음
Stencil Test

- stencil 값이 1인 것만 표시

- UI부분은 제거해서 표시하면 -> 렌더링 더 빠름
Color Blending
- 반투명이 물체 뒤가 보여야함
- depth test에서는 뒤에 있는 pixel이 제거되거나 대체됨
- 그러나, 몇몇 물체는 반투명하므로 하나 이상의 pixel 값을 합쳐서 최종 pixel color를 생성
- blending 연산은 모든 pixel shader output에서 수행됨, 출력 값이 render target에 그려지기 전에.
alpha(α) value
- blending 과정은 보통 alpha value를 사용한다
- 256 단계의 불투명도: 0은 완전 투명 255는 완전 불투명
- 정규화 하여 [0, 1] 범위로 사용하는 것이 더 선호됨
blending equation
Keeping Destination Pixel
- 목적 pixel을 덮어쓰지 않고 유지하고 싶을 때는 어떻게 할까
- source pixel blend factor를 D3D12_BLEND_ZERO로 해줌
- destination blend factor를 D3D12_BLEND_ONE 으로 해줌
- blend operator를 D3D12_BLEND_OP_ADD 로 해줌
- 그러면 다음과 같은 과정
- c=fsrccsrc+fdstcdst
- c=0∗csrc+1∗cdst
- c=cdst
Alpha Blending(투명도: Transparency)
- 알파 블랜딩에서는 초기 알파 구성 요소는 초기 픽셀의 투명도를 조절하는 비율로 간주된다
- Source blend factor = D3D12_BLEND_SRC_ALPHA
- Destination blend factor = D3D12_BLEND_INV_SRC_ALPHA
- Blend Operator = D3D12_BLEND_OP_ADD
- 다음과 같은 블랜딩 방정식을 따른다
- c=fsrccsrc+fdstcdst
- c=αs∗csrc+(1−αs)∗cdst
- 알파블랜딩에서는 임의로 primitive 렌더링이 불가능함, 모든 불투명 primitive를 렌더한 이후 back-to-front 명령 후., 그러므로 부분적으로 투명한 물체들은 정렬된다.

- 이미 그려져 있는 물체가 destination, 그릴 물체가 source
render 순서
1. Transparent Or Opaque
가장 우선 순위는 Opaque 한 primitive 입니다. 이를 먼저 렌더링해줘야 합니다.
2. Depth - Z 값
현재 Z 값이 0.8인 빨간색 삼각형이 Z 값이 0.5인 파란색 삼각형 보다 더 먼저 렌더링됩니다.(back-to-front)
3. Blending - α 값
Scissor Test와 Stencil Test의 차이점?
- 둘은 유사해보이지만 차이점이 있다.
- 복잡성: stencil test는 더 복잡하다
- 사용 예: scissor test는 UI 렌더링에 쓰이고, stencil test는 복잡한 시각효과나 로직에 의한 조건 렌더링할 때 쓰임
- 메커니즘 이해: scissor test는 특정한 사각형 밖에 있는 pixel들을 제거하는 것이고, stencil test는 stencil buffer 내 값과 비교하여 쓰고 검사를 포함한다.
Order-Independent Trnasparency
- alpha blending이나 color blending에서는 임의의 명령으로 렌더링 하지 못함
- 모든 fragment를 정렬하면 정확한 렌더링 결과를 내지만,,
- 많은 시간이 걸림
- 폴리곤이 교차하지 못함
- 동적인 씬에서, 너무 많은 일이 필요
- 이 문제점을 해결하기 위해 OIT 기술이 있음
Depth Peeling
- Depth peeling이 OIT 기술이 가능하게 만들었다
- 표준 depth test는 각 pixel에 가장 가까운 fragment를 주었음
- 그러나, 표준 depth test는 n번째로 가까운 표면을 주지 않았었다
- depth peeling은 n번째 가까운 표면도 추출할 수 있게 해줌

In first pass, normal 렌더링 하고 depth test는 가장 가까운 표면을 줌
Second pass, depth buffer가 처음 "peel away"를 하도록 사용함, 처음보다 더 작거나 같은 깊이에 있는 것을
After first pass, first pass 이후에는 depth buffer에 있는 알고리즘이 이전 pass로 부터 다음 layer를 위해 보이는 frament를 결정한다. 이건 각각 이어지는 pass는 이전 depth buffer에 접근하고 새로운 depth buffer를 만들어 내는 것이 필요하다
- 이전 버전에서 OpenGL, DX에서는 dual depth buffer가 없었음
- 근데 이제 D3D11, D3D12에서 multiple depth buffer를 사용 가능
- 모든 pixel에 독특한 depth에 각각 RGBA color는 분리된 layer에 저장된다.
- 남은 모든 것은 명령을 통해 layer들을 혼합함으로써 각 pixel에 있는 올바른 order-dependent color를 계산
D2
OIT: pixel 단위의 transparency(투명도) 구현이 가능하다.
실시간으로 fog 같은 것을 구현 가능
Sorting Based: polygon based sorting → pixel 단위의 transparency 구현이 불가능함.
pixel 단위로 하려면 OIT에 비해 느려짐
유익합니다.