GL, 3D 공간에서 직교 프로젝션 행렬 - Whitmem
GL, 3D 공간에서 직교 프로젝션 행렬
Graphic Development
2025-01-18 20:41 게시 e74b195fb222e3c9c07d

0
0
88
이 페이지는 외부 공간에 무단 복제할 수 없으며 오직 있는 그대로 게시되며 부정확한 내용을 포함할 수 있습니다. 법률이 허용하는 한 가이드 라인에 맞춰 게시 내용을 인용하거나 출처로 표기할 수 있습니다.
This page is not to be distributed to external services; it is provided as is and may contain inaccuracies.
직교 프로젝션 행렬의 원리
이 게시물에서는 직교 투영 행렬에 대해서 자세히 알아본다.
직교 투영이란 무엇이고, 어떤 과정을 통해 그래픽스에서 처리되는지 자세히 알아본다. 그리고 투영 행렬이 어떻게 나오는 것인지 유도를 해본다.
투영 행렬이란?
투영 행렬은 3D 공간에 존재하는 좌표 정점들을 2D 평면 상에 투영하기 위해 곱하는 행렬을 의미한다. 행렬이라고 하면 계산이 복잡해 보이지만, 사실은 그렇지 않다. 3차원 정점 정보인 (x, y, z) 을 2D 좌표 평면에 투영하는 과정을 나타낸다. 하지만 컴퓨터 그래픽스에서는 투영 행렬을 처리한 다음에 뷰포트 행렬을 처리하여 실제 화면 영역에 맞도록 배치하는 과정이 필요하다.
[ 2right - left 0 0 - right + leftright - left 0 2top - bottom 0 - top + bottomtop - bottom 0 0 -2far - near - far + nearfar - near 0 0 0 1 ]
투영이 가지는 의미
위 행렬이 어떤 의미를 가지는지 알아보자.
기본적으로 투영 행렬 (+x,+y,-z) 공간 안에 있는 모든 버텍스 정점을 (-1~+1, -1~+1, 0~1) 의 범위로 이동하는 행렬을 의미한다. 즉 투영 행렬은 이 세계에 존재하는 모든 객체에 대해서 바로 화면에 투영하는 것은 아니다. 이 세계에 존재하는 정점은 월드 공간에 존재하는 것이고, 이 월드 공간에 존재하는 객체들을 카메라 시점이 중앙에서 -z 축을 쳐다보는 카메라 공간으로 옮겨야 한다. 투영 행렬은 카메라가 원점에 존재하고, 카메라는 -z 방향을 쳐다보는 것을 전제하에 사용할 수 있는 행렬이다. 즉 원점에서 -z 축을 쳐다볼 때 존재하는 객체들을 비로소 화면에 투영하기 위한 것이라고 볼 수 있다. 투영 행렬을 사용하기 위해서 3D 공간에 존재하는 어떤 객체들을 카메라 뷰로 옮긴 상황에서 사용해야 한다. 단순 테스트를 위해서 구현을 하고자 하는 경우, 임의로 배치하는 객체들은 원점을 기준으로 -z을 쳐다보는 공간안에 객체를 배치해야 한다.
유도 과정
결과적으로 위 직교 행렬은 어떤 객체의 정점 (x,y,z) 이 존재할 때, 화면 위에 노말라이즈 된 범위인 x,y를 -1~1 범위 안으로 옮기고, z는 0~1 범위로 옮기는 역할을 한다.
카메라가 쳐다보는 공간에서, 어떤 버텍스가 존재한다고 가정한다.
해당 위치에 있는 (1, 0.5, -1)를 원하는 화면 공간에 투영하여 최종적으로 정규화된 (-1~1,-1~1,0~1) 좌표로 변환하는 것이 주요 목표이다. 그러기 위해서 투영 공간으로 옮길 투영 패널의 너비, 높이, 깊이 정보가 필요하다. 그것이 바로 near, far, left, right, top, bottom 정보이다.
즉 캐릭터가 쳐다봐 화면에 맺힐 수 있는 객체가 존재하는 공간인 분홍 공간을 정의하는 것인데, 이 분홍 공간의 좌, 우, 위, 아래, 앞, 뒤를 정의하는 것이다. 이 객체 공간에 있는 객체 좌표가 결국 -1 ~ 1 공간으로 표준화되는 것이고, 벗어나는 객체들은 -1 ~ 1 을 벗어나게끔 변환된다.
헷갈리니, 3차원이 아닌 2차원의 평면 공간에서 생각해보자.
어떤 정점은 카메라가 쳐다보는 공간에 존재하는 범위의 제한이 없는 자유로운 k점이고, 이 점을 분홍색 공간으로 이동해야 한다. 분홍색 공간은 분홍 공간의 x 최소 값은 -10, x 최댓 값은 10, y 최댓 값은 10, y 최솟 값은 -10이다. k점은 결국 -10~10 범위 안에 존재하는 정점이다. 이 정점을 -10 ~ 10을 기준으로 하여금 다시 -1 ~ 1 공간으로 바꿀 수 있다. 위 상황에서는 단순히 정점을 110배 하면 된다. 왜냐하면 분홍색 영역이 중앙 지점으로부터 좌 우 상 하 대칭이기 때문이다.
하지만 이러한 경우에는 말이 조금 달라진다.
좌우가 크기가 다른 경우, 어떻게 해야할까? 먼저 이 평면을 크기는 유지한 채 중앙으로 옮겨서 단순히 좌우 대칭이 되게끔 만든다. 위에서는 좌는 -10, 우는 +2 이기 때문에 너비가 12가 된다. 너비를 절반으로 나눈 6 값이 좌측 우측 대칭이 되게끔 이동한다.
대칭되게끔 만든 뒤에, 정점의 x에 대해 16한다. 그러면 정점은 해당 너비에 맞게끔 스케일이 조정되었다. 하지만 스케일만 조정되었을 뿐 위치가 맞지 않다. 왜냐하면 이 투영 공간은 원래 중앙에 존재하는 것이 아니라 왼쪽에 존재하는데 중앙으로 대칭을 맞추기 위해서 중앙으로 이동했기 때문이다. 따라서 스케일된 정점을 스케일된 차이 너비 만큼 다시 왼쪽으로 평행 이동 해 주면 된다.
위 사진에서의 원본 차이 크기만큼 다시 평행이동 해주면 된다. 초록 공간의 right와 빨간 공간의 right의 차이가 원본 차이라고 보면 된다. 일반 공간에서 원본 차이는 4이다. 이 4 만큼을 원본 지점에서 왼쪽으로 이동하면 된다. 그런데 4는 스케일된 크기가 아니라 원본 공간에서의 크기이기 때문에, 스케일된 크기로 변환하기 위해서 크기 조차 16해서 이동해야 한다. 그 과정을 수식으로 나타내면 다음과 같다.
x × 2right - left + ( right - left2 - right ) × 2right - left
위 식의 의미
위 사진 예시에서, right - left는 우측부분과 좌측 부분의 길이 차이를 구하는 것이다.
위 사진에서 좌는 -10, 우는 +2로 너비는 12이다. 너비 12를 구하는 과정이라고 보면 된다. 너비 12인 화면 투영 공간이 중앙에 있다고 가정한다.
이렇게 중앙에 배치했을 때, 좌측 우측은 중점을 기준으로 서로 대칭이 되기 때문에, 투영하고자 하는 버텍스의 정점 x를 한쪽 면의 길이 6만큼 나누어주면, 해당 면의 0~1 까지 범위로 나타낼 수 있다. 마찬가지로 음수 영역에 존재하는 x 역시 한쪽 면의 길이인 6만큼 나누어주면 -1~0 까지 범위로 나타낼 수 있다. 즉 중점에 존재하는 평면을 최대로 하는 -1 ~ 1 의 값을 가지는 새로운 공간의 x를 구할 수 있게 된다. 다시 돌아와서, 이 표면을 우리가 임의로 중앙으로 옮긴 위치이다. 옮긴 만큼 다시 원래 위치대로 보내줘야 한다.
원본 투영 공간은 right가 +2였다. 옮기고 난 뒤 +6가 되었는데, 즉 돌아서 생각해보면 원본 투영 공간에 대해 +4만큼 이동이 덜 된 것이다. 즉 공간에 존재하는 모든 정점을 오른쪽으로 +4인 ( right - left2 - right ) 만큼 더해야 한다. 그런데 여기서 정점은 아까 스케일된 새로운 공간으로 조절한 크기이기 때문에, 새로운 공간에 맞는 너비만큼으로 변환해서 빼야 한다. 새로운 공간에 맞게끔 곱하기 위해 2right - left 을 너비에 곱한 값을 더하면 된다.
그러면 결과적으로,
x × 2right - left + (-right + leftright - left) 가 된다. 이 작업을 x 축이 아닌, y축에도 반복하고, z 축에도 반복을 해 준다. 단, z 축은 Z 축을 한번 뒤집어주기 위해 -를 곱해서 연산해야 한다. 결과적으로 다음과 같은 행렬 식을 만들 수 있게 된다.
[ 2right - left 0 0 - right + leftright - left 0 2top - bottom 0 - top + bottomtop - bottom 0 0 -2far - near - far + nearfar - near 0 0 0 1 ] [ x y z 1 ]
댓글 0개
댓글은 일회용 패스워드가 발급되며 사이트 이용 약관에 동의로 간주됩니다.
확인
Whitmemit 개인 일지 블로그는 개인이 운영하는 정보 공유 공간으로 사용자의 민감한 개인 정보를 직접 요구하거나 요청하지 않습니다. 기본적인 사이트 방문시 처리되는 처리 정보에 대해서는 '사이트 처리 방침'을 참고하십시오. 추가적인 기능의 제공을 위하여 쿠키 정보를 사용하고 있습니다. Whitmemit 에서 처리하는 정보는 식별 용도로 사용되며 기타 글꼴 및 폰트 라이브러리에서 쿠키 정보를 사용할 수 있습니다.
이 자료는 모두 필수 자료로 간주되며, 사이트 이용을 하거나, 탐색하는 경우 동의로 간주합니다.