[CG] Vertex-Processing(1)
한 출력이 다음단계의 입력으로 사용되는 일련의 데이터 처리 구조를 pipline이라 부르고, GPU의 렌더링 파이프라인은 주로 폴리곤으로 된 3차원 장면을 받아 2차원 이미지로 뽑아내는 것을 목표로 하게 된다.

Render Pipeline은 보다시피 Vertex Processing -> Rasterization -> Fragment Processing, Output Merging으로 이루어진다. Vertex Processing은 대게 Transform을, Rasterization에서는 폴리곤의 내부를 차지하는 fragment(컬러 버퍼에 저장된, 픽셀을 수정하는데 필요한 데이터 모음)을 생성하게 된다.
물론 위의 구조가 강요되는 것은 아니고, 시대에 맞게 변화해 왔다. 쨋든 이러한 Pipeline 과정 속에서도 Transform을 적용하는 Vertex Progrmam과 프래그먼트 색깔을 정하는 fragment Program은 사용자가 프로그래밍 가능하다. 그러니까 대충 Vertex 상의 좌표를 회전하고 늘리고 지지고 볶고 옮기고(Scale, Rotate, Translate)하는건 가능하단 소리.
그리고 그중에서도 Vertex Processing 과정중 World Transform에 대해서 먼저 알아보자...
Wolrd Transform
Object Space에서 World Space(ex. 마크 좌표)로 가는걸 World Transform이라고 하게 된다. 쉽게 말해서 오브젝트를 월드상의 좌표계에 맞춰서 띄우겠다는 소리. 그리고 이러한 과정에서는 Scaling, Rotation, Translation이 들어가게 된다. 근데 문제는 S/R은 Linear Transform이지만 Translation은 Linear하다고 하기에는 거시기 하다.(아핀 변환으로 치면 맞긴 하다.) 그러므로 이건 나중에 얘기하고 일단 Scaling부터 생각해보자.

위와 같이 행렬 곱셈을 통해 축소/확대 되는걸 알 수 있다. 참 쉽죠?
다음으로 벡터의 회전에 대해서 생각해보자. 일단 Z축을 기준으로 얘기를 하자면... 대충 r만큼 길이를 가지고 phi만큼 각을 가진 벡터가 있다 치면.. 좌표는 다음과 같이 계산할 수 있다.

마찬가지로 y로 계산해주고, 행렬 곱셈 형태로 만들어주면 아래와 같다.

여기서 x,y,z를 y,z,x로 대체하면 x축 기준 회전이다. 또 y,z,x 를 z, x, y로 대체하면 y축 기준 회전이 된다.
다만 벡터 덧셈은 어떻게 표현해야 할까? 뭐 단순하게 x, y, z에 이동값 만큼 더하면 되겠으나... GPU는 행렬 곱셈에 최적화 되어 있다. 따라서 동차좌표를 사용해 행렬 곱셈 형태로 표현해 준다면 참 좋을것이다. 이를 표현하면 아래와 같이 할 수 있을 것이다.

다만 여기서 동차좌표의 4번째 원소가 항상 1은 아니다. 예를 들어서 (1, 2, 3, 5) (2, 4, 6, 10)은 모두 카타시안 좌표 (1, 2, 3)의 동차좌표다. (1, 2, 3, 1)은 수 많은 동차좌표중 하나인 셈. 한편 저 여분 원소에는 벡터/점 구분용으로 0/1을 넣기도 한다. 그리고 여기서 세 축의 중심각에 대한 회전들이 결합된 것을 Euler Transform이라고 부른다.

참고로 균등한 축소확대를 포함한다면, 노멀변환이 그냥 냅다 된다. 다만 대부분의 경우 아니므로 (m^(-1))^T를 적용해야 할 것이다. 증명 과정은 대충 생략한다. ( 대걍 dot product가 들어간다.)
View Transform
World Spcae의 모든 물체를 Camera Spcae로 변환하는 것을 의미한다. 참고로 이는 효율적인 렌더링 알고리즘을 위해서이다. 일단 Camera Space에 대해 이야기 해야 하는데, 얘네는 세가지 파라미터를 가지게 된다.
- EYE : 월드 공간에서의 카메라위치
- AT : 월드 공간에서 카메라가 바라보는 기준점. 쉽게 말해서 Focusing할 어떤 점이다.
- UP : 카메라의 상단을 대략적으로 묘사하는 벡터이다. 대게 월드 공간의 y축이나 카메라가 "기울어져"있다면 얘기가 달라지게 되며 이를 유의하여야 한다.

그리고 해당 공간은 {EYE, u, v, n}으로 표기된다. (공간에 대한 표기임에 유념하자. 예로 월드 공간은 {O(원점), e_1, e_2, e_3} ) 참고로 카메라 공간의 기저 u/v/n은 아래와 같이 구성된다.

근데 쨋든 월드 공간을 카메라 공간으로 변환해야 할 것 아닌가? 대충 Transform을 위해서 행렬을 곱해 주면 될거라는 생각이 들 것이고, 그것은 정답이며, 원점을 일치시키고 회전(기저 이전)하기 위해 대충 이동하고 곱하고 지지고 볶고 난리를 치면 되게 된다.
