센로그
3. Spaces and Transforms 본문
※ 참고
본문 내용들은 좌표값이 열벡터로 표현될 때에 관한 것임.
행벡터로 사용하고 싶으면 양 변 전치하면 됨. (AB)T = (BT)(AT)
열벡터를 v, 변환 행렬을 M이라고 할 때 Mv가 변환된 결과값이 될 것.
행벡터(vT)인 경우, (Mv)T = (vT)(MT)가 성립함.
OpenGL은 열벡터(column vector style)를 사용하는 데 반해, DirectX에서는 행벡터(row vector style)를 사용함. 따라서 변환 순서 유의하자.
◆ Scaling
오브젝트의 사이즈를 바꾸는 것.
Scaling factor S는 몇 배를 키울건지를 의미함.
각 Vertex 좌표에 곱하는 S가 1보다 크면 커지고, 1보다 작으면 작아짐
◇ 2D Scaling
각 Vertex 좌표(coordinate)에 Scaling Matrix S를 곱해준다.
< 예시 >
그냥 각 성분마다 곱해주면 됨!
◆ Rotation
오브젝트를 회전축을 기준으로 돌리는 것
돌리는 방향은 다음 두가지가 있음
- Clockwise rotation (CW)
- Counterclockwise rotation (CCW)
기본적으로는 CCW 방향이 양수. (양수 θ가 주어지면 CCW 방향으로 돌림)
◇ 2D Rotation
각 Vertex 좌표(coordinate)에 θ만큼 회전하도록 하는 Rotation Matrix R(θ)를 곱해준다.
default로는 CCW 방향으로 회전함.
CW 방향으로 회전시키고 싶다면 θ에 -θ 대입하면 됨!
< 예시 >
◆ 2D Translation
오브젝트를 이동시키는 것
원래 translation은 덧셈으로 표현됨.
그러나 scaling, rotation 등의 곱셈 연산들 사이에서 translation도 곱셈으로 표현하면 더 간편해지는 경우가 있다.
=> 동차 좌표계를 활용해 행렬 곱셈으로 표현 가능!
2D 좌표 (x, y)가 주어졌을 때, 이를 위와같이 동차 좌표인 3D 벡터 (x, y, 1)로 변환해서 행렬 곱셈 가능.
◆ Homogeneous coordinates 동차 좌표계
차원의 좌표를 1차원 증가시켜 표현하는 방법
동차 좌표를 이용하면 행렬간 이동(Translation), 변환(Transformation) 등을 곱셈으로 표현할 수 있다.
< 동차 좌표계에서의 변환 행렬 표현 >
1) Scaling2) Rotation
|
※ (x, y)의 동차 좌표가 항상 (x, y, 1)인 것은 아니다.
엄밀하게는, 0이 아닌 w에 대하여 (wx, wy, w)이 된다.
예를들자면 (x, y, 1) 또는 (2x, 2y, 2) 등이 될 수 있음!
그림에서 A와 B는 동차 좌표계 위에 있다. (같은 벡터 위에 있음)
※ 카르테시안 공간(Cartesian Space)이란 w가 1인 공간을 의미함.
동차 좌표 (X, Y, w)가 주어졌을 때 카르테시안 좌표는 (X/w, Y/w)가 되겠죠?
◆ 2D Transform - Combine matrices
Rotation하고나서 Translation 할거라면, 변환 행렬 TR을 먼저 서로 곱한 후 좌표에 곱해주자.
RT != TR 이므로 순서에 주의.
우리는 일련의 변환 작업을 순차적으로 진행하는 것이 아니라, 돌리고 회전하고 키우고 회전하고 ...섞어서 막 진행함.
이런 걸 효율적으로 하는 법!
그림과 같이 R을 해주고 T를 하고 싶다고 하자.
무작정 해보자면 앞서 배웠던 대로, 하나하나 순서대로 좌표에 곱해줄 수 있다. (다음 그림 참조)
그러나 이건 좀 비효율적인 것 같아! 그러면?
합치자!
R과 T를 한번에 연산해놓은 변환 행렬을 구해주자. (뒤에꺼부터 변환)
이 결과 행렬을 좌표에 곱해주면 같은 값 나옴~
< 순서에 유의 >
Matrix Multiplication은 Noncommutative(비가환적) 이므로 순서가 바뀌면 성립하지 않는다. 유의할 것
먼저 시행하는 변환을 뒤에 넣으면 된다. (열벡터 style일때 기준~ 당연함. 뒤에 위치한 변환 행렬이 좌표와 먼저 연산될 것이기 때문.)
◆ 원점이 아닌 임의의 점을 기준으로 Rotation 하는 법
원점 기준으로 옮겨서, 회전하고, 다시 이동하기
아까 배웠던 rotation은 원점 기준 rotation이었다!
그러면 임의의 점을 기준으로는 어떻게하지!?
=>원점 기준으로 옮겨서, 회전하고, 다시 옮겨주자!
< 예시 >
(a, b)를 기준으로 회전 변환을 하고싶다면!
일단 좌표계에서 -a, -b만큼 이동하면 원점 기준으로 바뀜
그러고 나서 회전 변환을 함
그 다음에 다시 +a,+b만큼 이동하면 됨.
즉, Rotation Matrix 앞뒤로 Translation Matrix를 곱해주어 원점에서의 회전 변환처럼 만들어주고,
이 변환행렬을 좌표에 곱해주면 됨~
◆ Affine Transform 아핀 변환
선형 변환(scaling, rotation)과 translation 변환이 결합된 변환
아핀 변환의 예시로는 다음과 같이 RT, SRT 등이 있을 수 있겠다.
◇ Affine transform - [L|t] transform
아핀 변환 결과로부터 L과 t를 분해해서, 따로 연산할 수 있다.
위의 아핀 변환 결과에서, 마지막 3행을 무시하면 2x3 행렬만 남는다.
결합된 Scaling이나 Rotation 부분인 2x2행렬을 L(combined Linear Transformation)로 표현하고,
결합된 Translation 부분인 2차원 열벡터를 T(combined Translation) 로 표현할 수 있다.
이러한 형태의 matrix를 [L|t]로 나타낸다.
※ L은 t 부분을 포함하지 않아 여전히 선형 변환이고, T는 L부분을 포함하기도 한다.
그럼 [L|t]를 왜 배우냐?
변환할 점을 p라고 할때, [L|t]는 Lp + t의 형태로 쓸 수 있다.
p에 L변환을 먼저 연산해주고, 그 다음에 t변환을 더해줄 수 있다는 뜻!
◇ Affine transform - Rigid Motion ( [R|t] transform )
Scaling과 관련없는, 즉 Rotation과 Translation만이 결합된 아핀 변환을 의미.
모양은 바뀌지 않고 Position(위치)과 Orientation(방향)만 변하는 강체 변환을 표현할 때 주로 사용.
게임에서 많이 보는 상호작용은 주로 Rigid Motion일 것.
아무리 많은 Rotation 변환과 Translation 변환이 결합되더라도, 결과 행렬은 항상 [R|t]의 형태로 표현할 수 있다.
따라서 항상 분해된 두 개의 step, 즉 Rp + t를 통해 물체를 변환할 수 있다!
※ R은 t부분을 포함하지 않아 여전히 Rotation 변환이고, t는 R 부분을 포함하기도 함.
◆ 3D Scaling
세 개의 Scaling factor Sx, Sy, Sz를 사용한다.
- Uniform Scaling : 세 Scaling factor가 같은 값인 경우. x, y, z축을 같은 비율로 늘리는 것을 의미함.
- Non-uniform Scaling : x, y, z축 비율을 다르게 하는 것
◆ 3D Rotation
회전축 관련 좌표 제외하고, 나머지 축들 관련 좌표에 회전 행렬 넣어서 변환 행렬 만듦.
2D에서는 회전 중심점이 필요했던 반면, 3D에서는 회전 중심축이 필요하다!
중심 축은 그대로 두고, 나머지를 돌리는 결과가 나오도록 해준다.
적용하면, z축 중심 회전은 위와 같이 표현할 수 있음!
< 3D Rotation Matrix >
x축, y축, z축을 중심으로 회전하도록 하는 회전 행렬을 각각 Rx, Ry, Rz라고 하자.
← Rx
← Ry ; 주의! y축 회전은 회전 행렬에서 - 위치가 바뀜
← Rz
◇ 3D Rotation - CCW vs CW
3D에서도, default로는 positive angle이 CCW 방향을, negative angle이 CW 방향을 의미한다.
※ 3D rotation에서, -θ == 2π -θ 이다. 즉 -90º == 270º이다.
◆ 3D Translation
동차 좌표계를 사용해 4차원으로 확장한 후, 곱셈으로 표현할 수 있다.
앞서도 언급했듯이, Translation은 기본적으로 곱셈이 아닌 덧셈으로 표현된다. 3D Translation에서도 동일하다.
이를 곱셈으로 표현하려면 동차 좌표가 필요하다.
이에 따라 편하게 연산하기 위해, 3D Scaling Matrix와 3D Rotation Matrix도 4x4 행렬로 확장할 수 있다.
이런 식으로! (Scaling)
또는 이런 식~ (Rotation)
◆ World Transform
Object Space ~> World Space로의 변환
< Object-space vs World-space >
어떤 object를 만들 때 사용되는 좌표계 시스템을 object space이라고 함.
자기 자신이 만들어졌을 때는 주변에 뭐가 있는지 모름. 즉, 한 object의 object space는 다른 object들과는 전혀 관계X
World transform은 모든 object들을 world space라는 하나의 좌표계 시스템으로 모으도록 하는 변환을 의미함.
(자세한 설명: https://grace7040.tistory.com/70)
◆ 3D Affine transform
2D 때와 똑같음. 선형 변환(Scaling, Rotation 변환)과 Translation 변환을 결합한 변환.
마찬가지로 아핀 변환 행렬은 3x4 행렬인 [L|t]로 분리할 수 있음. 3x3 행렬인 L과, 3차원 열벡터인 t로 이루어짐.
L 연산 먼저 하고, t 연산 더해주는 두 단계 분해할 수 있음. (Lp + t)
◆ Rotation과 Object-space 기저(Basis)
object space의 기저를 {u, v, n}이라 하고, world space의 기저를 {e1, e2, e3} 라 하자.
처음에 그냥 object를 만들면 두 space의 기저들의 방향이 각각 동일할 것임. (e1 = u, e2 = v, e3 = n)
근데 만약, rotation 변환을 해준다고 하자. 이는 object space의 기저가 통째로 돌아감을 의미.
회전한 u, v, n은 기저 e1, e2, e3에 R 변환을 한 것으로 구할 수 있음.(처음 생성되면 world space의 기저와 같으니깐)
얘네 셋을 합치면,
즉! 회전한 결과값{u, v, n}을 알고 있을 때, 이 회전을 만든 Rotation Matrix R은 다음과 같이 바로 구할 수 있다.
u v n 열벡터가 그대로 들어가면 됨~
(row vector style일때는, u v n이 행으로 들어갈 것~ 위의 R 전치 형태!)
◆ Inverse Transformation
변환 행렬들의 역변환에 대해서~
Translation, Scaling은 직관적으로 이해할 수 있고
Rotation의 Inverse는 Transpose와 같다.
■ Inverse Translation
■ Inverse Scaling
■ Inverse Rotation
이다.
직관적으로 이해하기 위해 크기가 1이고(u·u = v·v = n·n = 1) 서로 직교(u·v = v·n = n·u = 0)하는 u, v, n의 예시를 보자.
이때 RTR은 다음과 같다.
※ 실수 영역에서 Rotation 행렬의 역변환은 transpose(전치) 행렬이지만,
복소수 영역에서는 conjugate transpose(켤레 전치) 행렬임.
'게임 > 그래픽 프로그래밍' 카테고리의 다른 글
5. Input Assembler & Vertex Processing(2) (0) | 2023.05.12 |
---|---|
4. Input Assembler & Vertex Processing(1) (4) | 2023.05.12 |
2. Vectors and Matrices (0) | 2023.03.31 |
1. Modeling (0) | 2023.03.14 |
Graphics Rendering Pipeline 그래픽스 렌더링 파이프라인 (1) | 2023.02.04 |