LYSC STUDIO

LIST
Cover

언리얼 엔진 5의 나나이트(Nanite) 시스템 심층 분석: 가상화된 마이크로폴리곤 지오메트리의 렌더링 파이프라인과 최적화 전략

·UE5 Engine

언리얼 엔진 5가 게임 산업에 가져온 가장 큰 혁신 중 하나인 나나이트(Nanite) 가상화 지오메트리 시스템. 이 글에서는 나나이트의 내부 작동 원리부터 실무 적용 및 최적화 전략까지 심도 있게 파헤쳐 봅니다.

나나이트(Nanite)의 탄생 배경과 철학

수십 년간 리얼타임 렌더링 분야에서 폴리곤 예산(Polygon Budget)은 게임 개발자들을 끊임없이 괴롭혀온 제약이었습니다. 아티스트들은 수천만 개의 폴리곤으로 이루어진 고해상도 지브러시(ZBrush) 스컬프팅 모델을 만들고도, 엔진에 올리기 위해 노멀 맵을 굽고 리토폴로지(Retopology)를 진행하여 수만 개 수준으로 폴리곤 수를 줄여야만 했습니다. 언리얼 엔진 5의 나나이트(Nanite)는 이러한 전통적인 파이프라인을 완전히 붕괴시켰습니다.

나나이트는 '가상화된 마이크로폴리곤 지오메트리(Virtualized Micropolygon Geometry)' 시스템으로, 픽셀 크기보다 작은 폴리곤들을 효율적으로 렌더링하는 데 특화되어 있습니다. 아티스트가 영화 수준의 에셋(수백만~수십억 폴리곤)을 아무런 최적화 없이 임포트해도, 나나이트는 화면에 보이는 해상도와 거리에 맞춰 실시간으로 지오메트리 디테일을 스트리밍하고 스케일링합니다.

나나이트의 핵심 아키텍처: 클러스터(Cluster)와 DAG(Directed Acyclic Graph)

나나이트의 작동 원리를 이해하려면 메시에 대한 데이터 구조를 먼저 알아야 합니다. 나나이트는 임포트된 메시를 약 128개의 트라이앵글로 이루어진 클러스터(Cluster) 단위로 쪼갭니다. 그리고 인접한 클러스터들을 병합(Merge)하고 단순화(Simplify)하여 더 적은 수의 트라이앵글을 가진 새로운 클러스터를 생성합니다. 이 과정은 모델이 단일 클러스터로 축소될 때까지 반복되며, 결과적으로 DAG(Directed Acyclic Graph) 형태의 계층 구조를 형성합니다.

런타임 시 렌더러는 카메라의 위치와 화면 해상도를 기반으로 이 DAG를 순회합니다. 각 클러스터의 화면상 투영 크기를 계산하여, 픽셀당 약 1개의 트라이앵글이 렌더링되는 최적의 클러스터 레벨(LOD)을 선택합니다. 중요한 점은 이 모든 평가가 CPU가 아닌 GPU의 컴퓨트 셰이더(Compute Shader)에서 수행된다는 것입니다.

렌더링 파이프라인: 투 패스(Two-Pass) 오클루전 컬링과 소프트웨어 래스터라이저

나나이트는 극단적인 드로우 콜(Draw Call)과 오버드로우(Overdraw)를 방지하기 위해 고도로 커스텀화된 렌더링 파이프라인을 사용합니다. 일반적인 하드웨어 래스터라이저는 픽셀 크기보다 작은 트라이앵글을 그릴 때 효율이 급감합니다. 이를 극복하기 위해 나나이트는 소프트웨어 래스터라이저(Software Rasterizer)를 도입했습니다.

화면에 투영된 트라이앵글이 매우 작을 경우(일반적으로 8x8 픽셀 미만), 나나이트는 컴퓨트 셰이더 기반의 소프트웨어 래스터라이저를 사용하여 지오메트리를 렌더링합니다. 반면 트라이앵글이 클 경우에는 기존의 하드웨어 래스터라이저로 전환합니다. 이 하이브리드 접근 방식은 어떠한 상황에서도 최적의 퍼포먼스를 보장합니다.

또한, 나나이트는 투 패스 오클루전 컬링(Two-Pass Occlusion Culling)을 수행합니다. 이전 프레임의 뎁스 버퍼(HZB)를 기반으로 보이는 클러스터들을 먼저 컬링하고 렌더링(Pass 1)한 뒤, 이 과정에서 새롭게 뎁스 버퍼를 업데이트합니다. 그 다음, 첫 번째 패스에서 가려졌던 클러스터들을 다시 검사하여 실제로 보이는 것들만 추가로 렌더링(Pass 2)합니다. 이 덕분에 오버드로우가 거의 완벽하게 제거됩니다.

실무 최적화 전략 및 한계점

나나이트가 마법 같은 기술이긴 하지만, 무조건적인 퍼포먼스를 보장하는 것은 아닙니다. 나나이트를 프로젝트에 적용할 때 고려해야 할 몇 가지 중요한 한계와 최적화 포인트가 있습니다.

  • 재질(Material) 복잡도: 나나이트는 동일한 머티리얼을 사용하는 클러스터들을 모아서 렌더링합니다. 메시 1개에 수백만 폴리곤이 있어도 퍼포먼스 저하가 없지만, 머티리얼 인스트럭션이 무겁거나 투명도(Translucency), 마스킹된(Masked) 머티리얼을 무분별하게 사용하면 성능이 급락할 수 있습니다. 특히 WPO(World Position Offset)를 사용할 때는 주의가 필요합니다.
  • 디스크 공간과 스트리밍 메모리: 가상화된 지오메트리는 결국 방대한 디스크 용량을 요구합니다. SSD의 읽기 속도가 중요해지며, 텍스처 스트리밍과 마찬가지로 나나이트 데이터 스트리밍을 위한 메모리 풀 최적화가 필수적입니다. 콘솔 변수 r.Nanite.Streaming.MemoryBudget을 적절히 조절해야 합니다.
  • 하드 서페이스와 유기체의 차이: 나나이트 알고리즘은 딱딱한 표면(건물, 바위, 무기 등)에서 압도적인 압축률과 단순화 효율을 보입니다. 반면 머리카락, 얇은 나뭇잎 등 미세한 구조가 많은 경우 클러스터 단순화가 어려워 효율이 떨어집니다.

결론적으로 나나이트는 게임 아트의 패러다임을 바꾼 위대한 기술입니다. 모델러는 더 이상 토폴로지와 노멀 맵 베이킹에 시간을 쏟지 않고 창조적인 스컬프팅에 집중할 수 있습니다. 개발자는 이 시스템의 내부 원리를 명확히 이해하고, 메모리와 머티리얼 비용을 통제함으로써 차세대 그래픽을 안정적으로 구현할 수 있을 것입니다.

Implementation C++ / UE5
// 나나이트 관련 핵심 콘솔 변수 설정 예시 (DefaultEngine.ini)
[SystemSettings]
r.Nanite=1
r.Nanite.RequireDX12=1
r.Nanite.Streaming.MemoryBudget=512
r.Nanite.MaxNodes=2500000
// 나나이트 WPO(World Position Offset) 활성화 (UE 5.1+)
r.Nanite.AllowWPO=1
나나이트는 단순한 렌더링 기술을 넘어 아트 파이프라인 전체를 재정의하는 혁명입니다. 한계와 최적화 포인트를 명확히 이해하고 프로젝트에 적용하시길 바랍니다.