들어가며


안녕하세요 이번 글은 그래픽스와 관련하여 서술하게 되었습니다.

제가 어제 기업 직무 테스트를 치르고 왔는데 그래픽스와 관련하여 모르는 내용이 많은 것을 확인하였습니다.

그래서 고려대 그래픽스 강의를 참고하여 관련 내용을 정리해보려고 합니다.


GPU Rendering Pipeline


컴퓨터 그래픽스의 목표는 컴퓨터 안에 있는 3차원 공간을 우리가 보는 화면인 2차원 디스플레이에 표현하는 것입니다. 영화를 만들고 그림을 그리는 것처럼 말입니다.

우리는 여러가지 과정을 거쳐서 이를 실현 가능한데 이 과정을 렌더링 파이프라인(Rendering Pipeline)이라고 합니다.

렌더링 파이프라인은 총 네가지의 과정으로 구성됩니다.

  1. Vertex Shader
  2. Rasterizer
  3. Fragment Shader
  4. Output merger

위 네 가지 과정은 이름부터 생소하신 분들도 많으실텐데요, 알아보면 전혀 어렵지않은 내용입니다.


1. Vertex Shader

Vertex Shader란 것은 3d 공간을 구성하고 그 3d 공간에서 컴퓨터 화면에 표시될 정보만을 가져오는 프로그램입니다. 이 때 정보란 vertex의 좌표와 normal 벡터입니다.

예시로 다음은 언리얼 엔진을 실행하고 있는 모습인데요, 게임을 만들 때 다음과 같은 3d 공간이 있을 것입니다.



그리고 이 공간 안에서 실제로 게임을 하게되면 다음과 같은 시야로 공간을 보게될 것입니다.



위와 같은 시야를 화면에 보여주기 위해서는 여러 오브젝트들을 공간 상에 배치한 후 특정 위치에서 카메라로 보았을 때의 모습을 전달해주어야할 것입니다.

Vertex Shader는 아래의 과정을 통해 위의 목적을 달성합니다.



위 그림에서 두번째에 있는 world space가 유니티, 언리얼 엔진을 사용할 때 보이는 공간입니다. 그래서 world transform이란 오브젝트를 3d 공간 상으로 가져오는 것을 의미하며 모든 오브젝트들에 대해 수행되게 됩니다.

오브젝트들은 파일로 저장되어 각자의 object space에 있으며 아래와 같이 scaling과 rotation을 통해 공간 상으로 이동하게 됩니다.



이렇게 공간이 구성되고나면 우리는 카메라로 특정 부분만을 찍게됩니다. 보여주고싶은 화면 부분이죠. 그래서 카메라로 보았을 때의 좌표로 물체의 좌표들을 바꿔주게되는데, 이렇게되면 물체들이 camera space에 속하게 된다고 하며, 이러한 변환을 view transform이라고 합니다.

이 과정은 아래 그림과 같은 과정을 통해 이루어집니다. eye가 카메라라고 생각하면, 기존 world space에서 (10, 2, 0)의 좌표를 카메라를 기준으로 바꾸어 (0, 0, -10)으로 바꿔주게됩니다. 이렇게 바꿔주게되면 후에 진행할 연산들을 처리하기 쉬워집니다.



한편 카메라가 보여줄 영역은 정해져있는데 이를 view frustrum이라고 합니다. 아래의 그림에 보이는 사각뿔대의 영역만 화면에 보일 것이기때문에 그밖의 영역은 렌더링할 영역에서 제외해줍니다.



여기까지 했으면 이제 3d 공간에서 카메라로 보고싶은 영역의 정보만 잘 처리한 것 같습니다. 그러나 아직 끝은 아닙니다.

camera space에 있는 좌표값들을 그대로 사용하게되면 원근법이 적용되지않기에, 이를 적용하기 위해 projection transform이라는 변환을 적용해서 원근법이 적용된 좌표값으로 바꿔줍니다. 그러면 이제 clip space라고 하는 공간으로 이동한 것입니다.



이렇게까지 정점의 좌표들을 처리해주면 이제 vertex shader의 역할은 끝입니다.

이제 이 좌표들의 정보를 가지고 나머지 처리들이 이뤄지게되는데 그 부분은 다음 글에서 다루겠습니다.