Direct3D12

[DirectX12] 렌더링 파이프라인

태현123 2021. 7. 11. 18:30
728x90
반응형
SMALL

오늘 알아볼 내용은 DirectX12에서의 렌더링 파이프라인이다.

 

렌더링 파이프라인(Rendering Pipeline)이란?

- 3D 공간을 2D공간인 모니터(Screen Space)에 나타내기 위해 처리해주는 일련의 과정이다.

 

렌더링파이프라인 그림

빨간색은 Shader에서 GPU로 데이터 송신, 노란색은 GPU에서 Shader로 데이터 송신 부분이다.

 

각각의 Shader에서 어떤 일을 담당하는지 살펴본다.

 

InputAssembler(입력 조립기) : IA

- 정점의 정보를 응용 프로그램에서 전달받는다. 여기서 받은 정점 데이터를 다른 파이프라인에서 사용할 수 있도록 프리미티브(Primitive)로 조립한다.

Dx12 Topology

이 Primitive는 정점데이터를 어떤식으로 조립할지에 대한 정보이다.

조립형식

대강 이런식으로 조립한다.

 

VertexShader(정점 쉐이더) : VS

- 해당 좌표에 대하여 이동, 회전, 크기 변환과 같은 정점 정보의 연산과정을 수행한다.

정점 데이터를 GPU에서 받아와서 해당 데이터에 대해 정점연산을 수행해 준 다음에 VS_OUT 자료형으로 다음 파이프라인으로 넘겨준다.

Vertex Shader 코드

다음 쉐이더코드를 보면 VS_IN의 형식으로 GPU에서 데이터를 받아 VertexShader에서 offset만큼 더해주고 있다. 이런 식으로 정점 데이터에 대한 연산을 수행하여 VS_OUT형식의 데이터로 다음 파이프라인으로 넘겨주게 된다.

 

Rasterize(래스터화)

- 계산된 3D정점들을 2D화면에 뿌릴 수 있도록 2D화 시켜준다. 이 과정에서 클리핑, 원근나눗셈, 뒷면제거, 뷰포트 변환, 스캔 변환을 한다. 래스터라이저 단계는 프로그램 가능한 단계가 아니다.

클리핑 - 하드웨어로 구현되어 있고, 설정된 뷰 프러스텀에 들어와있으면 그리고, 들어와있지 않으면 안 그린다. 걸쳐 있는 경우, 바깥에 놓인 부분을 잘라낸다. 그러면, 클리핑 결과 잘린 부분에 정점이 추가되고 바깥 부분의 정점은 사라진다.

뒷면제거 - 삼각형의 정점과 카메라를 연결하는 벡터와 삼각형을 노멀이 가리키는 방향의 반대쪽에 존재할 경우 뒷면, 그렇지 않을경우 앞면으로 판단하여 뒷면을 제거한다. 이 때, 판단 방법은 두 벡터를 내적하여 양수일 경우 뒷면, 앞면일 경우 음수가 된다.

원근 나눗셈 - 정점 처리 과정에서 모든 정점이 클립 공간으로 넘어가고, 투영행렬에 의해 투영변환이 되었다. 이 때 값을 -z로 나눠준다. 이는 3차원 공간에서 2차원 평면에 표현할 때, 멀리 있는 것을 더 작게 나타내어 원근감을 갖게 하기 위함이다. 이렇게 나누는 것을 원근 나눗셈이라고 한다.

뷰포트 변환 - 3D공간에 있는 삼각형(Polygon)을 투영변환 결과를 이용하여 장치 좌표계로 매핑해 2D모니터에 출력할 2D영상을 만들어내는 단계이다.

스캔 변환 - 개별 삼각형이 차지하는 스크린공간의 픽셀 위치를 결정하고, 삼각형의 정점별 속성을 보간(선형 보간 Linear Interpolation)한다.

 

PixelShader(픽셀 쉐이더)

- 넘어온 정점 데이터에 대하여 색상연산을 진행해준다.

 

Pixel Shader 코드

다음 쉐이더 코드는 그냥 Vertex Shader에서 넘어온 데이터를 아무 계산 없이 그대로 return한다. 원래는 이 단계에서 광원, 텍스처와 같은 색상에 대한 연산을 처리해주는 경우가 많다.

 

여기까지가 가장 기초적인 쉐이더라고 할 수 있을 것 같다.

 

OutputMerger(출력병합기)

- 최종적으로 픽셀의 색상을 혼합해주는 단계이다.

https://docs.microsoft.com/ko-kr/windows/uwp/graphics-concepts/output-merger-stage--om-

 

OM(출력 병합기) 단계 - UWP applications

OM (출력 병합기) 단계에서는 다양 한 유형의 출력 데이터 (픽셀 셰이더 값, 깊이 및 스텐실 정보)를 렌더링 대상의 내용과 깊이/스텐실 버퍼의 내용과 결합 하 여 최종 파이프라인 결과를 생성 합

docs.microsoft.com

여길 보면 자세하게 나와있다.

 

여기까지하면 사실 상 물체를 화면 상에 띄울 수 있다.

 

하지만, 좀 더 기능을 추가하기 위해서 DX12에서는 몇가지 쉐이더가 더 존재한다.

 

GeometricShader(기하 쉐이더)

- 정점 정보를 추가한다. 이 쉐이더의 경우, 작은 단위(미시적)의 정점에 대해 정점정보를 추가/제거할 수 있다.

>> 삼각형(Triangle)

 

HullShader, Tessellator, DomainShader(헐 쉐이더, 테쎌레이터, 도메인 쉐이더)

- 기하 쉐이더와 달리 거시적인 관점에서의 정점정보를 추가/제거할 수 있다.

- 이 과정을 Tessellation Stage라고도 부른다.

>> 지형(Terrain)

Tessellation은 물체와 가까이 갔을 때 좀 더 세밀하게 볼 수 있도록 정점을 추가하거나, 멀어졌을 때 대충 보이도록 정점을 제거하는 연산을 한다. 이렇게 하면 좀 더 자원을 아끼면서 뛰어난 그래픽스를 구현할 수 있다.

 

ComputeShader(계산 쉐이더)

- 렌더링 파이프라인과 독립적으로 연산 1개만 해서 결과를 주고 받을 수 있다. 

 

-- 공부하는 사람입니다. 부족한 부분이 있으면 댓글로 말씀해주시면 감사하겠습니다.

반응형
LIST

'Direct3D12' 카테고리의 다른 글

[Direct3D12] 과제2  (1) 2019.11.01
[Direct3D12] 과제1  (0) 2019.11.01