본문 바로가기
DirectX11/정보정리

[DirectX11] 렌더링 파이프라인(2)

by 마두식 2022. 11. 5.
반응형

※  아래의 내용들은 DirectX 11을 이용한 3D 게임 프로그래밍 입문 책의 내용을 바탕으로 작성된 것입니다.

 

렌더링 파이프라인
  • 렌더링 파이프라인은 현재 가상 카메라에 비친 3차원 장면의 모습에 근거해서 2차원 이미지를 생성하는 데 필요한 일련의 단계 전체를 의미한다.

 

  • 렌더링 파이프라인 순서
  1. 입력 조절기(IA) 단계
  2. 정점 셰이더(VS) 단계
  3. 덮개 셰이더(HS) 단계
  4. 테셀레이터 단계
  5. 영역 셰이더(DS) 단계
  6. 기하 셰이더(GS) 단계
  7. 스트림 출력(SO) 단계
  8. 레스터화기 단계
  9. 픽셀 셰이더(PS) 단계
  10. 출력 병합기(OM) 단계

 

  • 정점 셰이더(VS) 단계

-  최종적으로 화면에 표시되는 것은 2차원 이미지이다.

=>  3차원 장면에 가상의 카메라를 배치해야 한다.
=>  카메라는 세계에서 관찰자가 볼 수 있는 영역 즉, 세계에서 2차원 이미지를 생성해야 하는 영역을 결정한다.


-  카메라에 국소 좌표계를 부여한다고 했을 때, 해당 좌표계가 바로 시야공간(view space)으로, 시점 공간(eye space) 또는 카메라 공간(camera space)라고 부르기도 한다.

=>  카메라는 해당 공간의 원점에 놓여서 양의 z축을 바라본다.
=>  x축은 카메라의 오른쪽 방향, y축은 카메라의 위쪽 방향이다.


-  세계 공간에서 시야 공간으로의 좌표 변경 변환을 시야 변환(view transform)이라고 부르며, 해당 변환 행렬을 시야 행렬(view matrix)라고 부른다.

-  한 변환의 역변환을 위한 행렬은 해당 변환 행렬의 역행렬이다.

=>  일반적으로 세계 좌표계와 시야 좌표계는 위치와 방향만 다르므로, W = RT 라고 두어도 무방하다
=>  W의 역행렬을 구하면 시야 행렬이 된다.(185p)


-  카메라의 위치와 대상점, 그리고 세계 상향 벡터만 있으면 그 카메라를 서술하는 국소 좌표계를 유도할 수 있으며, 그것을 이용해서 시야 행렬을 구할 수 있다.(186p)

=>  XNA Math 라이브러리는 위의 절차를 따라 시야 행렬을 계산하는 함수를 제공한다.
=>  일반적으로 세계의 y축이 위쪽 방향에 해당하므로 세계 상향 벡터는 거의 항상 (0, 1, 0)이다.


-  현재까지의 내용은 세계 공간 안의 카메라의 위치와 방향을 설명했고, 카메라를 서술하는 또다른 요소로 카메라가 바라보는 공간 영역이 있다.

-  카메라 시야 절두체 안의 3차원 기하구조를 2차원 투영 창으로 투영해야 한다.

-  원근 투영(perspective projection)

=>  3차원의 느낌을 주기 위해 이 투영은 반드시 평행선들이 하나의 소실점으로 수렴하는 방식으로 이루어져야 한다.
=>  그래야 물체의 3차원 깊이가 증가함에 따라 투영 결과의 크기가 줄어드는 현상이 나타난다.


-  정점에서 시점으로의 직선을 정점의 투영선(line of projection)이라 한다.

-  원근투영 변환은 하나의 3차원 정점 v를 투영선이 2차원 투영 평면과 만나는 v'으로 변환하는 변환이다.

=>  v'를 v의 투영이라고 부른다.
=>  3차원 물체를 2차원 평면에 투영한다는 것은 물체를 구성하는 모든 정점을 투영하는 것을 말한다.


-  절두체의 정의(5.6.3.1절 188p)

-  투영 창의 크기가 종횡비에 의존하게 되면, 하드웨어가 투영 창의 크기에 관여하는 연산(투영 창을 후면 버퍼에 사상하는 등)을 수행하기 위해 하드웨어에게 종횡비를 알려주어야 한다.

=>  종횡비에 대한 이런 의존성을 없앨 수 있다면 작업이 더 수월해진다.


-  정규화된 장치 좌표(normalized device coordinates, NDC)(5.6.3.3절 190p)

-  NDC 좌표에서는 투영 창의 크기가 고정되므로 하드웨어는 종횡비를 몰라도 된다.

=>  그래픽 하드웨어는 투영된 좌표들이 NDC 공간 기준이라고 가정하므로, 프로그래머는 항상 실제로 NDC 공간을 기준으로 한 투영 좌표들을 공급하는 데 신경을 써야 한다.


-  일관성을 위해 투영 변환을 하나의 행렬로 표현하는 것이 좋다.

-  원근 나누기(perspective divide)(= 동차나누기(homogeneous divide)) (5.6.3.4절 192p)

-  z값 정규화

=>  Direct3D는 투영된 x, y 좌표가 정규화된 범위이길 요구한다.
=>  앞에서 x, y는 정규화를 끝냈지만 깊이 성분인 z는 아직 정규화 되지 않았다.
=>  구간 [n, f]를 [0, 1]로 사상하는 순서 보존 함수 g(z)를 구축할 필요가 있다.
=>  순서 보존 함수란 깊이 값들을 변환해도 깊이 값들의 상대적 관계는 유지되는 함수를 뜻한다.
ex) z1 < z2 이면 g(z1) < g(z2)
=>  순서 보존 함수이기 때문에 정규화된 구간의 깊이들을 비교했을 때에도 정확한 결과(가려짐 여부)를 얻을 수 있다.
※  깊이 버퍼링 알고리즘에서 중요한 것은 깊이들 사이의 상대적 관계뿐이다.


-  깊이 버퍼에도 정밀도 문제(유한한 수치 표현 때문에, 변환된 두 깊이 값이 약간만 다른 경우 컴퓨터가 그 둘을 구분하지 못하는 것)가 발생할 수 있다.

=>  가까운 평면과 먼 평면을 최대한 가깝게 해서 깊이 정밀도 문제를 최소화 하는 것이 좋다.


-  원근투영 행렬을 곱한 후의(원근 나누기는 수행하기 전의) 기하구조를 가리켜 동차 절단 공간(homogeneous clip space) 또는 투영 공간에 있다고 말한다.

=>  원근 나누기를 수행한 후의 기하구조를 가리켜 정규화된 장치 좌표(NDC) 공간에 있다고 말한다.


-  XNA Math 라이브러리는 원근투영 행렬을 구축해주는 함수를 제공한다.

 

  • 테셀레이터 단계

-  테셀레이션이란 한 메시의 삼각형들을 더 잘게 쪼개서 새로운 삼각형들을 만드는 과정을 말한다.

=>  새 삼각형들을 새로운 위치로 이동함으로써 좀 더 세밀한 메시를 만들어 낼 수 있다.


-  테셀레이션의 장점

1.  카메라에 가까운 삼각형들에는 테셀레이션을 적용해 세부도를 높이고, 먼 삼각형들에는 테셀레이션을 적용하지 않는 방식의 세부수준(level-of-detail, LOD) 메커니즘 구현이 가능하다.
2.  메모리에는 저다각형(low-poly) 메시 즉, 적은 수의 삼각형들로 이루어진 메시를 담고 즉석에서 삼각형들을 추가함으로써 메모리를 적용할 수 있다.
3.  애니메이션이나 물리 처리 같은 연산들은 단순한 저다각형 메시에 대해 수행하고, 테셀레이션 된 고다각형 메시는 렌더링에만 사용함으로써 계산량을 줄일 수 있다.


-  Direct3D 11에 새로이 추가된 테셀레이션 단계들은 GPU에서 기하구조를 테셀레이션하는 수단을 제공한다.

=>  D3D 11 이전에는 테셀레이션을 구현하려면 CPU에서 삼각형들을 분할해서 새 기하구조를 만들고 그것을 다시 GPU에 올려서 렌더링 해야했다.
=>  새 기하구조를 CPU 메모리에서 GPU 메모리로 올리는 것은 느린 연산이다.
=>  CPU에서 테셀레이션을 계산하는 것은 CPU에 부담이 된다.
=>  D3D 11은 테셀레이션을 전적으로 하드웨어, 즉 D3D 11 대응 장치에서 수행하도록 하는 API를 제공한다.


-  테셀레이션 단계는 생략 가능하다(원할 때만 사용하면 된다)

 

  • 기하 셰이더(GS) 단계

-  기하 셰이더 단계는 생략 가능하다.

-  기하 셰이더는 하나의 온전한 기본도형을 입력받아서 임의로 변형한다.

-  기하 셰이더의 주된 장점은 기하구조를 생성하거나 파괴할 수 있다는 것이다.

=>  정점 셰이더는 항상 정점 하나를 받아서 정점 하나를 출력한다.
=>  기하셰이더는 입력 기본도형을 다른 여러 기본도형들로 확장하거나, 폐기할 수도 있다. 이는, 정점 셰이더와는 대조되는 특징이다.


-  기하셰이더의 흔한 용도는 하나의 점이나 선분을 하나의 사각형으로 확장하는 것이다.

-  기하 셰이더의 출력 정점 자료를 스트림 출력 단계를 통해 메모리의 버퍼에 저장해두고 나중에 활용하는 것이 가능하다.

 

  • 절단

-  시야 절두체를 완전히 벗어난 기하구조는 폐기, 절두체의 경계면과 교차하는 기하구조는 절두체 내부의 것만 남도록 잘라내야 한다.

=>  이를 절단(clipping) 연산이라고 부른다.


-  절단 연산은 하드웨어가 수행해준다.

=>  서덜런드-호지먼 절단 알고리즘

 

  • 레스터화기 단계

-  래스터화 단계(rasterization stage)라고도 하는 래스터화기 단계(rasterizer stage)의 주 임무는 투영된 3차원 삼각형으로부터 픽셀 색상들을 계산해내는 것이다.

-  뷰포트 변환(5.10.1절 199p)

-  후면 선별(5.10.2절 199p)

=>  삼각형은 2개의 면을 가진다.
==>  삼각형의 앞쪽 면을 보고있는 경우 전면(front-facing) 삼각형
==>  삼각형의 뒤쪽 면을 보고있는 경우 후면(back-facing) 삼각형

 

=>  Direct3D가 사용하는 관례에서 관찰자를 기준으로 시계방향 순서의 삼각형은 전면이고 반시계방향 순서의 삼각형은 후면이다.
※  여기서 순서란 정점의 순서를 의미한다.
※  Direct3D 렌더 상태의 설정에 따라서는 반대의 방식으로도 가능하다.

=>  전면 삼각형들이 후면 삼각형들을 가리므로 후면 삼각형들은 그릴 필요가 없다.
=>  후면 선별(backface culling 또는 후면 제외)은 파이프라인에서 그러한 후면 삼각형을 골라서 폐기하는 공정이다.
=>  후면 선별을 바탕으로 처리해야 할 삼각형의 수가 거의 절반으로 줄어들 수 있다.


-  정점 특성의 보간(5.10.3절 201p)

=>  정점 자료에는 위치, 색상, 법선 벡터, 텍스처 좌표 등 추가적인 특성을 붙일 수 있다.
=>  뷰포트 변환을 거친 후에는 정점의 특성들을 삼각형을 덮는 각 픽셀에 대해 보간해야 한다.
=>  정점 특성들 뿐만 아니라 정점의 깊이값도 그런 식으로 보간해야 한다.
=>  원근 보정 보간(perspective correct interpolation)
==>  원근 보정 보간은 하드웨어가 수행하는 것이므로 자세한 원리는 알 필요가 없다.

 

  • 픽셀 셰이더(PS) 단계

-  픽셀 셰이더(pixel shader, PS)는 프로그래머가 작성해서 GPU에서 실행하는 프로그램이다.

-  픽셀 셰이더는 각각의 픽셀 단편(pixel fragment)마다 실행된다.

-  기본적으로 픽셀 셰이더는 보간된 정점 특성들을 입력받아서 하나의 색상을 출력한다.

 

  • 출력 병합기(OM) 단계

-  픽셀 셰이더가 생성한 픽셀 단편들은 렌더링 파이프라인의 출력 병합기(output merger, OM) 단계로 입력된다.

-  출력 병합기 단계에서 일부 픽셀 단편들이 기각(폐기)된다.

=>  깊이 판정이나 스텐실 판정에 의해
=>  기각되지 않은 픽셀 단편은 후면 버퍼에 기록된다.


-  혼합(blending)도 이 단계에서 발생한다.

=>  혼합이란 새 픽셀이 후면 버퍼의 기존 픽셀을 완전히 덮어 쓰는 것이 아니라 두 픽셀을 일정한 공식에 따라 혼합한 결과를 기록하는 것을 말한다.
=>  혼합은 반투명 같은 특수 효과를 내는데 사용된다.

 

  • 요약

-  3차원 장면의 기하학적 서술과 그 장면 안에 놓인 가상 카메라의 위치와 방향이 주어졌을 때, 현재 가상 카메라에 비친 3차원 장면의 모습에 근거해서 2차원 이미지(모니터에 표시할 수 있는)를 생성하는데 필요한 일련의 단계들 전체를 렌더링 파이프라인 이라고 한다.

-  렌더링 파이프라인은 크게 보아 다음과 같은 단계들로 구성된다.

1. 입력 조립기(IA) 단계
2. 정점 셰이더(VS) 단계
3. 테셀레이션 단계들
4. 기하 셰이더(GS) 단계
5. 절단 단계
6. 래스터화기(RS) 단계
7. 픽셀 셰이더(PS) 단계
8. 출력 병합기(OM) 단계

 

 

 


 

 

 

틀린 부분이나 이상한 부분이 있으면 댓글로 편하게 지적해주세요.

감사합니다!

반응형

'DirectX11 > 정보정리' 카테고리의 다른 글

[DirectX11] 효과 프레임워크  (0) 2022.11.08
[DirectX11] 정점 버퍼와 색인 버퍼  (0) 2022.11.07
[DirectX11] 렌더링 파이프라인(1)  (0) 2022.11.03
[DirectX11] 색상  (0) 2022.11.03
[DirectX11] DirectX3D 초기화(2)  (0) 2022.10.28

댓글