Local Space

OpenGL에서 우리가 물체를 그리기 위해 정점의 위치를 정할 때 기준을 정하여 기준에 맞춘 위치를 명시한다.
예를 들면 육면체는 육면체의 중심, 원기둥은 아래 뚜껑의 중앙, 원뿔은 바닥의 중앙 등의 기준을 갖는다.
이런 기준을 Local Space에서의 원점이고 말 그대로 물체를 기준으로 본 좌표계에서의 원점이다.

하지만, 우리가 그릴 물체는 여러 개일 수도 있고, 움직임이 존재할 수 도 있고, 축소/확대될 수도 있다.
그러기 위해 우리는 Local Space에 존재하는 물체를 모든 물체에 기준이 되는 좌표계에 그려주어야 한다.
이를 World Space라고 한다.


World Space

World Space에서의 원점은 우리가 그릴 모든 물체에 기준이 되는 좌표계이다.
즉, 물체의 위치, 기울임, 크기 등을 조절해서 여러 개의 물체들을 World Space에 동시에 존재하도록 할 수 있다.
우리는 OpenGL에서 glm을 이용하여 Local Space에서 World Space로 변환 행렬을 만들고,
해당하는 정점의 위치, 법선 벡터에 적용시키게 된다.

이때, 정점의 위치는 단순한 위치를 표현하지만 법선 벡터는 방향을 갖기 때문에 변환 행렬을 수정해야 한다.

더보기

법선 변환 행렬의 증명과정은 아래와 같다.

 

T : 법선에 수직하고, 해당하는 정점과 임의의 한 점까지의 벡터
N : 법선
T' : 변환된 T
N' : 변환된 N
M : 정점의 변환 행렬
G : 법선의 변환 행렬

T와 N은 수직 하기 때문에 내적 했을 때 0이 나온다.
$N \cdot T = 0,\ N' \cdot T' = 0$

$N'\cdot T' = (GN)\cdot(MT)=0$
$N'\cdot T' = (GN)^{T}\cdot(MT)=0$
$N'\cdot T' = N^{T} G^{T} M T)=0$

위 상황에서 우리는 $N^{T} T = 0$인 것을 알고 있다.
그렇다면 $G^{T} M = I$가 되어 $G = (M^{-1})^{T}를 만족하게 된다.

법선 변환 행렬은 변환 행렬의 역행렬의 전치 행렬이다. => $(M^{-1})^{T}$이다.
이렇게 정점의 정보들을 World Space로 변환하면 사전작업이 완료됐다 볼 수 있다.

여기서 우리가 그려야 할 장면은 어떤 위치에서 어떤 방향으로 존재하며, 어떻게 해야 할지는 다음 과정에서 알 수 있다.


View Space

우리가 보는 장면, 카메라가 보는 장면이라 해서 Camera Space, Eye Space라고 불리기도 한다.
조금 어렵게 보일 수 있지만, 장면을 그리기 위해서 World Space의 앞/뒤, 위/아래, 위치를 변환하는 과정이다.

이 과정에서 카메라의 위치, 카메라가 보는 방향, 그리고 카메라의 정수리 방향이 어딘지 정하고,
회전, 이동 행렬들을 조합한 변환 행렬을 만들어 기존의 World Space 정보에 적용시키는 과정이다.

이렇게 적용되었을 때, 우리가 정한 너비, 크기에 해당하게 물체를 그릴지 판단하는 공간이 Clip Space이다.


Clip Space

우리가 보는 시야는 제한되어있기 때문에, 인간은 기계도 인간과 같이 표현하길 원한다.
표현한다면 기계는 수치적 연산을 통해 뒤까지 볼 수 있는 잠자리의 시야각을 표현할 수 있지만, 인간은 불편하다 느낀다.
그렇기에 인간이 느끼는 것처럼 제한된 시야를 보게 하기 위해 x, y의 좌표를 [-1~1]까지로 제한하여 정규화시킨다.
이러한 작업을 Clip이라 표현하여 그리지 않을 정보를 취급하지 않게 한다.

이렇게 만들어진 Viewing Box는 절두체(Frustum)이라고 불리고 절두체 내부의 물체들은 사용자의 화면에 나타난다.
이런 절두체를 화면에 표시하는 방법은 Orthographic Projection, Perspective Projection으로 2가지 정도 있다.

Orthographic Projection

이 방법은 너비, 높이를 그대로 찍는 방식으로 시야각을 고려하지 않고 주물을 찍어내듯 찍는 방식이다.

Orthographic Projection

 

Perspective Projection

원근감을 표현하기 위해 멀어질수록 작게 보이게 하기 위한 방법이다.

Prospective Projection

 

둘의 가장 큰 차이점은 w값을 조작하는가?이다.
우리가 가져온 물체들은 3차원의 정보들이었지만, 우리는 4차원의 정보를 다뤄야 원근감을 표현할 수 있다.|
이 4차원의 좌표계는 Homogeneous Coordinate라 한다.

 

Homogeneous Coordinate

기본적으로 우리는 3차원의 정보를 가져와 $vec4(Position, 1.0)$로 표현한다.
즉, $(2.0, 3.0, 4.0) -> (2.0, 3.0, 4.0, 1.0)$로 만들어주는데,
도대체 왜? 이게 원근법과 관련이 있나?라는 의문이 계속될 것이다.

계속해서 $(x, y, z) -> (x, y, z, 1.0)$으로 변환의 역변환은 $(x, y, z, 1.0) -> (x/1.0, y/1.0, z/1.0)$이다.
즉, 1.0으로 넣은 이유는 결국 x, y, z에 1.0을 곱한 변환인 것이다.
다시 말해서 $(x, y, z) -> (wx, wy, wz, w)$으로 변환의 역변환은 $(wx, wy, wz, w) -> (x, y, z))$이다.

위에서 Prospective Projection에서만 w값을 조작하는 이유가 여기 있다.
만일 $w = z$라고 한다면? $(x, y, z, z) -> (x/z, y/z, 1)$로 간단하게 확인할 수 있다.
또한, 여기서 Depth Value의 그래프가 $\frac {1}{z}$인 이유를 알 수 있다.

그리고 w값이 0이 된다면 Zero Division Error가 발생할 테니 z의 값은 0보다는 큰 값이 될 것이다.
즉, z의 범위는 [0~1]까지가 될 것이다.


정리

우리가 가져온 정보는 Local Space에 존재하기에 물체의 정보에 따른 변환 행렬을 통해 World Space로 변환하는 과정이 필요하다.
World Space에서는 우리가 그리고 싶은 장면을 표현하기 위해 View Space로의 변환이 필요한데,
이 과정에서 앞/뒤, 위/아래, 원점의 변환이 필요하다.
View Space에서 필요한 정보만 얻기 위해 Clip Space로 변환하고, Projection 하여 우리가 보는 장면이 탄생한다.

여기까지 OpenGL의 좌표계 변환 과정이다.

'OpenGL' 카테고리의 다른 글

Normal Vector의 변환 행렬  (0) 2022.11.14
OpenGL[Lighting]  (0) 2022.10.18
OpenGL[02](First Triangle)  (1) 2022.10.12
OpenGL[01](Shader)  (1) 2022.10.12
OpenGL[00](First Window)  (0) 2022.10.12

+ Recent posts