DirectX/개념

[DX] ##2. Local, World, View Space

코딩하는상후니 2022. 7. 29. 22:00

 


 

*하나의 점이 화면에 보여지기까지의 과정
 

 

 

*LocalSpace

 
=> 어떤 점들을 원점을 기준으로 어디에 위치해있는지 표현하는 공간.
=> 점이 시작되는 좌표가 있는 공간.
 
즉, 초기 물체가 그려지는 공간.
 

 


 

*WorldSpace

 
=> Local space 에서 그려진 물체를 크기,회전,위치를 가진 정보를 더해 Worldspace 공간으로 넘긴다.
 
=> 물체가 크기, 회전, 위치를 가지는 공간. 흔히 ' SRT ' 라고 부른다.
 
=> 물체마다 독립적인 World 행렬 존재
 
 
 
 

 

 

*Translation 행렬

 
=> 이동행렬의 이동 값들은 마지막 4x4 마지막 줄에 정의되어진다.
 

 

 

 

 

 

 

*Scale 행렬

 
=> 벡터의 스케일을 키워주는 행렬
 
=> 위치를 원점에 놓고 계산해야 물체 자체만을 키울 수 있음.
=> 그렇지 않으면 커지긴 커지지만, 이동하면서 커지게 됨.
=> 보통 원점을 기준으로 잡음 ( 0, 0, 0 )
 

 

 

 

 

 

 

 

*Rotation 행렬

 
=> '축' 을 기준으로 돌리는 개념.
 
 

 

*축-각도 회전 공식
 

 

 

 

*원의 반지름 r 이라고 하면, 왜 n x v = r  이 되는가 ??
||n x v|| = ||n|| ||v|| sin 𝛼   => n = 1
=> 직각삼각형 높이 => 원의 반지름
 
즉, n x v 외적 시
||n|| = 1 일 때, v 를 빗변으로 하는 직사각형 높이 가 나오게 됨.
반대로 ||v|| = 1 이라면, n 을 빗변으로 하는 직사각형 높이가 나옴.
 
 
결과적으로,
 
회전 할 벡터(v) 를 해당 축(n) 을 기준으로 원을 그리면서 회전할 때,
 
1. n,v 를 이용해서 원을 기준으로하는 x,y 축을 구한다.
 
2. x 축에 회전할 각도 cosθ 을 적용 시키고 y 축에 sinθ 을 적용해 더하게 되면
최종적으로 회전된 위치가 나오게 됨.
 
즉,  cos(θ) v⟂   +   sin(θ) ( n x v )   =  Rn ( v⟂ )

 

 

 

 

 

 

 

*단위원 회전

 
=> 이러한 원리로 보통 단위원 회전 방식으로 생각하게 되는데,
회전되는 축을 기준으로 다른 기저 축이 움직인다고 생각해야한다.
 
또한, 회전될 때, θ 를 기준으로 한 직각 삼각형이 움직인다고 생각하면 편하다.

 


 

=> 위 3가지 행렬을 이용해 'SRT 행렬' 을 만든다.
=> 해당 행렬을 LocalSpace 에 곱함으로써, WorldSpace 공간으로 넘어간다.
=> '순서 중요'
 
 
 
 
 
* 왜 Rotation 이 먼저 적용되면 안될까 ( RST ) ??
 
전체 크기를 스케일할 때는 같지만
한 축만 스케일 한다고 했을 때, 우리가 원하던 모양이랑 다를 수 있다.
우리는 Local Space 에서 넘어온 물체를 스케일하려는 것이지
넘어와서 회전시킨 물체를 스케일하는 것이 아님.
 
기본적으로 회전행렬에서 볼 수 있듯이,
단지 스케일 값으로 기저 축을 기준으로 늘리는 것이기 때문에
회전행렬로 선형변환된 축 기준으로 늘리는 것이 아님. ( 우리가 원하는 그림. )
 
 
기저  :  한 차원을 담당하는 축.
 
 
 

 

 

 

*View Space

 
 
=> 카메라 공간이라고 하기도 한다.
=> 일단 View Space 로 가기 위해선 World Space 에서와 마찬가지로
어떤 행렬을 곱하는 선형변환을 통해 이루어진다.
 
우리는 카메라를 통해서 해당 물체를 봐야하기 때문에
'카메라 위치를 기준' 으로 해당 물체가 어디 놓여져야하는지 알아야한다.
 
 
 
해당 행렬을 구하기 위한 방법은 2가지가 존재한다.
 
 
 
 
 
 
 
1. 카메라 월드 행렬 이용하기
 
=> '카메라의 역행렬' 이 곧 View Space 로 가는 행렬이다.
 
 
 
왜 그럴까 ??  생각해보자.
 
1. 카메라를 오른쪽으로 '5' 만큼 움직이는 것.
2. 물체를 카메라 기준 왼쪽으로 '5' 만큼 움직이는 것.
 
카메라를 우리의 눈이라고 생각할 때,  위 2가지 상황은 같다.
 
 
 
회전도 같은 개념이다.
대신, 위 상황과 마찬가지로 항상 카메라 기준의 회전인 것을 명심해야함.
 
즉,
1. 카메라가 오른쪽으로 30도 회전
2. 물체가 카메라를 기준으로 왼쪽 30도 회전 ( 공전의 개념 )
물체가 왼쪽으로 30도 회전 ?? => ( X )
 
 
 
 
( 카메라 월드행렬 RT ) => ( RT )-1 = T-1R-1 
R-1  =  Rt
=> 카메라의 회전 행렬 경우에는 '직교행렬' 특징 만족 =>  역행렬 = '전치행렬'
 
 
 
 
 
 
 
 
 
2. 카메라 위치, 방향 이용하기
 
 
*XMMatrixLookToLH ( FVECTOR EyePos, FVECTOR FocusPos, FVECTOR UpDir ) ...
 
 
 
EyePosition  :  카메라의 위치
FocusPosition  :  카메라의 전방벡터
UpDirection  :  대부분 ( 0.f , 1.f, 0.f )
 
 
=> 업벡터 ( 0.f, 1.f, 0.f ) 를 받는 이유는 전방벡터와 업벡터를 이용해 RightVector 를 만들 수 있음.
=> 결과적으로, '두 번 의 외적 ' 을 통해서 RightVector, UpVector 를 구할 수 있음.
함수로 구한 3x3 행렬을 전치시키고 ( 직교행렬 의 역행렬 )
카메라 위치를 반대로 넣어주게 되면 View 행렬 완성.
 
 
 
 
=> 1번에서 구한 행렬과 같은 행렬
 
 
 
Matrix _matView2 = {};
Vec3 Pos = GetTransform()->GetWorldPosition();
Vec3 Look = GetTransform()->GetLook();
Vec3 Up = Vec3(0.0f, 1.0f, 0.0f);
_matView2 = XMMatrixLookToLH(Pos, Look, Up);
 
 
 
*XMMatrixLookToLH
Builds a view matrix for a left-handed coordinate system using a camera position, an up direction, and a camera direction.
=> '방향' 을 기준으로 설정.
 
 
*XMMatrixLookAtLH
Builds a view matrix for a left-handed coordinate system using a camera position, an up direction, and a focal point.
=> 카메라가 집중할 '위치' 를 의미하는 점을 바탕.

 

 

 

 


 

 

참고 자료

 

- DirectX 11을 이용한 3D 게임 프로그래밍 입문