비타Cpp

렌더링 파이프 라인 - VS(Vertex Shader) Stage - View Space 본문

DirectX12/메모

렌더링 파이프 라인 - VS(Vertex Shader) Stage - View Space

멍C 2021. 8. 5. 17:58

3차원 장면의 2차원 이미지를 만들어 내려면 장면에 가상의 카메라를 배치해야 한다. 그 카메라는 World에서 관찰자에게 보이는 영역을 결정한다. 그 영역이 바로 응용 프로그램이 2차원 이미지로 만들어서 화면에 표시할 영역이다.

아래 그림에서 나온 것처럼 이런 가상 카메라에 local좌표계를 부여한다고 치자. 이 좌표계는 시점 공간(Eye Space)이나 카메라 공간(Camera Space)라고 부르는 시야 공간(View Space)을 정의한다. 카메라는 이 시야 공간의 Local 좌표의 원점에 놓여서 양의 z 축을 바라본다. x축은 카메라의 오른쪽, y는 카메라의 위쪽 방향이다. 렌더링 파이프라인 후반부 단계들에서는 장면의 정점들을 World 공간이 아니라 이 시야 공간을 기준으로 서술하는 것이 편한 경우가 있다. World 공간에서 View공간으로의 좌표 변경 변환을 시야 변환 (View Transform)이라고 하고, 해당 변환 행렬을 시야 행렬(View Matrix)라고 부른다.

 

정점의 세계 공간 기준 좌표를 카메라 공간 기준 좌표로 변환한다.

 

Local 공간 원점 및 x, y, z축의 World 공간에 상대적인 동차좌표들이 Qw = (Qx, Qy, Qz, 1), uw= (ux, uy, uz, 0), vw= (vx, vy, vz, 0), ww= (wx, wy, wz, 0) 이라고 할 때, View 공간에서 World 공간으로의 좌표 변경 행렬은 다음과 같다.

 

$$W=\begin{bmatrix}u_x & u_y & u_z & 0 \\ v_x & v_y & v_z & 0 \\ w_x & w_y & w_z & 0 \\ Q_x & Q_y & Q_z & 1 \end{bmatrix}$$

 

하지만, 우리가 원하는 변환 행렬은 그 반대 방향의 변환, 즉 World 공간에서의 View 공간으로의 변환이다. 그렇다면 우리에게 필요한 행렬은 W의 역행렬 W-1이다.

일반적으로 해당 좌표변환에는 비례 변환(S)은 쓰지 않는다. 그래서 W = RT라고 볼 수 있다. 이렇게 회전과 이동 행렬로 나눠 놓으면 좀 더 역행렬을 구하기 쉬워진다.

 

$$V=W^{-1}=(RT)^{-1}=T^{-1}R^{-1}=T^{-1}R^T \\ =\begin{bmatrix}1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ -Q_x & -Q_y & -Q_z & 1 \end{bmatrix}\begin{bmatrix}u_x & v_x & w_x & 0 \\ u_y & v_y & w_y & 0 \\ u_z & v_z & w_z & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} = \begin{bmatrix}u_x & v_x & w_x & 0 \\ u_y & v_y & w_y & 0 \\ u_z & v_z & w_z & 0 \\ -Q \cdot u & -Q \cdot v & -Q \cdot w & 1 \end{bmatrix}$$

 

결론적으로, 시야 행렬은 다음과 같이 정리된다.

 

$$V=\begin{bmatrix}u_x & v_x & w_x & 0 \\ u_y & v_y & w_y & 0 \\ u_z & v_z & w_z & 0 \\ -Q \cdot u & -Q \cdot v & -Q \cdot w & 1 \end{bmatrix}$$

 

카메라의 위치(Q)와 타겟점(T), 그리고 World공간의 상향 벡터(j)를 이용한 카메라 좌표계 구축.

이제 시야 행렬을 구축하는 데 필요한 벡터들을 직관적으로 구하는 방법을 알아보자. 위 그림에서 Q가 카메라의 위치이고 T가 카메라가 바라보는 지점, 즉 대상점(Target Point)라고 하고, j가 world공간의 '위쪽'을 가리키는 단위 벡터, 즉 상향 벡터(Up Vector)라고 가정하자. 그러면 위 그림의 카메라가 바라보는 방향 (전방 벡터; Front Vector)인 w는 다음과 같다.

 

$$w=\frac{T-Q}{\parallel T-Q \parallel}$$

 

이 벡터는 카메라의 Local 좌표의 z 축에 해당한다. w의 '오른쪽'을 가리키는 단위 벡터(Right Vector)인 u는 다음과 같다.

 

$$u=\frac{j \times w}{\parallel j \times w \parallel}$$

 

이 벡터는 카메라의 Local 좌표의 x축에 해당한다. 마지막으로, 카메라의 Local y축(Up Vector)인 v는 다음과 같이 정의된다.

 

$$v = w \times u $$

 

w와 u가 이미 직교인 단위 벡터이므로, 따로 정규화할 필요가 없다. 

 

 

 

 

 

 

Comments