4. 로컬공간->월드공간
01
정 점 변 환
로컬 공간(Local Space)
오브젝트별 각자의 기준좌표(원점을 중심으로 하는 좌표)계
를 가지고 있으며, 물체마다 서로 다릅니다.
게임에 사용하기 위해, 우리는 이 로컬 공간의 물체를 세계
공간(World Space)에 적절히 배치해야 합니다.
6. 왜로컬공간을사용할까?
01
1. 오브젝트는 한 씬에서만 사용되는게 아니므로, 한 씬에서의
월드좌표에 고정하는것은 효율적이지 않다. 그러느니 로컬 좌표로
가지고 있다가, 필요한 씬에서의 월드 좌표로 변환하는것이 더욱
낫다.
2. 같은 오브젝트를 위치, 회전방향만 다르게 해서 한 번에 많이
띄워야 할 때, 공통적인 정보만 정의해 놓고(나무 모양, 껍질
색 등) 나무의 위치나 방향, 크기 등은 각각 적절한 월드 변환을
통해 만드는 것이 낫다(인스턴싱).
7. 잠깐멀리돌아갑시다
01
아 핀 공 간 / 아 핀 변 환
벡터 : 크기와 방향만을 가진 값.
벡터 공간 : 벡터에 대해 정의된 연산
법칙(덧셈, 스칼라 배수)이 적용되는
공간
(x, y, z)
벡터의 한계점 : 크기와 방향만을 가졌기 때문에, 위치를 표
현할 수 없다.
즉 게임의 오브젝트를 벡터만으로는 표현할 수 없다.
아핀 공간
8. 잠깐멀리돌아갑시다
01
P = (𝑃𝑥, 𝑃𝑦, 𝑃𝑧)
그래서 ‘점(point)’을 더했습니다.
즉 벡터 공간에 점의 개념을 추가한 공간
이 아핀 공간.
우리가 흔히 사용하는 좌표계(데카르트 좌
표계)과
똑같이 사용합니다.
아 핀 공 간 / 아 핀 변 환
9. 잠깐멀리돌아갑시다
01
아 핀 공 간 / 아 핀 변 환
(2,2,1)
(3,1,5) 1. 𝑃 ± 𝑉 = 𝑃
2. 𝑉 ± 𝑉 = 𝑉
3. 𝑃 − 𝑃 = 𝑉
아핀 공간에서의 점과 벡터의 연산
점 + 점은 아핀 공간에서 사용할 수 없다.
(3,1,5)
(2,2,1)
V = (1, -1, 4)
10. 잠깐멀리돌아갑시다
01
아 핀 공 간 / 아 핀 변 환
아핀 변환
로컬 좌표계 -> 월드 좌표계 좌표 변환을 위해 오브젝트의 구성 요소
인 점, 선, 면 등은 크기/방향/위치를 변환할 수 있어야 한다.
11. 잠깐멀리돌아갑시다
01
아 핀 공 간 / 아 핀 변 환
선형 변환
하나의 벡터 공간을 다른 벡터 공간으로 변환하는 함수.
== 벡터의 크기와 방향을 바꾸는 변환
즉, 스케일 변환과 회전 변환은 선형변환에 속한다.
또한, 선형변환은 행렬의 곱셈 형태로 만들 수 있다.
17. 잠깐멀리돌아갑시다
01
아 핀 공 간 / 아 핀 변 환
3차원에서도 동일하게 적용됩니다.
(x, y, z) -> (x, y, z, 1)
18. 𝑥, 𝑦 → 𝑥 ∗ 𝑤, 𝑦 ∗ 𝑤, 𝑧 (𝑤 ≠ 0)
잠깐멀리돌아갑시다
01
동 차 좌 표 계
𝑥, 𝑦 → 𝑥 ∗ 𝑤, 𝑦 ∗ 𝑤, 𝑧 (𝑤 ≠ 0)
𝑥, 𝑦, 𝑤 → (
𝑥
𝑤
,
𝑦
𝑤
)
직교좌표계에서 동차좌표계로 변환
동차좌표계에서 직교좌표계로 변환
간단한 형태의 동차좌표계 변환(w = 1)
𝑥, 𝑦 → 𝑥 ∗ 1, 𝑦 ∗ 1, 1
== (𝑥, 𝑦, 1)
이런 식으로 직교좌표계의 점을 동차좌표계의 점으로 바꿀 수 있다
아핀 변환에서는 W = 1인 동차좌표계만을 사용한다.
19. 잠깐멀리돌아갑시다
01
아 핀 공 간 / 아 핀 변 환
무한원점
W값이 0에 가까워질 수록 직교좌
표계로 변환했을 때 점점 무한히
원점에서 멀어지게 된다.
이러한 동차 좌표계의 무한원점을
직교좌표계의 벡터에 대응할 수
있다.
20. 잠깐멀리돌아갑시다
01
아 핀 공 간 / 아 핀 변 환
1 0 0
0 1 0
𝑎 𝑏 1
=2 5 0 2 5 0
크기와 방향만을 가진 벡터의 특징을 만족한다
21. 2 5 1 − 2 5 0
= 0 0 1
잠깐멀리돌아갑시다
01
아 핀 공 간 / 아 핀 변 환
1. 𝑃 ± 𝑉 = 𝑃
2. 𝑉 ± 𝑉 = 𝑉
3. 𝑃 − 𝑃 = 𝑉2 5 1 − 2 5 0
= 0 0 1
점 – 벡터 = 점
2 5 0 + 2 5 0
= 4 10 0
벡터 + 벡터 = 벡터
이제 아핀 공간에서 점과 벡터
를 구분할 수 있다.
W = 1이면 점, w= 0이면 벡터
23. 다시좌표변환으로
01
아 핀 공 간 / 아 핀 변 환
점의 좌표변환
좌표계 B에서 좌표계 A의 오브젝트를 변환하여
사용하고 싶을 때, B 좌표계 기준에서 A 좌표계
의 축 벡터의 방향(u,v)을 알고있으면 u,v에 x,y만
큼 스칼라곱을 해주어 변환할 수 있다.
즉 월드 변환을 위해선 월드 좌표 기준에서의
로컬 공간의 축 벡터와, 원점을 알고 있어야 한
다.
24. 다시좌표변환으로
01
아 핀 공 간 / 아 핀 변 환
3차원도 똑같습니다.
만약 동차좌표계를 사용한다면..
좌표 변환 식을 행렬로
만들 수 있습니다.
25. 다시좌표변환으로
01
아 핀 공 간 / 아 핀 변 환
참고 : 아핀 변환(비례,이동,회전)과 좌표 변환은 수학적 동치이다.
(둘이 바꿔 쓸 수 있다)
결론 : 로컬 좌표 -> 월드 좌표 변환을 위해서는, 월드 좌표 기준으로
서술된 로컬 좌표의 축 벡터와, 크기, 원점 좌표를 알고 있어야 한다.
26. 01
로컬좌표계->월드좌표계
좌표 변환은 이런 식으로 해도 되지만..
그냥 SRT 형태로 정의해도 된다.
장점
u, v, w와 Q(월드 좌표계 기준
로컬 좌표계의 원점) 을 직접 구해서
좌표변환을 하는 대신, 원하는대로
편하게 스케일, 회전, 이동을 사용하
여 세계 좌표계에 안착시킬 수 있다.
28. 카메라변환
01
카메라변환
이전 로컬 좌표계->월드 좌표계 변환을 할 때, 월드 좌표 기준에서의
로컬 좌표의 축 벡터 / 원점 위치를 가지고 있으면 변환 행렬을 만들
수 있었다.
이 방법을 사용하여, 월드 좌표계 기준에서의 카메라의 위치/ 카메라
의 축 벡터(xyz) 를 가지고 있으면,
카메라 좌표계->월드 좌표계 변환을 수행하는 행렬을 만들 수 있다.
31. 01
카메라변환
뷰 행렬(VM) = 카메라 회전 행렬 * 카메라 이동 행렬
== (월드 회전 행렬 * 월드 이동 행렬) 의 역행렬
참고 : 회전행렬의 역행렬은
전치행렬과 같으며, 이동행렬의
역행렬은 요소에 –를 취해준 행렬
과 같다.
32. 01
아 핀 공 간 / 아 핀 변 환
필요한 요소 : 카메라를 배치할 원점, 월드 좌표계 기준에서 본 카메라의 축 3개.
w(look) = T – Q
y(right) = w 외적 j
v(up) = u 외적 w
두 벡터를 외적하면, 두 벡터에
동시에 수직인 벡터를 얻을 수
있다.
두 벡터를 외적하여 수직인 벡터
를 구할 때, 두 벡터는 직교하지
않아도 상관없다.
33. 카메라좌표계->원근투영좌표계
01
투영변환
Near plane(근평면) : 카메라로
볼 수 있는 가장 가까운 거리
Far plane(원평면) : 카메라로 볼
수 있는 가장 먼 거리
Aspect Ratio : 화면의 종횡비
Fovy(field of view) : 시야각
이제 시야 절두체(view frustum) 안에 있는 오브젝트들을 투영 창에 투영
(Projection)하여, 게임에 출력할 수 있는 평면 창 형태로 만들어야 한다.
34. 01
왜 절두체 형태로 생겼냐면, 원근감 구현을 위해서이다.
평행선들이 하나의 소실점으로 수렴되는 형태로 만들어야
깊이가 증가할수록(멀어질수록) 더 작아지는 현상을 만들
수 있다.
원근투영 변환은 하나의 3차원 정점 v를 v에 그어진 투영
선이 투영 창과 만나는 점 v'로 변환하는 변환이다.
깊이
37. 01
닮음꼴 삼각형의 원리를 이용하여, 정점 x,y를 투영 창에 투영한
x’, y’를 구할 수 있다.
𝑦′ =
𝑦
𝑧 ∗ 𝑡𝑎𝑛(
𝑎
2
)
𝑥′ =
𝑥
𝑧 ∗ 𝑡𝑎𝑛(
𝑎
2
)
38. 01
현재 모든 절두체 안의 정점들은, 이 범위 안에 있다.
이러한 작업을 수행한 뒤의 x’, y’ 좌표를 NDC(정규
화된 장치 좌표, Normalized device coordinates)라
고 한다.
투영 창의 크기가 종횡비(r)에 의존하므로, 하드웨어에 종횡비 값을
알려주어야 한다. 이러한 의존을 없애려면, 현재 –r~ r 범위내에 있
는 x’를 r로 나누어주면 된다.
39. 01
이제 투영 행렬을 만들어 봅시다
𝑥, 𝑦, 𝑧 ∗
1
𝑟𝑧 tan
𝑎
2
0 0
0
1
𝑟𝑧 tan
𝑎
2
0
0 0 1
=
𝑥
𝑟𝑧 tan
𝑎
2
,
𝑦
𝑟𝑧 tan
𝑎
2
, z
문제점 1. 투영행렬에 정점의 z값이 들어가 있으므로, 정점마다 각
각 다른 투영행렬을 만들어 주어야 한다. 이는 수만 개의 정점마다
다른 투영행렬을 만들어 주어야 하므로, 효율이 떨어진다는 것을 의
미한다.
문제점 2. z로 나누는 연산이 비선형이다. 즉 행렬로 만들 수 없다.
해결방법 : 동차좌표계로 만든 다음, w를 z로 만들어버리자.
41. 01
이제 절두체 안의 모든 정점들을 투영 창에 투영하는 행렬을 만드는
작업이 끝났습니다.
그런데, 누가 앞이고 누가 뒤지?
42. 01
n = near plane 값
f = far plane 값
Direct3D는 깊이(z값)이 0~1 사이로 정규화 되어있
기를 요구한다. 이를 위해 [n, f] (그려지는 가장 가까
운 영역/ 가장 먼 영역)을 [0, 1]로 사상하는 작업이
필요하다. D3D는 실제 깊이값이 얼마인지는 관심이
없으며, [0, 1] 사이의 상대적인 깊이 비례만이 필요
하다.
43. 01
조건 1을 B에 대하여 풀면 𝐵 = −𝐴𝑛 이 나오므로
이를 조건 2에 대입
𝐴 −
𝐴𝑛
𝑓
= 1
A의 분자 분모에 f를 곱하여 계산
𝐴𝑓
𝑓
−
𝐴𝑛
𝑓
= 1
𝐴𝑓 − 𝐴𝑛 = 𝑓
A로 묶으면
𝐴 =
𝑓
𝑓 − 𝑛
B = -An 이므로 𝐵 = −(
𝑓𝑛
𝑓−𝑛
)
즉
𝑔 𝑧 =
𝑓
𝑓 − 𝑛
−
𝑛𝑓
𝑓 − 𝑛 ∗ 𝑧
44. 01
최종적으로 만들어진 원근투영 행렬
이 투영 행렬을 곱한 뒤의 정점을 가리켜 동차 절단 공간
(homogeneous clip space)에 있다, 혹은 투영 공간에 있다라고
표현하며, 투영 행렬을 곱한 뒤 원근 나누기(w로 나누기)까지
수행한 결과를 가리켜 NDC 공간에 있다고 표현한다.
45. THANK
YOU
출처 : DirectX 11을 이용한 3D 게임 프로그래밍 입문 – 프랭크 D 루나
수학으로 시작하는 3D 게임 개발 – 양영욱
https://momenty.tistory.com/219 참고 블로그