티스토리 뷰

도입

오늘은 OpenGL에서 Perspective Projection을 다루는 Matrix에 대해서 알아보겠습니다.

OpenGL을 기준으로 쓰였고 DirectX와 세세한 부분이 다르니 주의하시기 바랍니다.

 

다시 한 번 복습하자면 컴퓨터 그래픽스가 하는 일은 결국 가상의 3차원 공간을 2차원 모니터에 색으로 표현하는 일입니다.

물체는 대체로 3차원 공간의 삼각형들의 조합으로 표현이 되고 삼각형들은 3개 정점의 조합으로 표현이 됩니다.

정점은 3차원 위치, 색 등의 정보를 가지고 있습니다.

이 정점을 2차원 모니터에 표현하려면 여러 공간 변환을 거쳐야 합니다.

 

아래는 3차원 공간에서 2차원 모니터로 옮기는 일반적인 변환 과정입니다.

 

 

전체 공간 변환 과정

출처: https://learnopengl.com/Getting-started/Coordinate-Systems

 

전체적으로 훑어 보면 정점은 처음에 모델 공간(Model Space 혹은 Local Space)에 정의되어 있습니다.

그 다음은 Model Matrix를 곱해서 월드 공간(World Space)으로 넘어갑니다.

그 다음은 View Matrix를 곱해서 카메라 공간(Camera Space) 혹은 뷰 공간(View Space)으로 넘어갑니다.

그 다음은 Projection Matrix를 곱해서 NDC(Normalized Device Coordinate, 정규화된 공간) 혹은 Clip Space으로 넘어갑니다. 

마지막으로는 Viewport Transform을 통해 Screen Space로 넘어갑니다.

각 공간에 대한 자세한 설명은 위 링크에 있습니다.

 

3차원에서 2차원으로 옮기는 변환 중 가장 핵심이 되는 것이 카메라 공간에서 NDC 공간으로 가는 변환입니다.

이 두 공간 사이의 변환을 하는 행렬을 Projection Martrix라고 합니다.

이 행렬이 바로 오늘 깊게 살펴볼 행렬입니다.

 

그렇다면 왜 3차원에서 2차원으로 옮기는 변환 중 가장 핵심이 Projection Transform일까요?

이 포스트를 모두 보고 나면 아마 이해가 갈 겁니다.

 

변환 개요

projection transform에 대해 자세히 알기 위해 먼저 변환을 하기 전인 카메라 공간과 변환을 한 후인 NDC를 자세히 살펴보겠습니다.

 

Camera Space

먼저 카메라 공간에 대해 알아봅시다.

카메라 공간

출처: http://www.songho.ca/opengl/gl_camera.html

 

카메라 공간은 카메라의 위치가 좌표계의 원점이 되고 카메라가 바라 보는 방향이 -z 축이 되고 카메라의 up 벡터가 +y 축이 되는 공간입니다.

여기서 중요한 것은 카메라가 바라보는 방향이 -z 축이라는 점입니다.

model 좌표계에서 정의된 정점들에 model matrix, view matrix를 곱해서 camera space에서 정의되도록 했다고 해봅시다.

카메라가 바라보는 방향이 -z 축이라는 의미는 변환된 정점들 중 z 값이 음수인 정점들이 화면에 그려진다는 뜻입니다.

그렇다면 z 값이 음수인 모든 정점들이 화면에 그려질까요?

그렇진 않습니다. 어떤 파라미터를 통해 한정된 시야각을 정의할 것이고 이 한정된 시야각 안에 들어오는 정점만 모니터에 그려질 것입니다.

여기서 또 하나 중요한 것은 Camera Space의 정점들 자체는 한정되어 있지 않다는 점입니다.

즉 시야각에 들어오지 않는 정점이라 하더라도 모두 정의되어 있기는 하다는 뜻이지요.

 

NDC(Normalized Device Coordinate)

그 다음은 NDC에 대해 알아봅시다.

Camera 공간과 NDC

출처: http://www.songho.ca/opengl/gl_projectionmatrix.html

그림 오른쪽에 있는 것이 NDC입니다.

NDC는 그림 대로 (-1,-1,-1)에서 (1,1,1)의 큐브 형태로 만들어진 공간입니다.

 

왼쪽에 보이는 좌표계는 Camera 공간이고 회색 Frustum(절두체)로 표시된 부분이 바로 위에서 설명한 "파라미터로 한정된 시야각"입니다. 이 절두체를 View Frustum이라고 부릅니다.

 

카메라 공간에서 Frustum을 이용해 공간을 자르는 이유는 현실의 시야각이 Frustum이기 때문입니다.

정면을 바라본다고 했을 때 단순히 바로 왼쪽 1m에 있는 물체는 보이지 않지만 앞 10m, 왼쪽 1m에 있는 물체는 비록 작게 보이기는 하지만 잘 보입니다. 즉 멀리 있을 수록 작게 보여 옆에 있는 것들이 잘 보이는 것이지요.

 

여기서 한 가지 주의할 점은 Camera 공간에서 NDC로 넘어갈 때 z축이 뒤집어 진다는 점입니다.

Camera Space에서는 Camera가 바라보는 방향이 -z 축이기 때문에 카메라와 가까운 점보다 먼 점의 z 값이 더 작을 것입니다. 하지만 NDC로 넘어가면 near plane에 가까운 점의 z 값이 더 작습니다.

 

*참고로 frustum을 이용한 projection 외에 다른 projection 방식도 있습니다. 바로 orthographic projection입니다.

orthographic projection은 아래처럼 직육면체를 정육면체로 바꾸는 projection입니다.

perspective projection에 비해 간단하기는 하지만 현실을 잘 반영하지 못합니다. 이 포스트에서는 깊게 다루지 않겠습니다.

orthographic projection

출처: https://stackoverflow.com/questions/46745702/seeing-only-half-of-the-object-when-rotating-opengl

 

다시 돌아와서, Camera 공간과 NDC 공간 사이의 변환을 하는 Projection Matrix에는 Camera 공간의 일정 부분을 추려내고 추려낸 부분을 적당히 옮기고 늘릴 부분은 늘리고 줄일 부분을 줄여 정육면체의 형태로 바꾼다라는 의미가 담겨있습니다.

즉, Projection Matrix에는 어떤 부분을 추려낼 것인가추려낸 부분을 어떻게 변형시킬 것인가에 대한 정보가 모두 담겨있는 셈이지요.

이 점을 염두에 두고 있으면 이어지는 글을 읽는데 수월할 것입니다.

 

이제 본격적으로 NDC 자체에 대해 살펴봅시다.

먼저 특이한 점은 NDC에 x, y 뿐만 아니라 z 값이 있다는 것입니다.

3차원에서 2차원으로 가는 핵심 변환이 Projection Transform이고 변환 후의 공간이 NDC 공간인데 정작 NDC 공간이 3차원이라는 점을 의아해 하실 수 있습니다. 

NDC 공간에 z 값이 있는 이유는 크게 2가지 입니다.

첫 번째 이유는 z 값이 나중에 depth testing을 할 때 쓰이기 때문입니다.

depth testing이란 간단하게 말하면 더 앞에 있는 점을 그리기 위해 depth 값을 비교하는 것입니다.

두 번째 이유는 z 값을 따로 저장해놓지 않으면 projection의 역연산인 unprojeciton을 하지 못하기 때문입니다.

z 값을 저장해놓으면 projection transform의 역연산을 통해 온전한 View Space에서의 정점을 얻을 수 있습니다.

 

다음으로 봐야할 것은 NDC의 x, y, z 값이 모두 -1에서 1사이라는 점입니다.

여기서는 값을 정규화(Normalize)했다고 표현합니다.

 

값을 정규화하는 이유는 해상도 차이에 빠르게 대응하기 위함입니다.

게임을 보면 해상도를 게임 도중에 바꿀 수 있죠.

정규화된 정점들을 이용하면 빠르게 바뀐 해상도로 픽셀을 그려낼 수 있을겁니다.

*정규화된 정점들을 어떻게 바뀐 Screen Space로 대응시키는지 자세히는 모릅니다. 

 

요약

아무튼 위 글을 요약하면 다음과 같습니다.

1. 3D에서 2D로 가는 변환의 핵심은 Projection Transform이다.

2. Camera Space에 -z축에 있는 점들이 그려진다.

3. Camera Space에 있는 점들은 범위의 한계가 없다.

4. Projection Transform은 Camera Space에서 View Frustum 형태로 자르고 정육면체로 변형 시키는 것이다.

5. Camera Space에서 NDC로 넘어가면 z 값이 반전된다.

6. NDC의 범위는 x, y, z 각각 -1~1이다.

7. NDC에서 z 값은 depth testing 및 unprojeciton에 쓰인다.

 

여기까지 perspective projection에 대해 간략하게 알아봤습니다.

아직 projection matrix의 형태에 대해서는 시작도 하지 못했고 위 내용에서도 자세히 다루지 못하고 넘어간 부분이 있습니다.

자세한 내용과 실질적인 matrix의 형태는 다음 포스팅에서 이어서 올리겠습니다.

 

 

참고 자료:
opengl의 projection을 설명하는 매우 좋은 자료입니다.

http://www.songho.ca/opengl/gl_projectionmatrix.html

 

OpenGL Projection Matrix

OpenGL Projection Matrix Related Topics: OpenGL Transformation, OpenGL Matrix Updates: The MathML version is available here. Overview A computer monitor is a 2D surface. A 3D scene rendered by OpenGL must be projected onto the computer screen as a 2D image

www.songho.ca

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함