-
3. 뷰 행렬프로그래밍/3D게임프로그래밍 2014. 4. 16. 03:14반응형
로컬 좌표 계의 위치로 설정된 정점은 장면 연출을 위해서 먼저 월드 행렬을 통해서 월드 변환을 합니다. 다음으로 카메라가 정의된 카메라 공간으로 변환하는데 이 변환을 뷰 변환이라 하고 이 때 정점의 변환에 적용되는 행렬을 뷰 행렬 이라 합니다. 뷰 행렬은 카메라의 위치, 카메라가 보고 있는 지점, Up벡터를 입력 받아서 만들어 집니다.
보통 카메라의 위치를 Eye벡터라 하고, 카메라가 보고 있는 지점을 Look 벡터라 합니다. 뷰 행렬을 만들기 위해서 먼저 카메라의 시선 방향을 설정하는데 이것을 카메라의 z 축으로 설정합니다.
이 z 축과 Up 벡터를 이용해서 카메라의 x 축 벡터, 카메라의 y 축 벡터를 다음과 같이 만듭니다.
Zaxis = 카메라가 보고 있는 지점 위치(Look) - 카메라의 위치 (Eye);
Zaxis = normalize(Zaxis);
Xaxis = Cross(Up,Zaxis);
XaXis = normalize(Xaxis);
Yaxis = Cross(Zaxis,XaXis);
위의 방법은 Direct3D가 왼손 좌표를 사용해서 이에 맞게 만들었습니다. 만약 OpenGL과 같이 오른손 좌표계 를 사용하는 경우라면 마지막 y 축을 결정할 때 x 와 z 축의 순서가 바뀌어야 합니다.
이렇게 카메라의 x 축, y축 , z 축을 구했으니 월드 공간에 있는 정점의 위치를 카메라 공간의 x 축, y축 , z 축에 해당하는 값을 구하면 이 값들이 카메라 공간으로 정점의 위치가 변환된 값이 됩니다. 이 값들은 간단히 카메라의 각각의 축에 대해서 카메라와 정점의 상대적인 위치 값을 내적을 이용해서 다음과 같이 계산 하면 됩니다.
P = 정점 위치;
Eye = 카메라 위치;
Float3 T = P - Eye; //카메라와 정점의 상대 위치
카메라 X축에 대한 값 = Dot(T, 카메라 X축);
카메라 Y축에 대한 값 = Dot(T, 카메라 Y축);
카메라 Z축에 대한 값 = Dot(T, 카메라 Z축);
위의 계산 방법을 조금 변형하면 다음과 같이 쓸 수 있습니다.
X' = Dot(P – Eye, Xaxis);
Y' = Dot(P – Eye, Yaxis);
Z' = Dot(P – Eye, Zaxis);
괄호를 풀어 다음과 같이 작성합니다.
X' = Dot(P, Xaxis) - Dot(Eye, Xaxis);
Y' = Dot(P, Yaxis) - Dot(Eye, Yaxis);
Z' = Dot(P, Zaxis) - Dot(Eye, Zaxis);
정점의 3차원 위치를 4차원 동차 좌표로 바꾸고, 행렬을 이용하면 다음과 같이 만들 수 있습니다.
뷰 행렬 =
수학적인 표현을 사용한 뷰 행렬을 프로그램으로 작성하기 위해서 다음과 같이 의사 코드(Pseudo code)를 작성합니다.
만약 뷰 행렬을 만드는 것이 어렵다면 Direct3D의 D3DXMatrixLookAtLH() 함수를 이용해서 위와 같은 내용을 구할 수 있습니다.
반응형