Camera Transformation - Lookat

Camera 변환에는 LookAt 변환과 카메라의 회전량과 위치를 통한 변환이 있다.
여기서는 먼저 Lookat에 대해 먼저 다루도록 하겠다.

LookAt변환은 상대적으로 단순한 형태로서
눈의 위치(eye) 에서 보는 위치(at) 그리고 카메라의 윗 방향 (up)으로 구성된다. 

카메라 공간도 공간임에 따라 행렬로 설명할 수 밖에 없다.
그러므로 카메라 변환을 살펴보기 앞서 행렬공간에 대해 짤막하게 미리 살펴보자.

에디터가 행렬을 나타내기 여의치 않으므로 MATLAB에서 나타내는 행렬 표기방식으로 설명을 진행한다.
" "는 다음 열의 값을 ";"은 다음행의 값을 나타낸다.
[1 2]는 1행 2열 행렬을 [1;2]는 2행 1열의 행렬이다.

공간을 정의함은 3개의 기저벡터를 지정하는 것이라 할 수 있다.
즉 [1 0 0;0 1 0;0 0 1]은 [1;0;0], [0;1;0], [0;0;1]의 3기저로 구성된 공간인 것이다.

기저는 열벡터이기 때문에 벡터지정 요소 사이에 ;을 기입했음에 주의하자.
열벡터가 나타내는 공간이므로 기저 V1, V2, V3가 나타내는 공간은
[V1x V2x V3x;V1y V2y V3y;V1z V2z V3z]이다.

즉 [2;3;4]벡터는 공간 [V1x V2x V3x;V1y V2y V3y;V1z V2z V3z]에서 다음 위치가 된다.
V1*2+V2*3+V3*4
= [V1x;V1y;V1z]*2 + [V2x;V2y;V2z]*3 + [V3x;V3y;V3z]*4
벡터 [2;3;4]는 공간 [V1x V2x V3x;V1y V2y V3y;V1z V2z V3z]에서 벡터 첫번째 요소는 첫번째기저와
벡터 두번째요소는 두번째기저와 그리고 벡터 세번째요소는 세번째 기저와 곱해진다.

행렬공간의 기저를 좀더 심도 있게 설명해 보겠다.
각 기저끼리 직각인 공간을 직교 (Orthogonal) 라한다.
그리고 기저의 길이가 1이면 정규직교 (Orthonormal) 이라한다.
일반적 3차원공간의 기저는 각 기저끼리 직각이다. 만약 직각이 아니라면 왜곡된 형태의 공간이 된다.
만약 한 기저가 틀어져있다면 틀어진 기저로 변환이 될 것이다. 
위에 제시한 공간상으로의 변환을 다시한번 확인해보자.
[V1x;V1y;V1z]*2 + [V2x;V2y;V2z]*3 + [V3x;V3y;V3z]*4
--> V1*2+V2*3+V3*4
V1, V2, V3기저가 직각이 아니라면 틀어진 공간으로의 변환이 될 것이다.
만약 기저 V1의 길이가 2라면 V1과 곱해지는 2는 2배가 아닌 4배가 된다.

그러므로 행렬공간은 각 기저가 직각이며 길이가 1인 정규직교이어야 한다.

위의 행렬공간의 기저를 이해하면 카메라 변환은 그냥 장난이다.
즉 우리가 처리해야할 것은 eye, at, up을 통한 행렬을 만드는 작업이다.
그 공간은 정규직교 공간임은 물론이다.

lookat에 들어가는 eye, at, up을 생각해보자.
이들은 단순히 위치만을 나타내는 벡터가 아닌 좌들로 구성된다.
각 기저를 찾아보자!!!!!!!(3개의 기저벡터가 필요하다)
eye의 위치에서 at으로 향하는 벡터를 생각할 수 있다.
이 벡터는 우리가 보는 카메라 공간에서 화면으로 들어가는 방향인 z를 의미함을 이해할 수 있을 것이다.
즉 이 것이 z축의 기저 V3이어야 한다.
두 번째 찾을 기저는 x축 기저이다.
up벡터는 위를 향하는 벡터로서 잠정적 y이다. 그러나 직교하지 않을 수 있다.
at-eye를 통해 찾은 V3기저와 up이 직교가 아니더라도 외적 연산을 통해 두 벡터에 직교하는 V1기저를 찾을 수 있게 된다.(아하!!!!!!!!!_ 이부분이 중요함!!!!!!!)
끝으로 V3와 V1을 외적시키면 나머지 V2를 계산할 수 있다.

<<수학함수>>
cross: 외적
cross([V1x;V1y;V1z], [V2x;V2y;V2z])
= [V1y*V2z-V1z*V2y;    V1z*V2x-V1x*V2z;      V1x*V2y-V1y*V2x]

이를 skew-symmetric matrix형식으로 나타내어 행렬 곱의 형태로 나타낼 수도 있다.
[x;y;z] -> [0 -z y;z 0 -x;-y x 0]

1) skews(V1)*V2
[0 -V1z V1y;V1z 0 -V1x;-V1y V1x 0][V2x;V2y;V2z]
-> [-V1z*V2y+V1y*V2z;    V1z*V2x+-V1x*V2z;     -V1y*V2x+V1x*V2y]

2) transpose(skews(V2))*V1
[0 V2z -V2y;-V2z 0 V2x;V2y -V2x 0][V1x;V1y;V1z]
-> [V2z*V1y+-V2y*V1z;-V2z*V1x+V2x*V1z;V2y*V1x+-V2x*V1y]

normalize: 정규화

V3=normalize(at-eye)
V1=normalize(cross(up, V3))
V2=normalize(cross(V3, V1))

이로서 eye, at, up을 통한 lookat연산을 완성했다.






카메라가 가끔 헷갈려 정리해봤다!!!
역시 블로그로 정리하면서 공부하는 맛은 쏠쏠해 ㅋㅋ

이 글을 공유하기

댓글

Designed by JB FACTORY