Rasterizer Stage

Rasterization은 각각의 primitive를 sample coverage에 따라 Pixel 또는 Fragment라고 불리는 2차원 이미지 요소로 나누는 과정이다. 즉, 이 stage는 vector 정보를 raster image로 바꾼다.
쉽게 말해서, 지금 이렇게 vertex 3개만 가지고 내부는 공허한 상태인 아래 삼각형의 안쪽을 pixel로 채워주는 과정이다. 오브젝트를 디자인할 때 primitive 내부를 같은 색으로 정의했을지라도 빛을 받거나 주변 환경에 대한 반사가 이루어지면 하나의 삼각형 안에서도 각 픽셀마다 조금씩 다른 색으로 렌더링 되어야 한다. 이 pixel들을 handling하기 위해서는 하나하나가 데이터형이 되어야 한다. 그리고 그 데이터형이 바로 pixel 또는 fragment라는 이름으로 채워지는 친구들이 된다. vertex를 기준으로 gpu 내부에서 채운다! 그리고 이 vertex를 기준으로 하나하나의 데이터형을 만들어주는 것, 이 친구들의 색깔을 결정해야 하니 준비해~라며 준비를 시키는 것이 이 stage이다. 이 stage는 엄청나게 빠르게 정해진대로 동작하는 fixed func이다.
Vertex shader를 통해 clip space에서의 final position을 구해, Rasterizer stage에 도달하는 정점들은 아래 3가지의 hard-wired vertex post-processing 단계를 거치게 된다. 이 3가지 function들을 수행하면서 픽셀을 만들어주는 것이다.
Primitive Clipping
Clipping은 clip space에서 수행된다. 그치만 일단 직관적인 이해를 위해 camera space에서 이 개념을 이해해보자.
삼각형 T1은 완전히 view frustum의 밖에 나가있으므로, clipping이 아니라 view frustum culling에서 없어진다. T2는 view frustum 안에 완전히 들어가있기 때문에 다음 단계로 넘겨 렌더링하면 된다. 삼각형 T3가 관건인데, 이렇게 view frustum을 교차하는 친구에 대해 clipping handling을 수행해줘야 한다. 새로 vertex를 만들어주는 operation을 수행하는 것이다.
projection transform은 projection space에서의 clipping volume을 정의하고, 이 volume 밖에 있는 primitive들은 clip 된다.
Perspective Division
아핀 변환과는 달리 $M_{proj}$의 마지막 열은 $(0\,0\,0\,1)^T$가 아니라 $(0\,0\,1\,0)^T$ 요거다!

이렇게 vertex $(x,y,z,1)$에 projection matrix를 곱하면 transform된 vertex의 w-coordinate는 z가 된다. 여기서 homogeneous (clip) space에서 Cartesian space로 바꿔주기 위해 각 vertex는 그것의 w-coordinate인 z로 나눠져야 한다. 그 결과는 아래와 같다.

이렇게 z로 나눠주는게 왜 Cartesian space로의 변환을 의미할까. z는 camera space의 xy-plane으로부터의 거리, 즉 얼마나 떨어져 있는지를 나타내는 positive value이다. 이때 z로 나눠주는 과정은 멀리있는 것을 작게 만들어줌으로써 멀리있는 것은 작아지고, 가까이 있는 친구는 유지되면서 가까이 있는 쪽이 커보이는 현상을 만든다. 이것이 perspective division이다. 그리고 그 결과는 NDC에 있다~라고 말한다. 그림으로 보면 다음과 같다.

z로 나눠준 이후의 결과물이 NDC, 그 전 단계가 clip space로, clip space와 NDC는 구분되는 개념이다. (예전에는 PD도 하나의 operation이었는데 요즘에는 이 과정이 한번에 일어나기 때문에 두 개를 따로 구분하는 게 큰 의미가 없다고 한다.)
마지막으로 이 과정을 정리한 순서는 다음과 같다.

Viewport Transform
지금까지 어떤 물체를 2x2x1이라는 cube space안에 넣어준거라면, 이제 이 친구를 스크린에 보여주는 것이 최종 목적이다. 따라서 screen coordinate로 옮겨주도록 하자. Dx에서, 이러한 viewport array는 rasterization stage를 수행하기 위해 사용된다. viewport는 3D scene이 투영되는 two-dimensional rectangle 영역이다.
In Microsoft's document, a viewport structure is described as follows:
typedef struct D3D12_VIEWPORT {
FLOAT TopLeftX;
FLOAT TopLeftY;
FLOAT Width;
FLOAT Height;
FLOAT MinDepth;
FLOAT MaxDepth;
} D3D12_VIEWPORT;
이렇게 3가지 function을 통해 screen space까지 넘어오게 되었다. 마지막으로 additional한 연산. . . face culling에 대해 알아보자.
Face Culling
primitive는 vertices의 순서에 따라 어디를 바라보는지가 결정된다. 이렇게 primitive의 특정한 facing 중
이렇게 face culling까지 수행해서 필요없는 걸 다 버렸다면, 이제 pixel을 만들어 내부를 채워보도록 하자 ~
Rasterization
Rasterization stage의 main role은 vector information을 raster image로 바꾸는 것이다.
하나의 primitive를 rasterizing하는 것은 다음 두 개의 파트로 구성된다 :
먼저 삼각형을 모니터라는 grid 위에 놓고, 삼각형이 차지하는 부분에 대해서는 pixel data가 색으로 결정되어야 하므로 이를 생성해준다. 이건 이후 pixel shader에서 최종 색을 결정해 렌더링될 것. 동시에 (x,y,z)만 만들어주는 것이 아니라, 이 친구가 어느정도의 깊이에 있는지 depth를 만들어준다.
이 과정에서 점들이 삼각형 안에 있는지는 Edge equation을 통해 판단한다.
다음과 같이 2D plane을 두 파트로 나누는 line이 있다고 가정해보자. 여기서 Edge equation은 주어진 point가 주어진 line을 기준으로 오른쪽에 있는지, 왼쪽에 있는지를 리턴해주는 함수이다. 리턴값은 left side인 경우 negative number, right는 positive, on line이라면 0이다.

'☃️ Study > Graphics' 카테고리의 다른 글
| Output-Merging (0) | 2023.11.08 |
|---|---|
| Input Assembler & Vertex Processing (0) | 2023.10.16 |
| [CG] Meshing and Geometry (0) | 2023.05.02 |
| [CG] Optics & Lighting (0) | 2023.04.25 |
| [CG] Viewings (0) | 2023.04.25 |
댓글