🎨DirectX

[DX] 렌더링 파이프라인, 공간변환

공대 컴린이 2023. 2. 4. 18:25
728x90

🎨 렌더링 파이프라인

파이프라인이라는 것은 한 정점이 어떤 과정을 거쳐서 렌더링 될 수 있는지(그려지는지)를 나타낸 과정이다.

IA → VS → RS → PS → OM

🔸 IA (Input Assembly, 입력 조립)

  • 렌더링 할 데이터를 집어넣는 과정으로 정점(Vertex Buffer)과 Primitive Topology 설정한다.
  • GPU가 CPU로부터 정점 데이터를 전달 받아서 프리미티브(삼각형)들을 만든다.
  • 정점 데이터를 CPU에서 GPU로 운반하기 위한 자료구조를 정점 버퍼(Vertex Buffer)라고 한다.
  • 정점 버퍼는 Position, Normal, Color, UV 정보를 직렬화된 배열 형태로 담고 있다.
  • GPU에서는 미리 전달받은 정점 버퍼의 정점들을 모아서 정점 데이터로 조립하는 것이 아닌, 삼각형과 같은 기본 도형(Primitive)로 조립해주기 때문에 입력 조립 단계라고 칭한다.
  • 이렇게 조립된 프리미티브가 정점 쉐이더의 입력(Input)이 된다.

🔸 VS (Vertex Shader, 정점 쉐이더)

  • 정점 데이터를 입력 받아 공간 변환을 수행한다.
  • Object Space에서 Clip Space까지 정점들의 공간 변환을 수행한다.

🔀 공간변환

 

공간 변환 과정

  • 공간 변환은 각각 행렬 연산을 통해 이루어지는데, 변환 행렬은 Model(World), View, Projection 총 3가지이다.
  • M, V, P는 변환 행렬의 이름이자, 변환 자체를 가리킨다.

M (Model)

  • 오브젝트 공간(Model Space, Object Space) -> 월드 공간(World Space)
  • 각 오브젝트마다 자신의 피벗 위치를 원점(0, 0, 0)으로 하는 좌표 공간을 갖고 있다.
  • 모델 변환은 각 오브젝트의 좌표 공간을 변환하여 하나의 월드 공간에 통합하는 과정이다.
  • 이 과정에서 이동(Translate), 회전(Rotate), 크기(Scale)변환이 이루어진다.
  • 이 세가지 변환은 각각 행렬을 통해 수행되고, 이를 하나의 행렬로 만든 것을 TRS 행렬이라고 한다.
  • TRS 행렬은 좌측부터 우측으로 S, R, T 순서로 곱해진다.

 V (View)

  • 월드 공간(World Space) -> 카메라 공간(View Space)

DirectX 좌표축

  • 카메라 공간은 카메라의 위치가 원점(0, 0, 0)이고, 카메라가 바라보는 방향이 +Z축인 공간을 의미한다.
  • 뷰 변환은 모든 오브젝트를 화면에 그려내기 쉽도록 카메라 기준으로 공간을 변환하는 과정이다.
  • 언리얼과 DirectX의 좌표축은 다르기 때문에 헷갈리지 말자!

P (Projection)

  • 카메라 공간(View Space) -> 클립 공간(Clip Space)
  • 카메라 기준의 정점 위치를 화면에 보이기 위한 정점 위치로 변환한다.
  • 화면에 렌더링될 수 있는 영역을 나타내는 절두체(Frustum)가 정의된다.
  • 절두체는 Near Clipping PlaneFar Clipping PlaneField of View를 통해 정의한다.
  • 절두체를 완전히 벗어나는 폴리곤들은 모두 버려지고 절두체의 경계에 걸쳐 있는 폴리곤들은 일단 유지한다.
  • 원근감이 없는 직교 투영(Orthographic Projection) 또는 원근감이 있는 원근 투영(Perspective Projection)이 행해진다.
  • 클립 공간의 좌표계는 사실 3D가 아닌 4D이다.
  • 클립 공간의 모든 X, Y 좌표는 -1 ~ 1 범위에 존재하며, Z 좌표는 0 ~ 1 범위에 존재한다.

🔸 RS (Rasterizer, 래스터라이저)

  • 3D 공간을 2D로 변환하는 것
  • Clip Space의 정점 데이터를 Viewport로 변환하고, 정점 데이터를 기반으로 보간된 프래그먼트(픽셀 데이터)를 생성한다.
  • 클립 스페이스의 정점 데이터를 전달받아 프래그먼트를 구성하고, 화면에 출력할 픽셀들을 찾아낸다.
  • 픽셀 색상 등의 데이터는 정점의 데이터를 기준으로 보간된다.
  • 프래그먼트(Fragnemt)?
    • 픽셀 하나의 색상을 화면에 그려내기 위한 정보를 담고 있는 데이터
  • 래스터라이저에서는 클립 스페이스 좌표의 모든 요소를 w값으로 나누면서 모든 원근법이 구현이 완료되며 이를 원근 분할이라고 한다.
  • 원근 분할을 마친 좌표계가 바로 NDC 좌표계이다.
  • 3D NDC 공간 상의 좌표를 2D 스크린 좌표로 변환하는 뷰포트 변환 과정을 수행한다.
  • -1 ~ 1 범위였던 (x, y)좌표를 화면 해상도 범위로 변환한다.

🔸 PS (Pixel Shader, 픽셀 쉐이더)

  • 변화된 공간을 Pixel 쉐이더로 처리하는 것
  • 픽셀 쉐이더는 모델이 화면에서 차지하는 픽셀의 개수만큼 실행된다.
  • 프래그먼트를 입력 받아 화면에 그려질 모든 픽셀의 색상과 깊이 값을 출력한다.
  • 쉐이더를 통해 색상을 변화시키는 것은 모두 픽셀 쉐이더의 역할이라고 보면 된다.
  • 투명도를 결정 하는 것도 픽셀 쉐이더, 라이팅과 그림자를 적용하는 것도 픽셀 쉐이더, 텍스쳐 색상을 메시에 입히는 것도 모두 픽셀 쉐이더에서 하는 역할이다.
  • 픽셀 쉐이더는 각 픽셀들의 색상과 깊이 값을 출력으로 전달한다.
  • 깊이 값은 Z-Buffer에, 색상 값은 Color Buffer에 저장된다.
  • 그리고 이런 버퍼들을 통칭하여 스크린 버퍼(Screen Buffer)라고 한다.

🔸 OM (Output Merge, 출력 병합)

  • 픽셀들을 화면에 출력하기 위한 마지막 연산들을 수행한다.
    • Z-Test
    • Stencil Test
    • Alpha Blending
  • 출력 병합 단계에서는 이렇게 겹치는 픽셀들을 연산 및 판단하여 픽셀의 최종적인 색상을 결정한다.

참조

https://rito15.github.io/posts/rendering-pipeline/

 

렌더링 파이프라인 간단 정리

렌더링 파이프라인 구조 요약(DirectX 9 기준)

rito15.github.io

 

728x90