이 기술 블로그에서는 스태틱 환경을 집중적으로 최적화하는 방법을 알려드릴 예정입니다. 이를 통해 비용이 큰 픽셀은 신(scene) 안에 상호작용형 오브젝트나 근접한 오브젝트처럼 가장 눈에 띄는 부분에 활용할 수 있습니다. 이 작업은 사소해 보이지만, 실제로는 우리 스튜디오를 포함한 많은 스튜디오의 창의적이고 반복적인 워크플로와 상충하는 경우가 종종 있습니다. 이 글에서는 최적화에 대한 우리의 생각들을 풀어나가고자 합니다. 그리고 멋진 경험을 만드는 데 필요한 워크플로를 제약하지 않는 선에서 높은 수준으로 최적화한 환경 콘텐츠를 제작하기 위해 UE4 툴을 기반으로 개발하는 방법을 설명하겠습니다. 주로 타임 스톨(Time Stall)을 예로 들겠지만 이러한 최적화는 내셔널 지오그래픽: 익스플로 VR(National Geographic: Explore VR)(오큘러스 퀘스트), 코스터 컴뱃(Coaster Combat), 펫 랩(Pet Lab)(오큘러스 고)을 포함한 다른 타이틀에도 적용되어 있습니다. 우리 스튜디오의 목표는 VR로 제작 가능한 영역의 한계를 넘어서는 것입니다. 그리고 탄탄한 기술적 기반으로 고퀄리티 비주얼을 추구하고 있습니다. 이러한 야심 찬 목표를 달성하기 위해 최적화에 관한 내부 철학을 정립했으며 그 원칙은 다음과 같습니다:
- 최적화 작업은 최대한 자동화합니다.
- 최적화 작업은 비파괴적이어야 하고 예술적 유연성과 반복처리가 가능해야 합니다.
- 최적화는 워크플로의 일부분입니다. 우리는 프로젝트 초반부터 우수한 성능을 위해 노력하고 정기적인 자동화 테스트로 검증을 하며 이를 계속해서 준수해 나가는 것을 목표합니다.
이미 잘 알려졌듯이 VR 최적화의 핵심은 다음과 같습니다. 모바일 VR에도 적용되지만, 예산이 조금 더 빠듯하다는 차이점이 있습니다.
- 셰이더 복잡성: 수많은 픽셀을 때로는 여러 번 그리기 때문에 가능한 한 경제적인 방법을 모색합니다.
- 드로 콜 수: 상태 변경은 GPU 및 CPU 리소스를 많이 소모합니다. 변경 작업을 제한합니다(퀘스트의 경우 약 150회 목표).
- 트라이앵글 수: 원시 버텍스 데이터는 특히 모바일 VR에서 제약이 되는 요소입니다. 약 15만 개를 목표로 합니다.
우선, 랜드폴(Landfall)의 개발 과정에서 스태틱 신을 최적화할 방법을 찾기 시작했고, 곧바로 언리얼 엔진에서 제공하는 계층형 레벨 오브 디테일(Hierarchical Level of Detail, HLOD) 시스템을 발견했습니다. 이 시스템을 사용하면 여러 오브젝트를 동시에 일괄 처리하여 드로 콜을 줄이고, 여러 머티리얼을 새로운 하나의 머티리얼로 구울 수도 있습니다. 이러한 이점은 최적화 워크플로 개선을 통해 이루고자 했던 부분과 딱 맞아 떨어졌습니다.
위 그림은 향상된 성능을 보여주는 타임 스톨 HLOD 클러스터의 예시입니다.
일반적으로 HLOD 프로세스는 아래와 같은 두 단계로 구성됩니다.- 클러스터 생성
- 프록시 메시를 형성하기 위해 신 안의 액터를 그룹화하는 프로세스입니다.
- 이 작업은 수동 또는 자동으로 가능합니다.
- 자동화된 클러스터 생성에서 많은 사항을 변경했으며 그 내용은 아래와 같습니다.
- 프록시 메시 구축
- 프록시 메시 렌더링에 사용할 소스 메시(및 머티리얼)를 병합하는 프로세스입니다.
- 병합한 메시는 다음과 같은 방법으로 최적화합니다:
- 각 메시는 하나로 병합되어 드로 콜 수가 줄어듭니다.
- 머티리얼 병합. 머티리얼의 수를 줄이고 단순화합니다.
프록시 메시 및 머티리얼 교체의 예:
주황색: HLOD 레벨 2. 액터 수: 1
파란색: HLOD 레벨 1. 액터 수: 2
녹색: HLOD 레벨 0. 액터 수: 8
HLOD 시스템이 제공하는 옵션은 최적화에 사용하고자 하는 사용자들에게 용이한 시작점을 제공합니다. 우리는 타이틀을 개발하는 동안 위의 모든 사항을 이행하는 동시에 더 우수하고 빠른 성과와 높은 퀄리티를 구현하기 위해 HLOD 시스템을 꾸준히 개선하고 확장했습니다. 아래 섹션에서는 프로세스의 변경 내용과 그 이유를 설명합니다.
주황색: HLOD 레벨 2. 액터 수: 1
파란색: HLOD 레벨 1. 액터 수: 2
녹색: HLOD 레벨 0. 액터 수: 8
자동화한 클러스터 생성의 향상
클러스터 생성은 HLOD 프로세스의 첫 번째 단계입니다. 먼저, 프록시 메시로 만들 클러스터에 추가할 스태틱 메시 액터를 선택합니다. 처음에 아트 팀은 아래와 같은 세 가지 이유로 모든 클러스터를 수동으로 생성했습니다. 첫째, 자동화된 클러스터링이 예기치 않거나 원치 않는 결과를 가져왔습니다. 둘째, 클러스터 생성이 다소 느리고 오랜 시간이 걸렸습니다. 셋째, 클러스터링을 제어하기 위한 파라미터의 수가 너무 적은 것으로 판단되었습니다. 예를 들어, 기본적으로 머티리얼의 다양한 셰이더 모델 유형을 구분할 수 없습니다. 이로 인해 투명하고 마스크가 적용된 머티리얼이 불투명한 머티리얼로 구워졌습니다.시간이 지나면서 클러스터 생성 시스템을 다음과 같이 개선했습니다.
- 대안이 될 다른 클러스터 생성 알고리즘으로 클러스터 생성 속도 향상(참고: 계층 구조의 응집형 클러스터링(hierarchical agglomerative clustering)
- 함께 클러스터링되는 머티리얼 유형을 더 효과적으로 제어하기 위해 클러스터 제약 추가
- 머티리얼 유형, 머티리얼의 스태틱 스위치값 등을 클러스터 제약으로 활용 가능
- 클러스터 생성 옵션 추가
비저빌리티 컬링 추가
중요한 개선 사항 중 하나로 플레이어가 볼 수 없는 메시 트라이앵글을 제거하는 기능이 있습니다. 저희는 게임에서 플레이어가 제약되어 있는 플레이 공간을 정의했습니다. 플레이 공간은 하나 이상의 볼륨으로 나타나며 한 레벨을 통한 스플라인으로도 나타납니다. HLOD 애셋을 생성하는 동안 이 툴은 플레이 공간에서는 보이지 않는 트라이앵글을 모두 제거합니다.
위: 트라이앵글 컬링 이전 타임 스톨의 식당 신(scene)
아래: 보이지 않는 트라이앵글이 컬링된 동일한 신
향상된 아틀라스 메서드
머티리얼 병합 중에 텍스처는 텍스처 아틀라스에 저장됩니다. 기본적으로 HLOD 시스템은 그리드 기반 솔루션을 사용합니다. 패킹된 애셋마다 상이한 해상도를 설정할 수는 있지만 이는 해당 애셋의 텍스처 크기를 기준으로 합니다. 우리는 백그라운드에서 사용되는 일부 오브젝트에 가끔씩 많은 텍스처 공간이 할당된다는 점을 발견했습니다. 이는 해당 머티리얼에 대형 텍스처가 포함되어 있기 때문이죠. 대형 텍스처 맵이 생기는 원인은 여러 가지입니다. 즉, 하나의 대형 텍스처 맵에 여러 애셋이 서로 결합되어 있거나, 플레이 공간에 가까이 배치되도록 제작된 소품이 백그라운드에도 사용되었기 때문입니다. 이 두 경우에, 애셋은 결합된 아틀라스 내에서 많은 공간을 차지합니다.우리는 트라이앵글 컬링에 사용한 볼륨을 통해 아틀라스를 더 효율적으로 패킹할 수 있었습니다. 다음은 아틀라스 생성 측면에서 개선된 사항입니다.
- 트라이앵글 컬링 후 아틀라스 생성
- UV 재생성을 통해 최적화한 패킹
- 플레이 공간에 가까운 오브젝트일수록 해상도 증가
- 패킹된 텍스처에서 오브젝트 크기를 정의할 때 라이트 맵 해상도도 고려
왼쪽은 언리얼의 기본 그리드 레이아웃입니다. 아틀라스 텍스처 내 사각형 영역이 각 메시에 할당됩니다.
오른쪽은 가중치 적용 UV 기반의 아틀라스 레이아웃입니다.
머티리얼 굽기 확장자
머티리얼 병합 프로세스에서 변경한 또 다른 사항은 아틀라스에 텍스처를 굽기 위한 옵션을 더 추가한 것입니다. 시스템은 텍스처를 굽고 결합하는 기능을 제공했지만 이 기능은 PBR 워크플로에만 제한되어 있었습니다. 즉, 최종 출력을 한 텍스처로 굽는 기능은 지원되지 않았습니다. 우리는 아티스트가 최종 텍스처로 다시 구워지는 대상을 제어할 수 있는 시스템을 구현했습니다.- 베이스 컬러 굽기
- UE4의 기본 베이크 메서드
- 베이스 컬러 입력만 새로 생성된 텍스처에 결합
- PBR 셰이딩 유지
- 일반적으로, 결합한 노멀 맵, 패킹된 메탈릭, 러프니스 및 앰비언트 오클루전 맵도 이 옵션을 통해 구워짐
- 플레이 공간에 가까워 여전히 다이내믹 셰이딩이 필요한 오브젝트에 주로 사용됨
- 디퓨즈 굽기
- 라이트 맵 및 베이스 컬러를 단일 텍스처 맵에 구움
- 디퓨즈 및 스페큘러 굽기
- 라이트 맵, 베이스 색 및 모든 셰이딩을 단일 텍스처 맵에 구움. 멀리 있는 오브젝트에 매우 유용한 기능
- 스페큘러 셰이딩이 구워지는 위치는 신 안의 액터에 의해 정의됨
- 라이팅을 제외한 한 머티리얼 안에 넣을 수 있는 하나의 단일 텍스처 맵 산출. 가장 경제적인 렌더링 방법
- 디퓨즈, 스페큘러 및 포그 굽기
- 이전 옵션과 동일하지만 익스포넨셜 하이트 포그도 포함함
왼쪽은 HLOD 레벨은 0이며 여기에는 원본 PBR 머티리얼이 사용됩니다. 개별 메시는 보이지 않는 트라이앵글이 컬링되는 하나의 새로운 메시로 결합됩니다. 이 LOD 레벨은 플레이어가 가깝게 위치한 경우에만 보입니다.
중간: HLOD 레벨 1. 이 메시에는 매우 단순한 머티리얼이 포함되어 있으며 모든 라이팅과 셰이딩은 텍스처에 구웠습니다.
오른쪽: HLOD 레벨 2. HLOD 레벨 1과 마찬가지로 하나의 텍스처 맵만 입력된 단순한 머티리얼을 포함합니다. 모든 라이팅과 셰이딩이 구워져 있습니다.Like HLOD level 1, this has a simple Material with only one texture map input.
우리는 약 2년 전부터 HLOD 시스템을 자체적인 필요성에 따라 확장하기 시작했습니다. 따라서, 충분한 시간을 두고 결과에서 나타난 장단점을 비롯해 개발 프로세스에 미치는 영향을 평가할 수 있었습니다.
긍정적인 점은 처음의 목표를 대부분 달성했다는 것입니다.
- 기존 설정을 기반으로 한 새로운 콘텐츠를 (재)생성할 수 있으므로 전체 프로세스는 비파괴적입니다. 대체로 조정 작업은 HLOD 프로세스를 재실행하는 정도만 필요했습니다.
- 이러한 프로세스를 언리얼 코드베이스 내부, 예를 들어 에디터와 커맨드릿에서 작동할 경우 여러 가지 이점이 있습니다. 이 프로세스는 에디터 내에서 모든 종류의 프로퍼티 세트와 원활하게 통합됩니다. 또한 기존 코드를 재투입하고 기존 코드 경로를 활용 및 확장할 수 있습니다.
- 이 과정은 거의 완전한 자동화 프로세스로 간편하게 진행됩니다.
앞으로 주목해야 할 몇 가지 사항은 다음과 같습니다.
- 애플리케이션 설치 공간이 증가하며 때로는 상당히 많이 증가하곤 합니다. 모든 대상을 HLOD 세트에 다시 구울 경우 디퓨즈 텍스처만을 렌더링하므로 성능상의 이점이 있습니다. 하지만 이러한 모든 애셋은 고유하게 구워진 자체 텍스처 아틀라스를 갖게 됩니다. 따라서 패키지 크기와 로딩 시간에 유의해야 합니다.
- 현재로서는 여전히 초기의 수동 설정이 필요하지만 이는 주로 프로젝트별로 구성하는 작업입니다. 이러한 설정이 올바르게 작동하려면 일부 초기 애셋도 필요합니다.
- 마지막으로, 가장 중요한 단점은 유지해야 할 변경 사항이 많다는 점입니다. 포트나이트에서 HLOD 시스템에 추가한 많은 개선 사항이 우리의 자체적인 최적화와 충돌하는 경우가 있습니다. 이 시스템은 UE4의 핵심 시스템이므로, 엔진을 업그레이드하는 경우 여러 변경 사항을 자체적인 변경 사항과 통합해야 하는 노력이 필요합니다.
우수한 엔진인 언리얼은 오픈 소스 라이선스이기 때문에 필요에 따라 유연하게 조정할 수 있습니다.
하나 덧붙이고 싶은 것은 우리는 한층 더 향상된 UE4 경험을 구축하는 데 도움을 줄 수 있는 인재를 언제든지 환영합니다. 암스테르담에서 함께 흥미진진한 VR 및 AR 타이틀을 개발하고 싶으신 분은 채용 정보를 확인해주세요.
앞서 언급했듯이 오큘러스 퀘스트에 대한 최적화 정보는 아래 자료를 참조하시기 바랍니다.
- UE4 Performance and Profiling | Unreal Dev Day Montreal 2017 [2017년 10월 9일]
- Optimizing Oculus Go for Performance [2018년 3월 22일]
- One Mesh To Rule Them All [2018년 4월 3일]
- Tech Note: Profiling & Optimizing on Mobile Devices [2018년 5월 30일]
- OC5 Talk - Porting Your App to Oculus Quest [2018년 9월 26일]
- Oculus Connect 5 | Reinforcing Mobile Performance with RenderDoc [2018년 9월 26일]
- Understanding Gameplay Latency for Oculus Quest, Oculus Go and Gear VR [2019년 4월]
- Developer Perspective: UE4 Logging and Console Commands for Mobile VR [2019년 7월]
- Developer Perspective: Improving Memory Usage and Load Times in UE4 [ 2019년 7월 25일]
- Developer Insights: How to Develop with Vulkan for Mobile VR Rendering [2019년 8월 2일]
- Common Rendering Mistakes: How to Find Them and How to Fix Them [2019년 8월 22일]
- Official Oculus documentation on Rendering in Unreal Engine 4 [2019년 9월 4일]
- Official Unreal Engine 4 documentation on HLOD [2019년 9월 4일]
- OC6 Talk - Using Vulkan for Mobile VR [2019년 9월 26일]