3 minutes
❎ Direct3D 11 Graphics Pipeline - 4. Rasterizer 스테이지
이전 글: ❎ Direct3D 11 Graphics Pipeline - 3. Vertex Shader 스테이지
VS까지의 결과는 정점 단위의 수학적 도형과 연속적인 공간 개념을 가진 수학적 모델이지만 GPU가 실제로 화면에 그릴 수 있는 최소 단위는 물리적 픽셀 단위이기 때문에 이 사이의 계산을 해주는 것이 바로 Rasterizer
Rasterizer는 Shader와 달리 프로그램이 아니라 하드웨어(GPU) 기능으로, HLSL로 조정 가능한 프로그래밍 대상이 아님
- 설정(State)에 따라 동작만 변경 가능
Vertex Shader는 수학적 연산을 담당, Rasterizer는 기하 정보에서 실제 픽셀로의 변환을 담당
1. 입력과 출력
입력
VS로부터 받은 Primitive(점 / 선 / 삼각형)
각 Primitive의 Clip 공간 좌표
VS에서 출력하는 기타 속성들
출력
픽셀의 후보가 될 fragment들
보간된 정점의 속성들
픽셀의 위치(Screen 공간 좌표)
2. Rasterizer 수행 단계 흐름
- Rasterizer의 작업 흐름은 하드웨어에서 자동으로 수행
1. Clipping
VS에서 넘어온 Clip 공간 기준으로 화면 밖에 있는 기하를 잘라냄
- VS에서 온
SV_POSITION(Clip 공간 좌표) 기준으로 수행
- VS에서 온
삼각형이 화면 밖에 걸쳐 있으면 경계선에서 삼각형이 잘리면서 새로운 정점들이 생성됨
삼각형이 화면에 완전히 밖이면 Primitive 자체가 제거됨
2. Perspective Division
- Clip 공간 좌표(
(x, y, z, w))를 입력으로 받아 NDC(Normalized Device Coordinates) 좌표((x / w, y / w, z / w))를 출력
3. Viewport 변환
NDC 좌표를 실제 화면 픽셀 좌표로 변환
Viewport: 화면의 어디에서 얼마나 큰 영역에 렌더링 결과를 그릴 것인가를 정의
Viewport를 설정하지 않으면 Rasterizer는 정상 동작하지 않기 때문에 렌더링 초기화 시 반드시 설정해주어야 함
예시
D3D11_VIEWPORT vp; vp.TopLeftX = 0; vp.TopLeftY = 0; vp.Width = screenWidth; vp.Height = screenHeight; vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; context->RSSetViewports(1, &vp);
4. 후면 제거(back-face culling)
카메라에 등지고 있는(카메라가 후면을 바라보고 있는) 삼각형 제거
성능 최적화와 중복 렌더 방지
Rasterizer State에서 정점의 권선 방향(winding order) 기준으로 판단 기준 설정
5. fragment 생성 및 속성 보간(scan conversion)
삼각형 내부를 덮는 모든 픽셀 위치를 계산. 이 결과물이 Pixel(Fragment) Shader의 입력 단위가 됨
Rasterizer는 픽셀 자체를 만들지는 않고, 이후 PS가 판단해서 화면에 픽셀을 그릴지 말지 결정하는 픽셀 후보(fragment)들을 생성함
fragment에는 화면 좌표, 깊이 값, 보간된 정점 속성 등이 포함됨
3. Rasterizer State
Rasterizer는 프로그래머블하지 않고, 모든 동작은 State 객체로 제어
D3D11에서 Rasterizer State 생성 흐름
D3D11_RASTERIZER_DESC desc = {}; desc.FillMode = D3D11_FILL_SOLID; desc.CullMode = D3D11_CULL_BACK; desc.FrontCounterClockwise = FALSE; ID3D11RasterizerState* rs = nullptr; device->CreateRasterizerState(&desc, &rs); context->RSSetState(rs);
Rasterizer State 핵심 항목들
FillMode: 면을 어떻게 그릴 것인가D3D11_FILL_SOLID: 삼각형 내부를 채움D3D11_FILL_WIREFRAME: 삼각형의 변만 그림
CullMode: 어떤 면을 버릴 것인가D3D11_CULL_BACK: 후면 제거(가장 일반적)D3D11_CULL_FRONT: 앞면 제거D3D11_CULL_NONE: 모두 그림- 메시가 통째로 안보일 때는 대부분 컬링의 문제이므로
D3D11_CULL_NULL로 찍어보는 디버깅을 많이 함
- 메시가 통째로 안보일 때는 대부분 컬링의 문제이므로
FrontCounterClockwise: 앞면의 정의기본값은
FALSE. 정점의 순서가 시계 방향인 경우 앞면으로 계산이 설정과 Mesh 인덱스 순서가 맞지 않으면 삼각형이 모두 사라짐
DepthBias: 깊이 값을 인위적으로 살짝 밀어낼 수 있는 기능Shadow Map의 Z-fighting 방지
일반 렌더링에서는 잘 안쓰지만, 그림자 구현 시에는 반드시 필요한 설정
MultisampleEnableScissorEnable
Multisample / Antialias?
Rasterizer는 멀티샘플링(MSAA)에도 관여함
지금은 ‘Rasterizer가 안티앨리어싱에도 관여하는구나~’ 정도만 짚고 가면 될 듯
Scissor
이미 만들어진 fragment 중에서 특정 사각형 영역만 통과시키는 마스크
화면 크기와는 독립적으로, 개발자가 지정한 사각형 영역 안에 들어오는 픽셀만 통과시키는 픽셀 단위 마스킹
- UI 클리핑 등에 활용
Clipping은 Rasterizer 초입에서 일어나는 기하 단위 절단, Scissor는 fragments가 생성된 뒤 일어나는 픽셀 단위 마스킹
4. Rasterization Rules
문서로 정리할 정도로 중요한 내용은 아니고, D3D 11을 지원하는 하드웨어가 보장하는 규칙과 한계를 명시한 것
Rasterizer는 수학적인 연속 공간을 이산적인 픽셀 격자로 바꾸는 단계이기 때문에 지켜야 하는 규칙과 제약이 존재
- 하드웨어(GPU)마다 Resterization 결과가 달라지지 않도록 하기 위한 목적(같은 입력이면 하드웨어가 달라도 항상 같은 픽셀 결과)
다음 글: ❎ Direct3D 11 Graphics Pipeline - 5. Pixel Shader 스테이지