Daily Life of BlueRose

컴퓨터 & 코딩 공부/컴퓨터 그래픽스 & 언리얼 엔진

컴퓨터 그래픽스 - 그래픽 파이프라인(렌더링 파이프라인) 단계 정리

푸른로즈 2024. 8. 26. 17:48
728x90

여는 글 

언리얼 엔진에서도 여러번 보았던 버텍스 셰이더, 픽셀 셰이더 등의 용어가 렌더링 파이프라인에 속한다는 것을 최근에서야 알게되었습니다. 기존에 얼마나 무지한 상태에서 엔진을 배우려했는지 새삼 느껴지네요.

 

컴퓨터 그래픽스에 대한 공부를 본격적으로 들어가기에 앞서, 렌더링 파이프라인별 특성을 알고 있어야 이후에 어떤 단계에서 진행되는 공정인지를 알 수 있을 것 같아서 한 차례 정리해보고 가려합니다.

 

정의

그래픽 파이프라인은 3D 개체가 우리의 2D 모니터 화면에 출력되기 까지 거치는 일련의 과정입니다. 3D3D로 표현하면 되는것 아닌가? 생각할 수 있겠지만, 컴퓨터의 처리결과를 통해 우리가 보게 되는 것은 모니터의 2D 화면이지, 디지몬 어드벤처의 가상 환경 세상이 아니라는 점을 기억해야 합니다.

 

단계 요약

OpenGL과 Direct3D의 그래픽 파이프라인은 아래 그림과 같습니다. 대체로 공통적인 과정을 갖고 있으며, 추가적으로 몇몇 특별 기능이 포함되어 있는 듯 하네요. 

 

OpenGL과 Direct3D 의 그래픽 파이프라인

 

 

개별 과정별 세부사항

Input Assmbler(Vertex Specification)

정점에 대한 정보들을 수집하는 단계입니다. 정점에는 정점의 좌표, 법선 정보 등 다양한 정보가 포함되어 있습니다. 이러한 정보를 컴퓨터가 그래픽카드로 전달해주는 단계라고 볼 수 있겠네요.

 

Vertex Shader(버텍스셰이더)

정점(=꼭지점/버텍스)의 정보를 토대로 공간에 배치하는 단계입니다. 정확히는 각 정점별로 세팅된 로컬좌표계를 월드좌표계로 옮겨주고, 최종적으로는 화면에 표시되는 모습으로 변환시켜주기 위한 단계입니다.

 

Tessellation

단어 Tessellation은 타일화라고 해석할 수 있는데 그래픽 파이프라인에서의 Tessellation은 기존 삼각형을 쪼개어 새로운 여러개의 삼각형을 만드는 단계입니다.

 

게임을 하다보면 가까이 있는 나무/풀과 멀리있는 나무/풀의 모습이 굉장히 차이나는 경우가 있습니다. 혹은 저격플레이를 하다보면, 멀리있는 몬스터는 찰흙덩어리마냥 엉성하고 가까이 있는 몬스터는 제대로 보이는 경우도 볼 수 있는데요. 이러한 차이를 Level of Detail(= LOD, 세부묘사수준)이라고 부르는데, Tessellation은 이러한 LOD 단계가 보다 매끄럽게 이행될 수 있도록 도울 수 있습니다.

 

다만 LOD와 Tessellation은 상호 의존적인 관계는 아닙니다. LOD는 기본적으로 카메라로부터의 거리에 따라 텍스처의 크기를 달리하여 보여주는 것이므로 Tessellation 없이도 구현이 가능하고, 이러한 LOD 단계간 간극을 보다 세부적으로 조절하기 위해서 Tessellation이 사용되는 것이지, LOD기능을 구현하는데 필수적인 것은 아닙니다.

 

참고로 언리얼엔진에서는 Tessellation을 별도의 기능으로 사용할 수 있는데요. 보통 Displacement map 기능과 함께 사용되어, 머티리얼(언리얼엔진에서 텍스처 및 각종 기능을 합산한 클래스)에 입체감을 부여하는데 사용됩니다. 밋밋한 바닥을 보강할 때, Tessellation 기능을 통해 삼각형을 보다 잘게 쪼개주고, 여기에 Displacement map을 적용하여 전에 없던 윤곽을 부여하는 식으로 사용할 수 있습니다. 다만 연산량이 많아서 특정 부분에서만 제한적으로 사용하는 편이라고 합니다.

 

Geometry Shader(기하셰이더)

기하셰이더는 기본 도형에서 정점을 추가하거나 삭제하는 기능으로 사용됩니다. 이미 모델링에서 생성되어 있는걸 굳이 추가할 필요가 있나 싶겠지만, (머리털 등)이나 지느러미와 같이 특정 일렬의 지점에서 늘어져나온 선을 생성한다던가, Tessellation과 유사하게 가까이에서만 볼 수 있는 세부요소를 추가하는 등 목적으로 사용가능합니다.

 

참고로 기하셰이더는 필수는 아니지만, 아래와 같은 목적으로 사용될 수 있습니다.

  • 동적 입자 시스템 : 파티클 시스템 특성상 입자가 생성되고 사라지는 일을 반복하게 되는 데 이때 기하셰이더가 사용될 수 있습니다.
  • 점 스프라이트 확장 및 털/지느러미 생성 : 특정 지점으로부터 버텍스를 한쪽 방향으로 길게 연장하여 털이나 지느러미를 연출할 수 있습니다. 털을 일일이 모델링 하는 것보다 차라리 셰이더를 이용하여 표면의 특정 지점으로부터 털이 자라나는 것처럼 연출하는 것이 반복작업에 용이할 수 있겠죠?
  • 섀도 볼륨 생성 : 광원-버텍스 연장선이 바닥과 닿는 지점을 확인하여 그림자로 처리하는데 사용됩니다.
  • 단일 패스 큐브 맵으로 렌더링 : 큐브맵은 주변 환경을 캡처하여 반사효과를 부여하는 데 쓰이는 개체인데요. 이때, 캡처를 위해서는 본래 좌/우/상/하/앞/뒤의 6개면을 렌더링 해야 하는데 기하셰이더를 이용하면 이를 한 번(단일패스)에 처리(렌더링)할 수 있다고 합니다.
  • 기본 요소별 재질 바꾸기(Material Switching per Primitive) : 특정 요소(점, 선, 삼각, 사각)별로 조건에 따라 다른 재질이 적용되도록 처리할 수 있습니다. 그러나 일반적으로 재질 변경은 버텍스 셰이더(좌표값에 따른 재질 지정) 혹은 픽셀 셰이더(화면에 비치는 물체의 재질 변경)에서 주로 처리합니다.
    언뜻 보았을때는 언리얼엔진에서의 지형 레이어가 이 기능을 사용할 것 같지만 그렇지는 않다고 하네요. 지형 레이어에서 고저차에 따라 눈이 덮힌 지형 표현 등은 버텍스 셰이더 단계에서 월드 좌표를 통해 구현되며, 레이어간 블렌딩(브러쉬가 칠해진 부분에 낙엽, 풀 등 표시)은 픽셀 셰이더 단계에서 이뤄진다고 합니다.

 

Rasterization(래스터화)

일반적으로 벡터 그래픽을 2D 픽셀(Pixel / Fragment) 이미지 형태로 변경하는 과정을 래스터화라고 부릅니다. 그래픽 파이프라인에서도 거의 같은 의미로 사용되며, 모든 정보가 확정된 3D 그래픽을 2D 화면의 픽셀로 옮기는 작업입니다.

 

Pixel Shader(Fragment Shader/픽셀셰이더)

래스터화가 완료된 2D 픽셀 이미지에 마무리 작업을 시행하는 단계입니다. 텍스처를 입히고 색상화하는 작업이 주로 이 단계에서 이뤄집니다. 라이팅 작업 또한 이 단계에서 이뤄지며, 이와 관련된 범프맵, 노멀맵 또한 이 단계에서 처리됩니다.

반응형