본문 바로가기

Today I Learned

23. 05. 24 - 좌표 변환

로컬 -> 월드

 

기존에 로컬 좌표에서 월드 좌표로 변환할 때 

 

월드 변환 행렬을 기 X 전  X 동 X 전 X 모로 외웠다. 

 

하지만 이번에 월드 좌표로 변환하는 다른 방법을 알려주셨다.

4x4 행렬에서 1행은 x축, 2행은 y축, 3행은 z축, 4행은 이동한 좌표를 의미한다.

그래서 x축 회전값을 1행에, y축 회전 값을 2행에, z축 회전 값을 3행에, 이동한 좌표를 4행에 넣는다.

그리고 크기는 4x4의 11,22,33번째 요소라고 오해하는 경우가 있는데, 

각 축의 크기는 각 행의 길이다. (x축의 크기의 경우 첫번째 행의 길이)

 

 

 

월드 -> 뷰

 

월드 좌표로 변환한 후에는 카메라가 보는 시점으로 좌표를 전환해야 한다. 이것을 뷰 스페이스라고 한다.

그러기 위해서는 카메라가 좌표계의 원점에 있어야하고 z축 방향으로 바라보고 있어야 한다.

이것은 카메라가 로컬좌표계에 있을 때와 같은데 그래서 뷰 변환 행렬은 카메라 월드 행렬의 역행렬로 구할 수 있다.

 

 

 

뷰 -> 프로젝션

 

이제 화면에 표현하기 위해 3차원 공간을 2차원 공간으로 바꿔야 한다. 물체의 z값을 없애버리면 된다는 간편한

선택지도 있지만 그러면 원근감을 표현할 수 없어 직교 투영(orthographic)밖에 표현할 수 없게 된다.

그래서 좌표를 z값으로 나눈다. (z값이 커질 수록 작아짐) 카메라는 near에서 far까지 z값의 표현 범위를 가지고 있는데

near이 0이 될 수 없는 이유도 z값을 0으로는 나눌 수 없기 때문이다. 하지만 또 단순히 z로 나누기만 한다면 z값이 모두 1로 같아져버린다. 그래서 우선 투영 행렬을 곱한다. (투영행렬은 후에 서술) 프로젝션 변환은 단순히 투영 행렬을 곱한다고 해서 되지 않는다. 투영 행렬을 곱해 z값을 0 ~ far로 만들고 (x,y,z,w)의 w자리에 z값을 보관한다. 그 후 w값을 이용해 

나누어 z값을 0~1로 만든다. 프로젝션 변환은 투영행렬을 곱했을 때 되는 것이 아니라 그 후 w로 나눴을 때 변환된 것이다.

 

 

 

그러고 나면 좌표가 (-1,1) 왼쪽 위 ~ (1,-1) 오른쪽 아래 인 화면이 되는데 이것을 화면 크기에 맞게 또 변환해야 한다.

화면 비율(width/height)를 구해 나눠주면 된다. (x,y,z,w)에서 방향 벡터일 경우 w가 0이고 위치 벡터일 경우 1인데

방향 벡터일 경우 이동 좌표를 무시하고 위치 벡터일 경우 이동한 좌표를 포함하기 때문이다. 그리고 transformcoord나 

월드 행렬, 뷰 행렬을 곱할 때도 곱하고나서 w로나누는 계산을 포함하지만 w가 1이므로 결과가 바뀌지 않는다.