선행지식 : 행렬 / 선형 대수 기저(basis) / Affine Matrix(아핀 공간) / 외적 등
그래픽 파이프라인
3차원 이미지를 2차원 래스터 이미지로 표현하기 위한 단계적인 방법
래스터(raster)란 이미지를 2차원 배열 형태의 픽셀로 구성하는 것을 의미
(출처) 위키백과
이번 글에서는 그래픽 파이프라인 중 Vertex Processing에 대해 알아보고자 한다.
Vertex Processing
우리는 연필을 화면에 출력하고자 한다.
연필을 출력하기 위해서는 연필을 구성하는 정보가 필요하다. 연필은 점들로 구성되어 있고 이를 정점(Vertex)라고 한다.
이 점 좌표를 그대로 화면에 찍으면 될까?
이는 연필 기준(Object)으로 표시한 것이기 때문에 여러 변환 과정이 필요하다. 이 과정을 Vertex Processing이라고 한다.
Vertex Processing이란?
물체의 정점(Vertex)을 화면에 출력하기 위해 변환하는 과정
좌표계 변환
위에서 연필의 정점은 연필 기준으로 나타낸다고 했다. '연필 기준'인 공간을 Object Space이라고 하며 연필을 화면에 출력하기 위해서는 이 공간을 바꿀 필요가 있다. 우리는 이를 좌표계 변환이라고 한다. 연필만의 공간(Objet Space)에서 화면에 출력하기 위해서는 여러 번의 변환(Transform)이 필요하다. 그리고 각 변환은 행렬로 나타낼 수 있다.
Vertex Processing 단계
World Transform
Object Space에서 World Space로 변환하는 과정
Object Space란 각 물체마다 가지고 있는 좌표계이다. 위의 연필도 자신만의 좌표계를 가지고 있다. 즉, 물체는 자신만의 좌표계를 가지고 있으며 정점(Vertex)은 Object Space를 기준으로 한 좌표들을 가지고 있다.
Object Space를 기준으로 출력하기에는 해당 좌표계는 연필만의 공간이다. 연필만의 공간을 화면에 나타낼 수는 없다. 또한, 연필과 함께할 지우개 등 여러 물체들을 함께 표시해야 한다. 이를 위해서는 모든 물체를 합쳐서 나타낼 공간이 필요하며 이 공간을 World Space라고 한다.
World Transform 행렬
Object Space에서 World Space로 바꿀 때 순서는 TRS 순으로 진행한다.
(선형 변환, 즉 물체의 모습을 바꾸지 않고 바꾸기 위한 순서이다)
T : 이동 (Translation) / R : 회전(Rotation) / S : 크기 (Scale)
View Transform
World Space에서 Camera Space로 변환하는 과정
3D 세계를 화면에 옮기기 위해서는 3D 세계에서 우리의 눈을 대신할 대리자가 필요하다. 이때 대리자로 카메라를 사용하고 카메라를 기준으로 한 좌표계를 Camera Space라고 한다.
화면에 출력할 때는 카메라의 범위에 보이는 것들을 출력하기 때문에 카메라 기준으로 좌표를 나타낼 필요가 있다.
<1-3>의 파란 점의 World Space 좌표 (x, y, z)를 Camera Space 기준으로 표현해보자.
이때 World Space 기준으로 표현하는 것이 쉽기 때문에 Camera Space의 좌표축을 World Space로 옮기는 방식으로 좌표계 변환을 할 수 있다.
- Camera의 원점을 world space의 원점O (0, 0, 0)으로 옮긴다.
- Camera의 축을 world space의 축으로 rotate한다. => Camera rotation의 transpose
바라보고자 하는 대상이 정해졌을 때 카메라 좌표축을 유도하는 과정을 아래 첨부했다. 관심있는 독자는 참고하길 바란다.
Projection Transform
Camera Space에서 Clip Space로 변환하는 과정
정점을 카메라까지 옮겼으니 슬슬 화면에 나타내고 싶다. 하지만 아직 카메라에 대해 고려하지 않은 요소들이 있다. 카메라 자체 요소인 시야(field of view), 종횡비(aspect) , 깊이(depth)에 대해 생각해볼 필요가 있다.
Field Of View (FOV, 시야)
FOV란 카메라 렌즈를 통해 카메라가 이미지를 담을 수 있는 각을 의미한다.
FOV가 크면 각이 넓기 때문에 화면에 보이는 부분이 많을 것이고
FOV가 작으면 각이 작기 때문에 화면에 좁은 부분이 보일 것이다.
(배틀그라운드를 해본 사람이라면 조준경(scope)를 꼈을 때 상황을 생각하면 된다)
Aspect (종횡비)
말 그대로 가로와 세로 비율을 의미한다.
Depth (깊이)
카메라에 보이는 모든 대상을 하면 좋으나 화면에 출력했을 때 점 같이 보인다면 굳이 출력할 필요가 없을 것이다. 이를 고려하여 카메라에 출력할 범위를 지정하려고 한다. 위 좌표계를 카메라 좌표계라고 했을 때 Z축의 범위가 깊이가 된다.
Z축의 가장 가까운 화면과 먼 범위를 Near-Far Plane 이라고 한다.
깊이를 고려하여 카메라가 출력하는 범위를 잘라보면 위 사진과 같은 절두체(View Frustum)가 나오게 된다.
실제 카메라가 출력하는 범위를 앞에서 알아본 절두체(View Frustum)로 나타낼 수 있다. 이 공간에서 좌표를 표현하려면 계산하기 매우 복잡할 것이다. 이 공간을 우리에게 익숙한 정사각형 공간으로 바꾸고자 한다. 이 때 이 공간을 Clip Space라고 한다.
절두체(View Frustrum)을 Clip Space로 변환하기 위해서는 aspect를 이용하여 식을 구할 수 있다.
식 유도
위 과정을 진행하면 Object Space에서 Clip Space으로 변환할 수 있다. 아직 정점은 3D 공간에 있다.
다음 글에서는 Resterization과 함께 Screen Space로 변환하는 방법에 대해 알아보고자 한다.
출처
연필 <a href="https://www.flaticon.com/kr/free-icons/" title="연필 아이콘">연필 아이콘 제작자: Freepik - Flaticon</a>
지우개 <a href="https://www.flaticon.com/kr/free-icons/" title="지우개 아이콘">지우개 아이콘 제작자: Those Icons - Flaticon</a>
카메라 <a href="https://www.flaticon.com/kr/free-icons/" title="카메라 아이콘">카메라 아이콘 제작자: Freepik - Flaticon
<0> MS Learn https://learn.microsoft.com/en-us/windows/win32/direct3d9/rendering-from-vertex-and-index-buffers
<2-3, 3-3> 강의 자료
<3-1> 유니티 Documentation 뷰 절두체 이해 https://docs.unity3d.com/kr/530/Manual/UnderstandingFrustum.html
<3-2> A semi-physical simulation system for binocular vision guided rendezvous - Scientific Figure on ResearchGate. Available from: https://www.researchgate.net/figure/A-viewing-frustum-defined-in-OpenGL-to-emulate-the-real-camera_fig1_261264621 [accessed 31 Mar, 2024]
<3-3> https://carmencincotti.com/2022-05-02/homogeneous-coordinates-clip-space-ndc/