본문 바로가기
DirectX 12/Vector & Matrix

[DirectX12 - Vector & Matrix] Chapter 05. World, View 변환 행렬

by song.ift 2023. 6. 30.

로컬 스페이스 -> 월드 스페이스 -> 뷰 스페이스

투영
- 카메라에 찍힌 모든 물체들을 비율에 맞춰 화면안에다가 맞게 찍히게 변화하는 단계
화면안에 들어오는 것들의 범위를 Clip Space 라 한다.

마지막 단계로 스크린에다가 그려주는 것을 뷰포트 라고 한다.
해상도마다 비율이 다르니 비율에 맞춰주는 작업들.


 

로컬스페이스
-x,y,z 쪽을 순서대로 right, up, look 벡터라고 한다.

로컬스페이스에서 월드 스페이스로 갈려며 월드행렬을 해주면 된다.
반대로 월드스페이스에서 로컬 스페이스로 갈려며 월드역행렬을 해주면 된다.

 

월드행렬
(x, y, z, 1) [right.x right.y right.z] = (X, Y, Z, 1) <- 월드행렬
     [up.x    up.y    up.z   ]
             [look.x  look.y  look.z ]
             [pos.x   pos.y   pos.z  ]
pos는 월드의 원점을 기준으로 한 기저벡터, 월드 좌표임
pos는 SRT의 T임. SR도 있다하면 위의 월드변환행렬에 각 SR에 맞는 값들이 곱하고 더해지게 됨.
그래서 월드행렬은 SRT 행렬을 적용한 결과물임


 

뷰 스페이스(카메라스페이스, eye스페이스)
-모든 물체들을 카메라에 맞춰 좌표계가 변한다.
카메라를 기준으로 즉 카메라의 좌표를 원점으로 잡고
카메라가 바라보는 축을 z축으로 잡는 새로운 좌표계를 만들어 그것을 뷰행렬이라고 연산해주게 된다.

카메라의 로컬스페이스로 모든 애들을 끌고온다고 볼수있다.

카메라는 절두체가 있으며, 그 절두체 안에 있는 것들만 보여준다



월드스페이스의 정점을 카메라 좌표계에 맞춰야 하는 이유?
http://egloos.zum.com/EireneHue/v/984622
밑에 답변 :

자, 그런데 왜 월드 스페이스의 정점들을
카메라 좌표계에 맞도록 만들 필요가 있을까요?

이 이유는, 결국 소프트웨어 속에서 우리가 보통 생각하는 카메라와 같은 개념은
존재할 수 없기 때문입니다. 생각해 볼까요? 현실 세계에서 사람은 항상 눈을 통해서
무언가 볼 수 있습니다. 고개를 돌리면 다른 곳을 바라볼 수 있게 되겠지요.

하지만 모니터에 출력된 화면은 그런 식의 개념이 성립하지 않습니다.
윈도우 창은 언제나 자신이 보여줄 픽셀정보만 가지고 있는 것일 뿐이므로,
어디까지나 픽셀 단위로 출력할 내용을 변화시키는 것으로 모든 것을 구성해야 합니다.

이는 다이렉트 3D 환경 역시 마찬가지입니다. 정의하자면, 

카메라가 존재하는 것이 아니라, 

카메라가 존재하는 것 처럼 보이도록 조작하자!

라고 정의하면 보다 접근하기가 쉬울 듯합니다. 촛점을 카메라가 존재하는 것처럼
보이도록 눈속임을 만드는 것에 두십시오.
그렇다면 마치 카메라가 존재하는 것 처럼 보인다는것은 무엇을 의미하는 것입니까?
화면은 가만히 있는데, 다른 모든 객체가 동일한 방향으로 이동하면, 어떻게 보일까요?
이때는 마치 화면이 이동하는 것처럼 보입니다.
회전 역시, 모든 객체가 일정하게 회전하는 것으로 비슷한 효과를 줄 수 있습니다.

따라서 카메라 개념을 도입한다는 것은, 카메라 라는 객체를 만들고, 이 객체의 위치와,
회전상태 등에 대한 정보를 준비한 후, 이들을 실제 월드 스페이스에 정점정보로써
존재하는 객체들에 적용하여 모든 객체의 좌표를 변경하는 것이라 할 수 있습니다.

카메라가 이정도 이동했고 이정도 회전하는 것처럼 보여주고 싶다.
그러면 월드의 정점들이 어느정도 이동하고, 어느정도 회전하면 마치 카메라가
월드 속에서 회전하고 이동하는 듯한 모습을 연출할 수 있다는 뜻입니다.

 



월드에서 카메라의 로컬로 돌아가고 싶으면 카메라의 역행렬을 구하면된다.
즉 카메라의 월드변환의 역행렬이 그 역행렬 자체가 뷰 스페이스로 변환하는 열쇠가 될 수 있다.
그게 뷰 변환 행렬이라 볼 수 있다.

 


 

근데 뷰 변환 행렬을 구하는 방법중에 역행렬말고도 또 다른 방법이 있다.
내장 함수 중에 
XMMATRIX XM_CALLOCN XMMatrixLookAtLH {
FXMVECTOR EyePosition, // 카메라 위치
FXMVECTOR FocusPosition, // 포커스 포인트(카메라가 보는 하나의 점)
FXMVECTOR UpDirection      // y로 1.0f인 단위벡터
}
이 있다.

뷰 변환 행렬을 보면
[right.x up.x look.x 0]
[right.y up.y look.y 0]
[right.z up.y look.z 0]
[c.right c.up c.look 1]
으로 나와야한다.

원리는 이러하다.
EyePosition에서 FocusPosition까지의 벡터가 Look.
그다음 UpDirection에서 Look을 외적하면 right를 구할 수 있다.
그리고 UpDirection은 임의로 잡은것이지, 실제로 right와 look에 수직 직교인 벡터가 아니다.
그래서 다시 look에서 right를 외적해 실제 up을 구한다.
이것도 뷰 변환 행렬의 도출 방법이다.

댓글