Direct3D 12 graphics Pipeline

이중에서 오늘 알아볼 단계는 Rasterizer다. Shader와 달리 하드웨어로 고정된 연산이 이루어지고, 따로 프로그래밍이 불가능하다.

 

 

Rasterizer

 

◇  primitive를 2차원 이미지 요소(pixels)로 분할한다.

 

앞선 vertex shader가 vectex들을 clip space로 옮긴 후에 rasterizer에게 넘겨준다.

이후 raterizer는 크게 5가지의 역할을 수행한다.

  • Primitive Clipping
  • Perspective division
  • Back-face culling
  • Viewport transform
  • Rasterization

요약하면 primitive를 pixel로 쪼개고, pixel 마다 필요한 data들을 넣어준다. 그리고 pixel shader가 연산량이 많기 때문에 이전에 불필요한 pixel들을 제거해주는 역할도 하게 된다.

 

 

Primitive Clipping

◇  안보이는(= clipping volume 밖) primitive 자르기

  • 이전 포스팅에서 설명했듯이 사다리꼴 모양이 아닌 clipping volume을 기준으로 일어난다.
  • 점(Point), 선(Line), 삼각형(Triangle)에 따라 겹쳤을 때의 처리 방식이 조금씩 다르다.
  • Point : 크기가 1 pixel보다 클 경우에 중점을 체크해서 버릴 지 결정
  • Line : 새로운 vertex 생성 후 자르기
  • Triangle : 경계선에 vertex를 생성하고 자르기

 


Perspective Division

◇  w로 나누기를 통해 원근 구현 

  • homogeneous(clip) 좌표를 Cartesian 좌표로 변환하는 과정에서 모든 좌표를 w로 나눈다 (이때 w = z) 
  • 아래 사진을 보면 연산 후에는 camera에 멀리 떨어져있던 선분이 더 짧아지게 된다.
  • 이 결과로 얻은 좌표를 NDC(Normalized Device Coordinates)라고 부른다.

 

 

 


Viewport 

◇  실제 window에서 내가 그림을 그릴 영역  

  • screen space, viewport 모두 3차원 공간이다. (DirectX = 2×2×1/OpenGL = 2×2×2)
  • 아래처럼 여러가지 변수들로 Viewport를 정의한다.  

 

 

 

 

Viewport Transform

◇  NDC space에서 window space로 변환하는 과정

  • Perspective Division을 해서 원근까지 표현했지만, 그 값들은 camera가 보는 시점에서 기준이다.
  • 이 단계에서 모니터의 비율에 맞게 NDC 좌표들을 변환하게 된다.
  • scaling과 translation을 통해 계산된다.

 

  • 보통의 경우 vieport가 전체 모니터 스크린을 의미하기 때문에 아래 값을 대입해주면 깔끔한 matrix가 나온다.
  • TopLeftx = 0, TopLeftY = 0, MinDepth = 0, MaxDepth = 1 

scaling과 translation을 적용한 최종 matrix

 

 

 

 

Back-face Culling

 

◇  Camera를 등지고 있는 면들을 없애버리자!

  • camera 기준 3D 오브젝트의 뒷면에 해당하는 부분은 보이지 않기 때문에 Culling을 해준다.
  • GPU 비용이 비싼 Rasterization, Pixel Shader 단계 전에 제거해준다.
  • 삼각형의 앞면/뒷면 여부는 삼각형의 vectex 순서로 결정된다.

  • 위 사진을 참고하면 Projection Transform 이후에는 모든 projection line이 z축과 평행하게 된다.
  • 삼각형을 xy 평면에 투영한 뒤 간단한 행렬식을 계산하여 front/back을 판단한다.
  • 행렬식 < 0 = Front face = CW
  • 행렬식 > 0  = Back face = CCW
  • 행렬식 = 0  =  edge on

  • 이 행렬식은 사실 두 edge vector의 외적이다. 즉, normal vector의 방향을 나타낸다고 볼 수 있다.
  • 따라서 행렬식의 부호에 따라 해당 삼각형이 바라보는 방향을 판단할 수 있다. 

 

◇  만약 반투명 물체라면? 

  • 반투명일 경우 back face를 날려버리면 안된다.
  • DirectX에서는 Rasterizer 상태에서 cull mode를 설정해서 옵션을 변경할 수 있다.
  • None : 아무것도 제거 X
  • Front : front face 제거 = 내부 단면을 보이게 한다.
  • Back : 일반적인 back face culling (DirectX 기본 설정)

 

 

 

 

 

Rasterization 

◇  vector 정보를 pixel로 쪼개자!

  • 크게 두가지 단계로 진행된다.
  • 1) 그리드에서 어떤 픽셀들이 삼각형에 포함되어있는지 확인한다. (Edge Equation 활용)
  • 2) 선택된 픽셀마다 color와 depth value 정보를 넣어준다. 
  • 이후 pixel shader가 나중에 최종 색 렌더링을 한다.

 

 

Edge Equation 

◇  픽셀이 삼각형 안에 포함되는 지를 판단할 때 사용 

  • point가 왼쪽에 있는 경우 : negative number(음수)
  • point가 오른쪽에 있는 경우 : positive number(양수)
  • point가 line 위에 있는 경우 : zero number

  • point가 삼각형 내부에 있다면 모든 edge들에 right side에 위치한 것이다.
  • 즉, 세 개의 edge모두 edge function이 양수를 return한 경우이다.
  • 함수에 대해 좀 더 설명해보자면,, E =  A x B = A와 B의 외적이다.
  • A = v1 - v0, B = p - v0 (아래 사진에서 파란색, 초록색으로 표시되어있다.)
  • 외적을 했을 때 아래와 같은 성질 때문에, 결과의 부호로 p의 위치를 판단할 수 있다.
  • 0 < θ < 180 : positive value
  • 180 < θ < 360 : negative value

 

 

 

 

Attribute Interpolation

◇  fragment(pixel)에 속성값(color,depth,normal 등)을 보간해서 부여하자! 

  • 삼각형 내부 점은 세 꼭짓점의 가중합으로 표현 가능
  • C0, C1, C2 = 꼭짓점 색상
  • p = 내부 픽셀
  • 𝜆0, 𝜆1, 𝜆2 = 픽셀 p가 삼각형 내에서 얼마나 각 꼭짓점에 가까운지를 나타내는 가중치

 

 

 

Barycentric coordinate (중심 좌표계)

 

◇  픽셀 p에 대한 𝜆0, 𝜆1, 𝜆2를 구하는 수학적인 방법 (Edge Equation 활용)

  • T : 전체 삼각형 면적
  • 예를 들어) T0 = area(p,v1,v2) , λ0 = p가 v0쪽에 얼마나 가까운지를 의미한다.

  • 이때 T0 = 0.5 ∗ E(p, v1 , v2) 이다! 왜냐면 Edge Equation은 외적, 즉 평행사변형의 넓이를 의미하기 때문에 반띵만 해주면 된다. 0.5는 약분되어 사라지고, 아래와 같은 식이 완성된다.

 

 

 

Rasterization Rule (Top-left Rule)

◇  겹치는 픽셀이 있을 때 한쪽만 포함 시키자!

  • 삼각형의 edge가 겹칠 때, 겹치는 픽셀이 두 번 계산되지 않도록 처리해야 한다.
  • 겹치는 edge를 기준으로 left edge와 top edge를 선택하게 된다.

 

 

 

 

Reference KHU 강형엽 교수님 강의를 수강하며 정리한 내용입니다.

+ Recent posts