Article

Gamza 2011. 5. 19. 12:20

화면좌표로부터 카메라공간좌표를 얻어내는것은 생각보다 쉽게 유도가 됩니다.

각 행렬들이 어떻게 생겨먹었는지만 좀 알면 되죠.
다만...정변환과정을 모르고 역변환을 한다는건 불가능하겠죠?
이 과정에 대해선 이미 잘 알고 계신다고 생각하고 글을 풀어나가겠습니다.
모르시는 분들은 아래에 있는 '공간좌표에서 화면좌표로의 변환과정에 대하여...' 를 참고하시기 바랍니다.
음...그럼 각 행렬이 어떻게 생겨먹었는지 좀 알아볼까요?
Mproj(원근투영)

Mclip
Mvs

근디...DX에서 프로젝션 행렬이라 함은...Mproj * Mclip을 말하죠.
(Panning 은 Mclip에의해 일어나는 현상입니다.)
따라서 다음과 같은 꼴의 행렬이 나오게됩니다.
MDXproj = Mproj * Mclip
[ ? 0 0 0 ]
[ 0 ? 0 0 ]
[ ? ? ? 1 ]
[ 0 0 ? 0 ]
자...그럼 실제 카메라 공간의 점을 하나 잡아놓구 변환을 해보죠.
(x,y,z,1) * MDXproj * Mvs
Xp = ( x * MDXproj.11 + z*MDXproj.31 ) * Mvs.11 + z * Mvs.41
Yp = ( y * MDXproj.22 + z*MDXproj.32 ) * Mvs.22 + z * Mvs.42
Zp = ( z * MDXproj.33 + 1*MDXproj.43 ) * Mvs.33 + z * Mvs.43
Wp = z
자...이제...실제 화면 좌표가 나왔습니다.
Xs = Xp/Wp = ( x/z * MDXproj.11 + MDXproj.31 ) * Mvs.11 + Mvs.41
Ys = Yp/Wp = ( y/z * MDXproj.22 + MDXproj.32 ) * Mvs.22 + Mvs.42
Zs = Zp/Wp = ( MDXproj.33 + 1/z * MDXproj.43 ) * Mvs.33 + Mvs.43
여기에 Mvs의 실제값을 대입해서 스크린 좌표를 계산해보죠.
Xs = ( x/z * MDXproj.11 + MDXproj.31 ) * dwWidth/2.0f + dwX + dwWidth/2.0f
Ys = ( y/z * MDXproj.22 + MDXproj.32 ) * -dwHeight/2.0f + dwY + dwHeight/2.0f
Zs = zfunc(z) ; //좀 복잡해서리...^^

헥헥...자...이제 원점으로 돌아갑시다. 문제가 뭐였죠?
Xs,Ys,Zs 가 주어졌을때 x,y,z 를 구하는.....켁...!!!
중학교수준의....문제가 되어부렸네요.....-.-;;;;
x = ( ( ( (Xs-dwX)*2.0f/dwWidth - 1 ) - MDXproj.31 ) / MDXproj.11 ) * z
y = ( ( - ( (Ys-dwY)*2.0f/dwHeight - 1 ) - MDXproj.32 ) / MDXproj.22 ) * z
z = inverse_zfunc(Zs)

뭐...꼭 Zs를 사용하지 않고 z 에 원하는 값을 넣어서 카메라 좌표계의 임의의 z에 대한 좌표를 바로 뽑을수도 있습니다.
z=t 라고하면 x=A*t y=B*t 꼴의 직선의 방정식이 됩니다. ( 카메라위치와 스크린좌표를 지나는 )
임의의 z(뷰공간)에 대한 x,y를 뽑을수 있다는 말이죠.

참...마지막으로...
이렇게 구해진 x,y,z 에 Inverse( ViewMatrix ) 를 곱해주면 월드 공간에서의 좌표가 나오겠죠?
Inverse( WorldMatrix * ViewMatrix ) 를 곱하면 오브젝트 공간상의 좌표가...^^

♡달링 알랍♡


좋은글 정~~말 감사합니다.