2D 게임 개발 프로젝트를 마치고 오늘부터는 3D기반의 게임 개발에 필요한 학습을 진행합니다.
오늘 배운 내용은 게임의 눈 역할을 하는 카메라에 대해 학습한 내용을 정리해보겠습니다.
게임 세계에는 수많은 3D 메쉬와 정점들을 배치하지만 그 모든 것들을 다 그리고 플레이어에게 제공하지않습니다. 카메라를 통해 플레이어에게 제공되는 시야 공간(Viewing Volume)을 정의하여 컴퓨터의 자원을 효율적으로 사용합니다.
카메라의 범위와 필터링을 관리하는 개념은 다음과 같습니다.
Near Plane (근거리 평면): 카메라 렌즈로부터 렌더링이 시작되는 최소 거리입니다. 이보다 가까운 물체는 잘려서 보이지 않으며 이 평면이 최종적으로 픽셀이 설정되는 가상의 스크린역할을 합니다.
Far Plane (원거리 평면): 카메라로부터 물체를 렌더링할 수 있는 최대 거리입니다. 이 지점보다 멀리 있는 물체는 화면에 그려지지 않습니다.
Culling (컬링): 카메라가 특정 레이어(Layer)의 물체만 그리거나 무시하도록 설정하는 기능입니다. Far Plane보다 멀리있거나 Near Plane 보다 가까이 있는 오브젝트들을 수학적인 계산에 제외하여 화면에 그리지 않습니다. 이 Culling이 렌더링 부하를 줄이는 핵심 시스템이라고 할 수 있습니다.
3D 공간을 화면에 투사할것인지에 따라 플레이어에게 다른 시야를 제공합니다.
Perspective (원근 투영): 4각 비라미드 형태의 Frustum 구조를 가지며, 현실의 사람의 눈과 가장 유사한 방식입니다.
카메라로부터 멀리 있는 오브젝트일수록 더 작게 계산되며 일반적인 1인칭/3인칭 3D게임, 공간감, 깊이가 중요한 환경에 주로 사용됩니다.
Orthographic (직교 투영): 모든 투영선이 평행한 직육면체의 구조를 가지며, 원근감이 배제됩니다.
오브젝트가 카메라에서 멀거나 가까워져도 원래의 크기를 유지하며, 대표적으로 아이소메트릭 뷰 기반의 RPG나 전략 게임, 미니맵을 렌더링할때 주로 사용됩니다.
Perspective의 각을 조절하면 Orthographic와 유사한 시야를 제공할 수 있습니다.
다만, 유사한 시야라면 Orthographic를 사용할텐데 그러지 않는 이유는 바로 패럴랙스(Parallax)에 있습니다.
직교 투영시에는 배경의 깊이감이 사라지지만, 원근 투영의 시야각을 직교 투영과 유사하게 조절하면 미세하게나마 거리차에 따른 움직임 변화가 남아있어 훨씬 자연스럽고 고급스러운 입체감을 줄 수 있습니다.
즉, 직교 투영의 구도와 동시에 원근 투영의 3D 그래픽 효과를 얻기 위해 사용할 수 있습니다.
FOV는 원근 투영 뷰를 사용할 때, 공간의 스케일과 투영선의 각도를 결정하는 핵심 변수로, 카메라 렌즈가 포착하는 시야의 너비를 각도로 나타낼 수 있습니다.
FOV는 사람이 세상을 바라보는 방식(Horizontal)에 맞춰 가로 시야각을 기준으로 설정되어 왔습니다.
가로 시야각이 결정되면 화면의 해상도에 맞춰 비율에 따라 수직 시야각을 계산하여 적용합니다.
vertical_fov = horizontal_fov * screen.height / screen.width
세로 시야각을 계산하여 최종적으로 가로/세로의 비율을 계산해야합니다. 이유는 화면 왜곡(Stretching) 을 방지하기 위해서입니다.
화면 왜곡은 카메라의 시야와 모니터의 비율이 맞지않을 경우 빈 공간을 채우기 위해 부족한 방향으로 오브젝터를 억지로 늘려 발생하는 문제입니다.
결과적으로 가로 시야각만 맞추는 것이 아닌 세로 시야각 즉, 수직 기준점을 찾아 화면 왜곡현상을 방지해야하기 때문에 세로 시야각의 계산이 필요합니다.
카메라가 비추는 영역의 실제 크기는 Top(수직 절반 높이)값을 시작점으로 다음과 같이 계산이 진행됩니다.
1. Top
Top = tan(vertical_fov/2) x N(카메라 원점 ~ Near Plane까지의 거리)
2. Bottom
Bottom = -Top
3. Aspect Radio
Screenn Width / Screen Height
3. Right
Right = Top x Aspect Radio
4. Left
Left = -Right
* NearPlane Width, Height
Width = Right - Left
Height = Top - Bottom
오늘은 카메라의 기본 가시 범위부터 해상도 비율에 따른 FOV 계산에 대하여 학습하였습니다.
공부하면서 계산파트에서 삼각함수의 내용이 본격적으로 사용되는 것을 보고 아직 수학파트가 부족하기 때문에 본격적으로 보강할 필요성을 느끼게 되었습니다.