렌더링 파이프라인은 대표적으로 Raytracing Pipeline, Rasteriztion Pipeline 등이 있다.
Raytracing은 연산량이 많아 실시간으로 표현해야하는 게임에서는 잘 사용되지 않았으나, 컴퓨터 하드웨어가 올라가면서 점차 게임쪽에서도 사용되고 있는 추세이다.
Rasteriztion은 우리가 계산해야 될 픽셀만 추출해서 그리는 방식으로 Raytracing에 비해 연산량이 적어 주로 사용되는 방식이다.
최근에는 Mesh Shader Pipeline도 나왔다.
* Vertex Buffer & Index Buffer
HDD에 있는 정점 데이터들을 CPU에 로딩 후 GPU로 넘겨서 작업을 하는데 이때 이 정점 데이터들을 운반하는 자료구조를 Vertex Buffer라고 한다.
Index Buffer는 사각형 하나를 그리기 위해 총 6개(2 * 3, 삼각형 2개)의 Vertex가 필요하지만 Index Buffer를 이용하면 6개가 아닌 4개로 사각형 하나를 표현할 수 있다. Index Buffer는 각 Vertex의 Index를 저장하고 있는 Buffer이기 때문에 중복되는 값을 찾아서 그리지 않도록 할 수 있는 것이다.(Index Buffer가 없어도 상관은 없다.)
Vertex는 위지 데이터 말고도 색, 법선, UV(텍스쳐 좌표) 등등 다양한 정보를 개발자가 원하는 만큼 저장하여 사용되기 때문에 정수값만 저장하고 있는 Index Buffer가 훨씬 효율적이다.
1. Input Assembler 단계
각 정점 데이터를 GPU에서 전달 받고 나면 이 정보를 어떻게 할 것인가를 필요로 하는데(선으로 연결, 점으로 냅둠, 삼각형 하나로 연결)이 정보를 Primtive Topology라고 한다.
이러한 정점의 데이터를 읽고 삼각형과 같은 도형으로 조립하는 일을 수행한다.
2. Vertex Shader 단계
Input Assembler를 통해 조립된 도형들을 로컬 좌표에서 월드 좌표로 변환하여 각 필요한 위치에 존재하도록 옮기거나, 카메라가 있는 경우 카메라가 중심이 되는 View Space변환 후 Projection 변환(투영변환)을 거쳐 최종적으로 Clip Space 공간으로 변환하는 단계
* 월드 공간 변환
각 도형이 가지고 있는 Local Space(자기 자신이 중심이 되는 공간)를 World Space(게임 공간)로 바꾸는 과정
* 카메라 공간 변환
실제로 화면에 나오는 카메라의 공간(가시영역, 절두체)에 위치한 도형과 그렇지 아니한 도형을 다르게 표현하여 성능을 높일 수 있다.(카메라에 보이지 않는 부분은 표시하지 않거나 등등) 절두체 공간에 경계를 걸치는 도형의 경우 바깥쪽 부분을 잘라 버리는데 이를 클리핑(Clipping)이라고 한다. 이 클리핑은 Clip Space에서 Rasterization으로 넘겨질때 수행된다.
* Projection 변환(투영 변환)
월드 공간 변환을 통해 각 도형을 위치 시키고 나서 3차원으로 위치한 정점을 2차원으로 변환하는 과정.
원근법을 사용한다. 단 최종적으로 2차원이 된 것이 아니라 3차원을 2차원으로 가공하기 위한 준비과정이 끝난정도이다.
3. Tesselator 단계(필수 단계는 아님)
1) HullShader
Vertex Shader에서 진행하는 공간 변환을 진행하지 않고 정점 데이터를 전달한다.
이 전달 받은 데이터를 가지고 폴리곤의 분할 수, 분할 방식 등을 결정한다.
2) Tesselation
다각형을 겹치지 않게 작고 조밀하게 배치하여 실제에 보다 가깝게 표현하는 기술
3) DomainShader
Tesselation 단계에서 출력한 정점마다 한번씩 호출되며, Tesselation이 활성화 되면 Vertex Shader의 역할을 대신 수행한다.
* Tesselator 단계는 꼭 필요한 단계가 아니다.
애초에 게임 제작시 하이 폴리곤(정점이 많음), 로우 폴리곤(정점이 적음) 두 개의 Mesh를 제작하여 사용하는 방식을 주로 사용한다.
4. Geometry Shader 단계(필수 단계 아님)
기존 폴리곤에서 정점 추가, 삭제 등의 연산을 수행하는 단계
Perticle과 같이 동일하지만 크기, 위치, 회전 등이 다른 Mesh의 경우 모두 메모리에 올려 사용하는 게 아니라 지오메트리 셰이더를 이용하여 동일한 Mesh의 정점 정보들만 조금씩 수정해서 사용하는 것이다.
GPU의 도움을 받아 정점을 추가하기 때문에 연산속도가 빨라지고 메모리적으로 효율적이다.
5. Rasterization 단계
이제부터는 정점으로 이루어진 삼각형이 아닌 하나의 도형으로 처리가 된다.
1) 이 도형을 2차원 평면에 투영시켜 모니터의 픽셀에 표현한다.
2) 도형에 포함된 픽셀마다 Pixel Shader(Fragment Shader)가 실행된다.
3) 이 도형의 각 정점에 할당된 데이터들(UV, Nomal, Color)은 보간되어 도형 내부의 Pixel Shader로 넘어온다.
Rasterization 단계는 고정 파이프라인 단계로 프로그래머는 이 로직을 바꿀 수 없다. 자체 알고리즘으로 알아서 동작을 하기 때문입니다. 클리핑, 원근 나눗셈(Perpective division), 뒷면 제거(backface culling), 스캔 변환(ndc scan transform), 뷰포트 변환 등을 수행한다.
* 클리핑
투영 변환 이후 클립 공간 볼륨 바깥에 위치한 폴리곤을 잘라내는 작업.
중요한 건 클립 공간은 절두체와 달리 정육면체이기에 연산이 더욱 단순하게 진행 할 수 있다.
절두체는 사다리꼴 모양의 도형이라 연산이 까다롭기 때문에 클립 공간으로 변형하는 것이다.
* 원근 나눗셈
Z좌표로 모든 성분을 나누어 가까운 물체는 크게, 먼 물체는 작게 그려지도록 계산되며 투영 변환 이후 정점 데이터는 x,y,z,w 값을 갖는데 여기서 w 성분에 z값이 저장된다. 원근 나눗셈 이후에 w는 1이 되므로 x,y,z 좌표계로 변환되는데 이를 NDC(Nomailize Device Coordinate) 공간이라고 한다.
* 뒷면 제거
가려진 면적은 굳이 연산할 필요가 없으므로 외적 삼각형의 바라보고 있는 면의 방향을 구하여 뒷면일 경우 연산에서 제외시킨다.
* 뷰포트 변환
NDC 공간의 물체들을 Screen 공간으로 이전 시키는 변환
* 스캔 변환
정점 데이터에 들어온 데이터들을 보간하여 하나의 도형을 생성하는 과정(도형 하나가 내부에 차지하는 모든 픽셀을 생성하는 과정)
* Pixel Shader
Rasterization 된 도형에 색, Nomal 값 등을 맵핑하여 출력해주는 셰이더
6. Output Merger 단계
물체를 최종적으로 화면에 그려주는 단계
* Computer Shader
일반 렌더링 파이프라인과 별도로 그래픽 카드를 사용할 때 실행할 수 있도록 도와주는 셰이더.
게임 렌더링의 일부를 가속시키거나, 대량 병렬 알고리즘용으로 사용된다.
효율적으로 사용하기 위해선 GPU 아키텍쳐와 병렬 알고리즘에 대한 지식, DirectXComput, OpenGL Compute, CUDA, Open CL 등의 지식이 필요하다.
'Engine' 카테고리의 다른 글
SDL을 이용한 게임 구현(Cross-platform Development Library designed) (1) | 2024.11.26 |
---|---|
DirectX 11 Graphic (2) | 2024.11.24 |
Life Cycle (1) | 2024.11.23 |