3D 그래픽을 얘기하려면 대학 수업 수준의 방대한 내용을 말해야 한다. 많은걸 생략하고 Godot과 같은 게임 제작 툴을 사용하기 위한 내용에 포커싱을 맞춰 정리해 보려 한다.
3D Model
3D 그래픽은 기본적으로 vertex라고 불리는 3D공간상의 점들의 집합에 이 점들을 이은 선들로 면을 만들어 물체를 표현한다.

이와 같은 방법으로 일반적인 3D 오브젝트는 다음과 같이 삼각형으로 구성된다. 삼각형을 기본단위로 쓰는 이유는, 3개의 점일 때 항상 평면을 이루는 면의 최소 단위이고, 평면일 때, 빛의 반사를 수학적으로 계산하는게 단순해진다. 사각형도 쓰이긴 하지만, 3개 이상의 점을 이용하게 되는 폴리곤들은 면에 휘어짐이 가능해지고 이는 수학적 계산을 어렵게 만든다. 이러한 오브젝트는 마치 그물과 같아서 Mesh Object라고 부른다.

많은 삼각형을 쓸수록, 실제 모습과 비슷하게 보이겠지만, 계산량도 비례해서 늘어난다. 작은 수의 삼각형을 사용하되, 겉에 이미지를 씌워서 그럴듯하게 보이도록 하는데, 여기에 사용되는 이미지가 텍스쳐이다.

3D 물체에 2D 이미지인 Texture를 포장지처럼 감싸주게 되는데, 메쉬 오브젝트는 속이 비어있는 오리가미(종이접기)와 같기 때문에 전개도를 2D에 펼칠 수 있고, 여기에 텍스쳐 이미지를 씌워준다. 이 2D 전개도의 좌표계로 (u, v)를 사용한다. 3D 물체를 전개하는 방법은 너무나 다양하기 때문에, 이 (u, v) 좌표계를 3D vertex(x, y, z) 좌표계에 매핑하는 정보가 필요하다. 이 매핑 정보를 포함해 UV map이라고 부른다.
광원과 표면에서의 빛의 반사를 처리하는 보다 복잡한 내용이 있지만, 나중에 다룰 것이고 가장 기본적인 3D 모델은 이와같이 vertecies들로 이루어진 매쉬 오브젝트와 텍스쳐로 구성된다.
Camera
앞에서 생성한 3D 모델을 스크린에 보여주기 위해선 현실에서와 같이 카메라가 필요하다. 3D 모델들을 카메라를 통해 스크린에 보여주는 일련의 계산 과정을 3D 렌더링이라고 한다.
3D 공간의 오브젝트들을 카메라에 담기 위해서는 2D로 투영하는 Projection이 필요하다. Projection에는 다음과 같이 Orthogonal Projection 과 Perspective Projection 두가지 방법이 있다.
Orthogonal은 단순하지만, 원근 표현이 되지 않는다.
현실과 같은 방식은 Perspective지만, 그래픽적인 표현을 위해 Orthognal이 사용되기도 한다. 예를 들면 CAD도면의 경우, 정확한 수치의 표시가 중요하고 원근은 필요가 없다. 두가지 Projection에 동일하게 Front Plane과 Back Plane이 존재하는데, 컴퓨터 그래픽에서는 무한한 공간을 스크린에 투영하지 않고 한정된 볼륨의 공간을 투영하게 된다. 여기서 Front-Back plane사이에 있는 오브젝트들만 스크린에 투영된다.
Perspective Projection을 조금 더 살펴보면 다음과 같다.

FOV는 Field Of View의 약자로 얼마나 넓은 영역을 투영시킬지 정하는 각도이다. fovy로 표시된건, y축 각도를 의미한다. 카메라로 치자면, 렌즈 초점거리와 유사한 개념이다. FOV의 수평, 수직에 다른 값을 사용하는데 따라, 화면의 aspect ratio를 결정하는 값이기도 하다.
Godot에서는 Camera에 ‘Keep Aspect’속성이 있고, 수평 또는 수직을 고정하도록 되어있다. 고정된 방향으로는 리사이즈가 되도 화면에 대한 물체의 비율이 유지되는 속성이다. 이 말은, 해당 방향으로 FOV가 고정이라는 얘기이기도 하다. 다르게 얘기하면, Keep Aspect에서 고정되지 않은 방향은 FOV가 가변적이란 얘기다. 다음 그림을 비교해보자.


위 두 그림은 Keep Height 상태에서 스크린 사이즈를 1024×768에서 1600×1600로 변경해본 것이다. 높이가 달라졌지만, 높이 방향으로는 비율이 유지되어 변경된게 없어보인다. 하지만, 넓이 방향으로는 고정된 높이를 기준으로 비율이 달라졌으므로 FOV가 좁아진걸 확인할 수 있다.
Godot에서 FOV는 상당히 헷갈리게 되어 있어서 좀 생각해볼 필요가 있다. Godot 카메라 속성을 보면, FOV가 수평, 수직이 분리되어 있지 않고 하나의 값을 갖는다.

도움말에는 “Since keep_aspect locks one axis, fov sets the other axis’ field of view angle.”라고 써있다. 내가 해석을 못해서 그런건지 모르겠지만, keep_aspect로 고정되지 않은 쪽의 FOV를 설정한다고 말하는 것 같다. 하지만 이 얘기가 맞다면, 해상도를 변경했을 경우, FOV값이 같이 바뀌어야 함에도 그렇게 동작하지 않는다. 또한, 직접 FOV값을 변경하면 높이와 폭 둘 다 변경된다.
내 생각엔 Keep Aspect에서 설정한 방향에 대한 FOV 값이라는 결론이다. 해상도를 변경해 화면이 리사이즈되도 비율이 유지되므로 FOV도 변경되지 않는다.(확인 결과와 일치) FOV를 직접 변경하는 경우, 해상도 비율에 맞춰서 가변적인 다른 방향 FOV도 같이 변하는 것으로 생각된다.
1 thought on “Godot 3D rendering #1 : 3D Model and Camera”