ThorVG 활용 사례 조사 (Godot Engine)
ThorVG 공식 쇼케이스에 없는 새로운 활용 프로젝트를 찾고자 했으나 적합한 대상을 찾지 못해서 오픈소스 프로젝트인 Godot Engine을 탐색해 보았다.
1. Godot Engine이란?
고도 엔진(Godot Engine)은 누구나 사용할 수 있는 완전 무료 오픈 소스 크로스 플랫폼 게임 엔진이다. 가장 큰 특징은 가볍고 직관적인 2D 및 3D 개발 환경을 제공한다는 점이다.
용량이 작아서 저사양 기기에서도 잘 돌아간다.
2. Godot이 ThorVG를 선택한 이유
나무위키를 찾아보니 고해상도 작업 환경을 위해 UI 요소들을 벡터 방식으로 만들었는데 이때 확대해도 깨지지 않는 벡터 그래픽을 렌더링하기 위해 ThorVG 엔진을 탑재한 것을 알 수 있었다.
추가로 ThorVG 세미나 영상(13분 9초)을 참고하면 Godot에서 비주얼 아트워크나 모션 기반 GUI를 출력할 때 ThorVG가 활용되고 있다고 한다.
3. 코드로 확인한 ThorVG 통합 방식
ThorVG가 실제 엔진에 어떻게 통합되어 있는지 확인하기 위해서 Godot을 설치하고 Godot 실행 앱의 패키지 내부(Contents/) 구조와 바이너리 번들 구성을 살펴보았다.
설치된 앱 패키지 내부에 별도의 동적 라이브러리(.dylib)가 없었는데 Godot이 ThorVG를 빌드 시점에 메인 바이너리에 정적 링크(Static Linking)하여 단일 실행 파일로 포함시키는 방식이기 때문이었다.
그래서 정확한 코드 레벨의 호출 흐름과 통합 구조 분석은 Godot GitHub 공식 저장소 기반으로 진행했다.
엔진 내부 코드를 보면 ThorVG는 크게 2가지 역할을 하고 있는 것으로 분석했다.
① SVG 파일을 일반 이미지로 바꿔주는 역할 (Rasterizer)
- 실시간 계산 부담 및 프레임 드랍 방지:
.svg파일은 매 프레임마다 실시간으로 계산해서 그리는데 이 경우에 게임 실행 중 과부하가 생길 수 있고 과부하가 생기면 프레임이 떨어지므로 일반 이미지로 변환해 두는 것 ThorVG로 미리 픽셀 이미지화해 두면 런타임 시 추가 계산 없이 가볍게 출력할 수 있어 퍼포먼스 유지 가능
-
tvg::Picture객체로 SVG 데이터 로드- 파일에 들어있는 SVG 원본 데이터를 ThorVG가 이해할 수 있는 객체로 불러오는 과정
-
tvg::SwCanvas(소프트웨어 캔버스) 생성- 캔버스를 만든 후 픽셀을 담을 공간을 준비하고 Godot이 요구하는 해상도에 맞춰 실제 렌더링 수행
-
Godot Image 리소스로 매핑
- ThorVG가 픽셀로 변환해 준 결과물을 Godot 엔진이 사용할 수 있도록 Image 데이터 형식으로 전달
② 폰트 안에 들어있는 컬러 이모지를 그려주는 역할
- 기본 폰트 렌더러의 한계: Godot의 기본 폰트 엔진(FreeType)은 단색 윤곽선 글자 전용이라서 폰트에 이모지를 스스로 그릴 수 없음
- ThorVG를 통한 컬러 이모지 출력: SVG 기반 이모지 글리프를 만나면 ThorVG를 호출하여 폰트 버퍼 공간에 컬러 그림을 직접 그려 넣도록 처리
-
tvg::Picture객체로 SVG 글리프(조각) 로드- 폰트 파일 안에 숨어있던 특정 컬러 이모지의 SVG 데이터 조각을 찾아 ThorVG 객체로 불러오기
-
FreeType 글리프 버퍼를 렌더 타깃으로 직접 지정
- 새 메모리를 만들지 않고 기본 폰트 렌더러(FreeType)가 이미 비워둔 메모리 공간을 그대로 타깃으로 지정하여 낭비와 속도 저하를 막고 있는 부분
-
FreeType 렌더러에 ThorVG 연결
- Godot이 기본 폰트 엔진(FreeType)에게 SVG와 관련된 렌더링 작업은 ThorVG가 대신할 거라고 알려주는 부분
4. 정리
Godot은 ThorVG를 엔진 전체에 결합하는게 아닌 필요할 때만 불러와서 사용하는 방식으로 활용하고 있었다.
한 번만 실행되면 되는 에디터 파일 추가(임포트) 단계에서는 ThorVG API를 직접 호출해 연결했고 글자를 쓸 때마다 매번 그려야 하는 폰트 렌더링 단계에서는 언제든 다른 도구로 교체할 수 있도록 표준 인터페이스 뒤에 유연하게 연결해 두었다.
같은 엔진 안에서도 용도와 목적에 따라 코드를 통합하는 방식이 완전히 다르게 설계되어 있다는 점을 보고 추후 설계할 때 이 점도 고려해야겠다고 판단하였다.
댓글
Discussion 원문