DirectX

13. View 변환 행렬

devRiripong 2023. 12. 21.
반응형

Local 영역에서 물체를 꺼내서 World에 배치했다고 하면 다음은 View이다. 

1. view (camera, eye) space

월드 좌표에서 카메라를 기준으로 다시 한번 좌표를 변환해 주게 된다. 

 

카메라의 영역이 찍고 있는 것에 따라서 가두리 양식장 안이 찍히게 될 것이고, 이걸 카메라 스페이스 혹은 뷰 스페이스, 아이 스페이스라고 부른다. 

 

World 좌표에서 Camera 좌표로 넘어갈 수 있는 View 행렬을 곱해서 카메라가 바라보는 좌표에 따라 모든 것을 바꿔줘야 한다. 

 

World좌표에 View 행렬을 곱해서 View좌표로 전환할 수 있다. 반대로  View 좌표를 View 행렬의 역행렬을 이용해서 world좌표로 전환할 수 있다. 

 

카메라의 위치가 0, 0, 0으로 세팅되어 있다면 world 좌표와 달라질게 없다. 하지만 대부분의 경우 카메라는 다른 곳에 있을 것이다.


캐릭터를 클릭하면 world 좌표가 나오는데 어떻게 하면 camera 좌표가 나올지 생각을 해 보자.


카메라가 봤을 때 물체가 작게 보이고, 가까우면 커보인다. 원근법 적용은 카메라에 따라 다르긴 하지만, 보통 원근 투영을 통해서 2D화면에 넣는데 그걸 하기 위해서 1차적으로 카메라를 기준으로 하는 좌표로 변신을 시켜줘야 한다. 

 

2. View 행렬 만들기

행렬을 만들어 보자. 

방법1. 카메라의 월드 좌표 행렬의 역행렬을 구한다.

카메라가 바라보는 기준으로 모든 물체를 바라본다는 말은, 모든 물체들을 카메라의 로컬 영역으로 끌고 가는 거랑 유사하다고 볼 수 있다. 이 말은 카메라의 로컬 스페이스로 모든 물체들의 좌표를 끌고 온다는 얘기로 받아 들일 수 있다.

방법2. 카메라의 Rotation x Translation의 역행렬을 구한다.

카메라가 0, 0, 0위치에 있다면, world위치라면 View 행렬은 그냥 항등행렬이 되지만, 카메라가 다른 위치로 간다면, 유니티에서 카메라를 오른쪽으로 이동하면, 모든 물체들이 왼쪽으로 이동한다는 것을 볼 수 있다. 카메라가 위로 이동하면 모든 물체들이 아래로 이동하고, 모든 물체들이 카메라 이동 방향의 반대로 이동하고, 또한 회전을 하면 반대 방향으로 문체가 공전한다는 것을 알 수 있다. 

 

두가지중 어떤 것으로 선택하든 결과는 같게 나와야 한다. 

식을 만들어 보면, 

방법1.
카메라도 SRT를 통해서 자신의 로컬에서 월드로 가는 것을 구할 수 있는데, 그것의 역행렬을 구하면 된다. SRT에서 Scale은 카메라 이기 때문에 의미가 없고, Rotation, Translation을 구해서 world변환 행렬을 구한 다음에, 그거에 대한 역행렬 자체가 카메라의 뷰 행렬이라고 볼 수 있다. 

 

방법2. 
두 번째 방법은 카메라와 회전과, 이동에 반대로 물체가 이동한다는 것에 착안해 RT의 역행렬을 구하면 된다. 

먼저 R의 역행렬을 구하면, 회전 행렬 부분이 직교 행렬이기 때문에 그냥 transpose를 하면 된다. 

또 T부분의 역행렬은 반대로 이동하는 것이니 -만 붙여주면 된다.

이 둘을 곱해주면 된다.  

4행은 내적으로 간단하게 적었다.

 

3. XMMatrixLookAtLH 함수 사용하기

https://learn.microsoft.com/ko-kr/windows/win32/api/directxmath/nf-directxmath-xmmatrixlookatlh

 

XMMatrixLookAtLH 함수(directxmath.h) - Win32 apps

카메라 위치, 위쪽 방향 및 초점을 사용하여 왼손 좌표계용 보기 행렬을 작성합니다.

learn.microsoft.com

이걸 위처럼 직접 SRT를 구해서 되긴 하지만, 보통 그렇게 안하고 하나의 함수가 마련이 되어 있다. 

XMMatrixLookAtLH 함수가 있다. 
카메라의 Eye 포지션은 카메라의 위치다. 
카메라 위치 하나 지정하고 카메라가 어디를 바라보는지를 두번째 인자로 지정한다. 이게 룩벡터가 된다. 

세번째 인자는 임의로 updirection. 그냥 윗방향 찍어준다. up 찍어주면 함수 내부에서 외적 이용해서 동시에 수직으로 하는 3의 방향을 그려주고, 모든 선들이 직각이 되도록 xyz를 구해주는 원리로 동작을 한다. 이 함수를 쓰면 알아서 뷰 행렬이 만들어진다. 

 

4. 맺음말

만능 공식 이용해서 만들어 줄 수 있었다.
물체가 배치 되어도 로컬 영역이 없어지는게 아니다. 
로컬 좌표가 월드 좌표계로 가면 월드 좌표 기반으로 되고, 그 다음 순서로는 카메라로 찍어서 카메라가 바라보고 있는 좌표를 기준으로 다시 바꿔주는 것이다. 

카메라 스페이스는 카메라의 위치를 0, 0, 0이라 하고, 카메라가 보는 방향을 look 벡터로하고, z축으로 해서 모든 좌표를 변환하는게 끝이다.   

이제 남은 건, 물체가 화면에 어떻게 그려질지 판단하는게 남는다.

다음에 해야할 것은, 카메라를 유심히 보면, 일종의 가두리 양식장 같은게 있어. 
절두체라고 한다.
near, far가 있는데, 영역 안에 들어 있는 물체만 찍혀야 한다. 
가두리 양식장에 들어왔다고 해도 물체들마다 자신들만의 위치가 있다.
카메라가 찍고 있으면 플레이어 앞에 어떤 물체가 플레이어를 가려서 안찍힌다거나 그런 거 까지 염두해야 한다. 

 

다음 단계인 투영단계에서 다 케어하는 거다. 
다음 단계는 투영 좌표계


반응형

'DirectX' 카테고리의 다른 글

15. Screen 변환 행렬  (0) 2023.12.22
14. Projection 변환 행렬  (0) 2023.12.22
12. World 변환 행렬  (0) 2023.12.20
11. 좌표계 변환  (0) 2023.12.19
10. SRT 변환 행렬  (0) 2023.12.18

댓글