Polygon 제작자는 JavaScript의 메모리 관리와 네이티브 앱 배포 과정에서 겪은 문제를 해결하기 위해 엔진을 Jai로 다시 만들었다. 그 결과물인 Polygon v2.0.54는 절차적 지오메트리와 커스텀 머티리얼 등을 지원하며, 아티스트용 실행 파일과 개발자용 SDK로 제공된다.
JavaScript에서 Jai로 옮긴 이유
Polygonjs는 8년 전 three.js, TypeScript, Vue.js를 기반으로 브라우저에서 절차적 지오메트리를 만드는 도구로 시작했다. 상업 프로젝트에도 사용됐으며 기존 저장소는 계속 공개돼 있다.
제작자가 엔진을 다시 만들기로 한 주요 이유는 메모리 사용량을 정확히 파악하고 제어하기 어려웠기 때문이다. 브라우저에서 지오메트리를 많이 만들면 메모리가 부족해 탭이 종료될 수 있다. 기존 시스템은 렌더러나 노드 간 캐시가 더는 사용하지 않는 지오메트리를 삭제했지만, 다른 객체가 이를 참조하면 가비지 컬렉터가 메모리를 해제하지 않을 수 있었다. 제작자는 코드가 실제로 메모리를 해제했는지 확인하기 어렵다고 설명했다.
가비지 컬렉터가 메모리를 정리할 때는 프레임 처리 시간을 상당 부분 차지해 프레임이 끊길 수 있다. 메모리를 재사용하는 객체 풀링 같은 기법을 적용해도, 시스템이 누락된 곳을 알려주지 않는다는 문제가 있었다. 테스트 스위트에서 메모리 누수를 확인할 수 없다면 문제를 파악하기 어렵다는 설명이다.
배포 과정에서도 한계가 있었다. Electron이나 Capacitor를 사용하면 Windows, Mac, Linux용 빌드를 만들 수 있었지만, Steam API를 연결해 멀티플레이를 지원하려 할 때 JavaScript에서 네이티브 라이브러리를 호출해야 했다. Electron 샌드박스를 오가는 작업이 복잡해졌고, 제작자는 경쟁 상태나 메모리 누수가 없다고 확신하지 못해 게임을 출시하지 않았다.
재작성 과정과 메모리 관리
제작자는 약 2년 전 대안을 찾기 시작했고, Jonathan Blow가 만든 프로그래밍 언어 Jai의 베타에 지원해 컴파일러를 사용했다. 글을 쓸 당시 Jai는 아직 공개되지 않은 상태였다. 제작자는 Jai에서 메모리 할당 위치와 방식, 해제 시점을 확인하고 제어할 수 있었으며, 풀이나 임시 할당자를 통째로 해제하는 속도도 장점으로 꼽았다. Windows, Mac, Linux뿐 아니라 WebAssembly, Android, iOS로도 배포할 수 있다는 점에서 Electron을 더는 고려하지 않게 됐다고 밝혔다.
엔진 전체를 다시 쓰기로 한 뒤에는 절차적 엔진의 핵심과 약 300개 노드를 재작성해야 했다. three.js를 더는 쓸 수 없어 씬 그래프와 렌더러도 직접 만들어야 했다. 첫해에는 객체 지향 언어로 만든 노드 시스템을 구조체와 함수만 지원하는 언어로 옮기며 기반을 구축했다. 초기에는 three.js를 렌더링에 사용했고, WebAssembly에서 지오메트리를 만든 뒤 JavaScript로 포인터와 크기를 전달했다. 이후 네이티브 환경을 위해 wgpu와 WebGPU를 익히고, Jai 호출을 JavaScript의 WebGPU 호출로 변환하는 얇은 계층을 추가했다.
둘째 해에는 메모리를 해제하지 않고 재사용하는 방식을 적용했다. 노드가 지오메트리를 만들 때 중앙 시스템에서 새 메모리 영역을 받거나, 이전에 사용을 마친 영역을 재사용한다. 노드, 표현식, 지오메트리 속성, 객체 속성, 연결 정보 등 생성되는 데이터는 재사용 배열이나 프레임 끝에 비우는 임시 할당자에 저장된다. 제작자는 이 방식으로 개발이 쉬워지고 버그가 줄었으며, 문제가 생겼을 때 진단도 간단해졌다고 설명했다.
이 과정에서 GPU용 GLSL·WGSL 코드와 CPU용 JavaScript·Jai 코드를 구분하던 gl 노드와 js 노드를 하나의 코드 문맥으로 통합했다. 코드 노드는 간단한 전환으로 GPU 또는 CPU용 코드를 생성할 수 있다. 렌더러는 기본 Lambert 셰이더로 여러 절차적 객체를 표시하는 단계에서 출발해 커스텀 머티리얼도 렌더링할 수 있게 됐다.
Polygon v2 사용 방법
Polygon v2.0.54는 절차적 지오메트리, 커스텀 머티리얼, 컴퓨트 셰이더, 렌더 그래프를 지원하며 추가 기능도 개발 중이다. 장면 파일을 열고 저장하려는 아티스트는 실행 파일을, 커스텀 노드를 만들려는 개발자는 SDK를 사용할 수 있다. 라이브 데모를 체험하거나 다운로드할 수 있다.
댓글 (0)
로그인하면 이 기사에 내 생각을 남길 수 있어요