원문 캡처 · magnopus.com
원문 캡처 · magnopus.com

Magnopus의 샘 벌리(Sam Birley)는 언리얼 엔진용 가우시안 스플랫 렌더러를 고쳐 GPU 인스턴스 수 제한을 없애고, 장면 전체를 메모리에 올리지 않아도 되는 스트리밍과 세부 수준(LOD) 처리를 구현했다고 설명한다. 이 방식은 사용자 지정 메모리 예산 안에서 GPU보다 큰 장면도 불러와 렌더링하도록 설계됐으며, Magnopus의 OKO Unreal과 OKO Web에 Streamed SOG 지원으로 적용됐다.

기존 렌더러는 언리얼 엔진의 GPU Scene에 스플랫을 인스턴스로 등록해 에셋 하나당 약 1,600만 개까지만 처리할 수 있었다. 벌리는 GPU Scene 사용을 중단하고 간접 인스턴스 드로우 방식으로 바꿨다. 스플랫 데이터를 GPU 텍스처에 저장하고, 정렬 키를 만드는 셰이더가 계산한 드로우 수를 활용해 렌더링했다. 테스트 에셋 약 3,000만 개를 그릴 수 있었고, 카메라 시야 밖 스플랫을 GPU에서 걸러내는 기능도 추가했다.

이후에는 모든 스플랫을 GPU 메모리에 상주시킬 수 없다는 문제가 남았다. 스플랫 하나는 데이터를 압축해도 약 32바이트를 차지했다. 이에 공간을 여러 영역으로 나누고 각 영역에 성긴 단계부터 촘촘한 단계까지 저장하는 PlayCanvas의 Streamed SOG 형식을 사용했다. 화면에서 멀거나 작게 보이는 영역은 더 성긴 단계로 그리며, 화면상 오차를 픽셀 단위로 추정하는 SSE 기준을 적용해 프레임마다 영역별 LOD를 선택한다. 사용자는 프로젝트 설정에서 Low·Medium·High 품질을 고를 수 있다.

필요한 데이터는 파일이나 HTTP를 통해 비동기적으로 불러온다. 처음에는 아무 데이터도 없을 수 있고, 거친 단계부터 먼저 도착한 뒤 세부 정보가 추가된다. GPU 업로드가 끝난 뒤에야 해당 데이터가 그려지도록 처리하며, 메모리 예산이 차면 가장 멀리 있는 영역부터 내보낸다. 여러 카메라가 동시에 렌더링되는 언리얼 환경도 지원하도록 카메라별 LOD 선택과 전달을 처리했다.

텍스처 크기 제한도 조정했다. 행마다 4,096개 스플랫을 배치하던 고정값을 하드웨어 한도에 가까운 폭으로 넓혀 단일 텍스처에 최대 약 2억 6,800만 개를 담을 수 있게 했다고 벌리는 설명한다. 이는 약 8.6GB의 VRAM에 해당한다. 그보다 큰 장면은 고정 크기의 텍스처 풀에 필요한 청크만 불러오고, 사용하지 않는 청크를 내보내 처리한다.

벌리는 LOD 선택이 느리고 청크 제거 정책이 단순하며, 오버드로가 렌더링 성능의 주요 한계로 남아 있다고 밝혔다. 약 3,000만 개 스플랫으로 된 테스트 장면은 이제 몇 초 안에 열리고, 시간이 지나며 세부 묘사가 선명해진다고도 설명했다. OKO Unreal과 OKO Web에 Streamed SOG 지원이 구현됐으며, 제품은 OKO Unreal 다운로드 페이지에서 확인할 수 있다.

관련 글: 1편: Niagara를 사용해 언리얼에서 GPU 기반 가우시안 스플랫 뷰어를 만든 방법, 2편: 언리얼에서 사실상 무제한 가우시안 스플랫을 렌더링하게 된 과정.