ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [48] - Rasterization
    Graphics 2021. 8. 13. 22:30

    Rasterization

    figure 1a

    Texture에 대한 공부를 하려면 Rasterization Stage에 대한 공부를 해야 합니다. Rasterization 전 단계까지 예를 들어서 정점[Vertex]이 여덟 개인 육면체를 CPU로부터 넘겨받았다고 가정하겠습니다. IA Stage에서 받은 이 Vertex들은 삼각형의 조각으로 정리가 됩니다. 한첨 전에 배운 것을 떠올려 보면 Vertex의 stride를 정의하고 Description을 정의하던 파트가 분명 존재했습니다.

    figure 1b

    figure 1b의 ByteWidth, StrcutureByteStride와 같은 Description을 통해서 버퍼의 정보를 정해주어 전달을 받은 Vertex를삼각형으로 재구성합니다. 

    figure 1c
    figure 1d
    figure 1e

    이렇게 처리된 Vertex들을 Rasterization 단계에 이르면 Sampling을 진행합니다. Sampling을 한다는 것은 CPU에서 넘겨 받은 삼각형 하나 안에  Fragment라는 데이터의 군집으로 채워 넣는다는 뜻입니다. 

    "In Computer Graphics, a sample is an intersection of channel and a pixel."

    그렇기 때문에 Primitive Assembly - Rasterization 이후에 Fragment Shader라는 단계가 옵니다. 이 Fragment를 조정하기 위함입니다. D3D에서는 Fragment shader가 아닌 Pixel shader라는 이름을 갖고 있으며 이 둘은 거의 비슷한 기능을 수행합니다. 

    Fragment가 정점들 사이를 채운다고 했습니다. 그리고 Pixel shader, Fragment shader는 이 데이터들이 어떤 식으로 표현될 것인지를 결정하는 한편 Vertex Shader는 이 정점들의 표현을 관리합니다.

     OpenGL과 D3D는 마치 거대한 차이가 있는 것처럼 보입니다. 이 차이는 그저 API 수준의 차이에 불과하며 GPU Rendering Pipeline의 추상적 구현에 불과합니다. 이에 관해서는 날짜가 오래되긴 했으나 아래의 블로그의 글을 읽어보면 OpengGL과 D3D의 차이가 어떤 의미에서 '차이'라고 하는지 이해하는데 도움이 됩니다. 각 단계들이 수행하는 일을 유심히 읽어보면 둘이 크게 다르지 않다는 사실을 알아차릴 수 있습니다. 

    (A trip through the Graphics Pipeline 2011: Index | The ryg blog (wordpress.com))

    (Direct3D vs. OpenGL: comparison (xmission.com))

     

     Rasterization은 크게 두 파트로 나누어 집니다. 하나는 Window Coordinates 내에서 어떤 부분부터 어디까지 Pixel을 차지하고 있는 것인지 파악합니다. 즉, 다음과 같은 그림처럼 세 개의 정점으로 만든 삼각형 내에 어떤 Pixel이 들어오는지 판단합니다.

    이러면 총 11개의 Fragment가 생성되었다고 할 수 있습니다. 다음 파트에서 세 정점으로 둘러싸인 영역에 포함되는 11개의 Fragment는 Attributes ( e.g, Colour, Depth)을 설정해줍니다. 

    만약, 육면체를 GPU에 넣었다고 가정하면 총 8개의 Vertex가 들어오게 되는데, Position, Normal, Colour의 정보도 함께 갖고 있습니다. 이 정보들이 파이프 라인에 따라 처리되면서 결국 최종적인 Screen 상의 좌표가 계산됩니다. 이 좌표를 갖고 Fragment를 생성합니다. 그리고 이 정보를 갖고 Arrtibutes를 할당해줍니다. 

     

    Rasterization 첫 번째 파트 입장에선 Vertex 내에 어떤 Pixel이 실제로 들어왔다고 판단할 수 있는지 계산할 논리가 필요합니다. 이 계산을 도와주는 방정식을 Edge Equation이라고 합니다. 크게 어려운 논리는 아닙니다. 

    Edge Equation

    이 그림과 같이 Window를 좌우로 나누는 직선이 하나 존재한다고 가정합니다. 그리고 이 직선을 기준으로 점이 어느 쪽에 속하는지 Edge Equation이 검증합니다. 

    그래서 좌측 그림과 같은 점은 Edge Equation에 의해서 임의의 양수를 반환, 좌측에 속하는 점은 음수, 그리고 중앙에 위치한 점은 0을 반환하게 설계가 되어 있습니다. 

    이러면 어떤 한 점에 대해서 세 개의 Vertex로 둘러싸인 점이 삼각형 내부인지 외부인지 판단할 수 있습니다. 

     

    v0, v1, v2 총 세 개의 Vertex를 갖는 삼각형이 존재하고 어떤 Pixel이 안에 위치를 하는지 계산을 해야합니다. v0에서 v1으로 향하는 직선이 하나, v1에서 v2, v2에서 v3로 향하는 직선이 그어질 것입니다.

    이때, Pixel P가 삼각형 안에 존재하는지 아닌지는 이 모든 직선에 대해서 '우측'이 위치하는지 아닌지 확인하여 판단합니다. 

    Edge Equation을 통해서 어떤 Pixel P의 상태를 판단하는 함수를 E(P, v_a, v_b)라고 하겠습니다. 그럼 한 삼각형에 대해서 세 개의 Edge Equation이 필요할 것입니다. 그럼 한 픽셀에 대해서 다음과 같이 계산이 될 수 있을 것입니다. 

     

    이 계산은 아직 왜 Edge Equation이 각각의 값을 반환하는지 설명하기엔 부족합니다. 설명을 위한 전초전에 불과합니다.

    Edge Equation을 다르게 해석하는 방법도 있습니다.

    Assigning Attributes for Fragments

    위의 과정을 통해 삼각형이 차지하는 Pixel들을 찾고 Fragment를 결정할 수 있습니다. 이전까지는 우리가 갖고 있는 정보는 삼각형의 각 Vertex에 불과했으나 이제는 생성된 Fragment에 대한 정보도 생성을 해주어야 합니다. 이 정보는 각 Vertex의 정보를 참조하여 결정합니다. 그리고 이를 결정할 때는 Barycentric Coordinate라는 것을 사용합니다. 아래의 식이 한 Fragment의 정보를 결정하는 Barycentric Coordinate입니다.

    figure 2a

    이때 람다 값에 대해서 Weight라는 표현을 쓰기도 합니다. weight를 통해서 fragment는 barycentric coordinate상에서 정보를 갖게 됩니다. 그리고 이 Weight는 삼각형 내의 어떤 영역에 비례하는 값을 갖습니다.

    그래서 이 정보를 토대로 Weight를 어떻게 결정하는가 하면 Edge Equation을 응용하면 금방 찾을 수 있습니다. Edge Equation은 두 벡터의 Cross Product였습니다. 가령, T0의 경우엔 v1-P 벡터와 v1-v2 벡터의 cross product에 0.5를 곱해주면 넓이를 구할 수 있다는 뜻입니다. 이걸 수식으로 정리하면 다음과 같습니다.

    Weight의 값은 삼각형의 넓이에 비례한다고 했습니다. 즉, 전체 삼각형에 대한 각 삼각형의 비율을 값으로 갖는 것입니다. 따라서 다음과 같이 Weight를 결정할 수 있습니다.

    감탄만 나옵니다. Edge Equation만 구했을 뿐인데 많은 문제들을 해결했습니다. 

    Rasterization Rule ( Top-Left Rule )

    어떤 픽셀은 두 개의 삼각형의 경계에 있을 수 있습니다. 만약 제대로 된 규칙이 존재하지 않는다면 일반적으로 이 픽셀은 두 번 처리가 될 것입니다. 그런 일을 방지하기 위해 약간의 규칙이 존재합니다. 

    figure 2b

     

    실질적으로 수 많은 삼각형을 처리하다 보면 반드시 왼쪽 그림과 같이 겹치는 일이 있을 것입니다. 이때를 대비해서 figure 2b처럼 삼각형의 Edge에는 고유한 이름을 정의했습니다. 

    규칙의 이름처럼 Top-Left에 우선권이 주어집니다. t1과 t2의 엣지에 겹핀 픽셀들은 t1의 LEFT에 걸쳤기 때문에 LEFT가 RIGHT보다 우선순위가 높아 t1의 Rasterization을 따릅니다. 

    t2와 t3의 관계에서도 t3의 TOP이 t2의 Bottom보다 우선 순위가 높기 때문에 t3의 Rasterization에 떨어졌습니다.

     

    이렇게 Rasterization에 대한 전반적인 이론은 정리했습니다. 다음엔 Texture의 이론을 공부하고 나서 다시 D3D로 돌아가도록 합니다. 마지막은 간단한 예제입니다. 이 단계는 Rasterization Stage로 Hardwire 한 단계입니다. 우리가 간섭할 이유도 없고 하고 싶지도 않습니다. 이렇게 최적화가 잘 되어 있기 때문입니다.

    'Graphics' 카테고리의 다른 글

    [50] - Texture - 2  (0) 2021.08.26
    [49] - Texture - 1  (0) 2021.08.17
    [47] - Bindable/Drawable System - 3  (0) 2021.08.12
    [46] - std::optional  (0) 2021.08.12
    [45] - Multithreading Execution Policy  (0) 2021.08.11
Designed by Tistory.