Оптимізація пайплайну Lumen+Nanite+VSM для реалістичного проєкту в Unreal Engine 5

Привіт! Мене звати Сергій, я Head Dev команди Spacedev Games. У цій невеликій статті я поділюся досвідом оптимізації графічної складової комплексного проєкту в стилі «реалізм» на Unreal Engine 5 з використанням пайплайну Lumen/Nanite/Virtual Shadow Maps і способами, як досягти результату у більше ніж 100 FPS на mid-end залізі. Методи та приклади, наведені у статті, актуальні для версій рушія 5.2 і пізніших.

Пайплайн Lumen + Nanite + VSM

З офіційним релізом UE5 і його подальшими оновленнями Epic Games пропагують використовувати Lumen GI для програмного трасування променів, технологію Nanite замість Level of Details, а також Virtual Shadow Maps (VSM) для рендерингу тіней. Кожен новостворений проєкт на UE5 за замовченням конфігурується під цей пайплайн, що може викликати проблеми із продуктивністю при високому рівні деталізації вашої сцени, використанні ассетів від Quixel Megascans, великої кількості Foliage на сцені тощо.

За загальноприйнятим стандартом, для досягнення мінімум 60 кадрів на секунду, на рендер кожного кадру вашої сцени має виділятися до 16.6 мілісекунд. В рамках даного фрейм-бюджету ви маєте вмістити і задачі для GPU в Render Thread, і обчислення CPU в Game Thread. Консольна команда, що допоможе моніторити дані показники в реальному часі:

stat unit

І також кількість кадрів на секунду:

stat fps

Зазвичай проблеми із продуктивністю виникають або в Game Thread, що означає ботлнек на CPU, або в Render Thread, що свідчить про ботлнек на стороні відеоприскорювача. Але часто завантажений Game Thread може викликати додаткові обчислення Render Thread через так званий CPU stall (час очікування відеокартою завершення обчислення інструкцій CPU) і навпаки. Тож перш за все слід визначити, яка саме частина вашого проєкту є ботлнеком. В цьому можуть допомогти як вищезазначені команди, так і профайлери:

  • команди profilegpu і stat gpu підкажуть, на що саме витрачається ресурс відеокарти;
  • stat streaming допоможе дізнатися, чи не є проблемою текстури у вашій сцені.

Читайте також

Для профайлінгу Game Thread можна використовувати команду stat game, яка покаже, як часто CPU навантажується тими чи іншими операціями — Blueprint Time, World Tick Time тощо. Для більш точного визначення проблемних аспектів на стороні CPU мені подобається використовувати профайлер із Session Frontend через його візуальну простоту і доступність, який був вирізаний із нових релізів Unreal Engine на користь нового профайлера Unreal Insights. Для Session Frontend можна записати стат-файл командами stat startfile і stat stopfile (у будь-якій актуальній версії рушія) і завантажити їх у профайлер Session Frontend, який доступний у всіх версіях рушія до 5.2 включно.

Тут я буду розбирати варіант саме ботлнека на стороні GPU, за умови що у нас немає проблем із Game Thread, а CPU не перенавантажує відеокарту надмірним потоком інструкцій.

Отже, перше, з чим ви зіткнетесь при спробі оптимізувати ваш Render Thread, буде факт того, що Lumen за замовченням, навіть у пустій сцені, використовує до 5 мілісекунд часу для реалізації обчислень. Маючи всього декілька Nanite мешів на сцені ви побачите ще один неприємний факт у вигляді відносно високого показника Nanite::VisBuffer, що фіксується рушієм за замовченням навіть із мінімальним використанням Nanite. Це не є великою проблемою, якщо ви цілитесь виключно на гравців із high-end системами та прискорювачами рівня RTX 40XX. Проте якщо мета дозволити гравцям із більш доступними збірками насолодитися вашою грою у 60+ кадрів з рендером в нативній роздільній здатності — це може виявитись фактично недосяжним.

Пайплайн Lumen/Nanite/VSM з коробки не дозволяє використовувати ніякі інші підходи або комбінування із більш класичними методами (як от LOD, Masked Foliage, Cascaded Shadow Maps або використання Screen Space Global Illumination замість Lumen). Всі три технології були створені для роботи виключно між собою, а їх комбінування з альтернативними методами або вимкнення на користь legacy підходів може вирішити початкову проблему, але накладе x3 додаткові проблеми зверху.

Наведені нижче підходи з погляду Epic Games фактично є «костилями» і не рекомендовані до реалізації під Lumen/Nanite/VSM пайплайн. Проте допомогли розібратися з проблемами швидкодії на боці GPU у нашому проєкті (Glory to the Heroes). Він при цьому використовує Lumen, фотоскани, великі відкриті локації та зараз не виходить за рамки 17-20 мілісекунд на кадр навіть у найважчих сценах із 100 комплексними AI агентами, що завжди залишаються активними (на відеокарті рівня RTX 3060 TI).

Nanite

Nanite був створений для заміни LOD-ів та поліпшення візуальної якості віддалених об’єктів. Він чудово виконує свою функцію без значного імпакту на продуктивність при використанні з no-baked high-poly геометрією (як фотоскани). Однак якщо ваша сцена складається із мешів з різною геометрією і топологією (наприклад, високополігональних сканів великих каменюк або архітектури разом із no-geometry) ви отримаєте проблеми з швидкодією та overhead на Render Thread через Virtual Shadow Maps, що необхідний для коректного рендерингу нанітної геометрії, а саме їх вплив на Shadow Path. Застосування Nanite до masked ассетів або геометрії із якісною лоу-полі топологією може викликати циклопічного рівня навантаження на GPU через так званий Quad Overdraw.

«Тому якщо ваш проєкт включає як лоу-полі, так і хай-полі моделі — Nanite слід використовувати виключно там, де він необхідний і на тій геометрії, яка має важку топологію і високу щільність геометрії»

Рендерер не зможе обробити нанітні і не нанітні відбивачі (casters) тіней разом в одному графі, тому Shadow Path розділиться на два окремих — Nanite Rasterize Path і Non-Nanite Rasterize Path, що будуть оброблятися послідовно. Також не нанітні меші не будуть мати відповідної «Nanite Data Structure», що використовується рендерером для прискорення обчислень нанітної геометрії.

Простим рішенням, яке допомогло нам при створенні локації із густим лісом, що повністю складається із не-нанітних мешів дерев, трави, кущів тощо, стало агресивне використання якісних LOD-ів з 2Д «імпостерами» на останньому LOD-і, а також вимкнення тіней на всіх LOD-ах, крім першого і нульового. Це призвело до ледь помітних втрат візуальної якості через зменшення загальної деталізації тіней на сцені, проте мінімізувало час на обчислення Non-Nanite Rasterize path.

Lumen

Так само як і VSM, Lumen покладається на Nanite Data Structure, щоб побудувати граф сцени GI (Global Illumination). І так само як у випадку із нанітною і не-нанітною геометрією разом із VSM, Lumen вимагає додатковий окремий граф для включення нанітної і не-нанітної геометрії в GI.

Для зменшення імпакту через ці додаткові обчислення з мінімальними втратами якості і деталей відображень (Lumen Reflections) можна законфігурувати наступні налаштування Lumen (можна використовувати як консольні команди, так і глобально налаштувати проєкт), що мають найбільший вплив на продуктивність:

  • Lumen.ScreenProbeGather.MaxRayInstensity — даний параметр відповідає за максимальну інтенсивність променів, що використовуються для збору інформації про освітлення в сцені (Screen Probe Gather) в рамках Lumen GI. Простіше кажучи, він контролює, наскільки яскравими можуть бути відбиття та непряме освітлення. Зменшення цього значення може допомогти оптимізувати продуктивність, але може призвести до менш точних або тьмяніших відбиттів.
  • Lumen.ScreenProbeGather.ScreenTraces.HZBTraversal — відповідає за оптимізацію трасування променів, зокрема, з використанням ієрархічного буфера глибини (Hierarchical Z-Buffer, HZB) для пришвидшення цього процесу. Вимкнення цієї опції може покращити якість, але значно вплине на продуктивність.
  • Shadow.Virtual.ResolutionLodBiasDirectional — контролює зміщення рівня деталізації (Level of Detail, LOD) для віртуальних тіней від спрямованих джерел світла (Directional Lights). Він впливає на роздільну здатність карт тіней, що використовуються для рендерингу. Збільшення значення цього параметра зменшить роздільну здатність тіней, що призведе до покращення продуктивності, але зробить тіні менш чіткими.
  • Lumen.Reflections.DownsampleFactor — контролює роздільну здатність, в якій обчислюються Lumen Reflections. Простіше кажучи, він визначає, наскільки сильно зменшується роздільна здатність, перш ніж Lumen обробить відбиття. Збільшення цього значення призведе до менш детальних відбиттів, але значно покращить продуктивність.

Додатково можна поекспериментувати із наступними параметрами у PostProcessingVolume:

  • Lumen Scene Lightning Update Speed
  • Final Gather Lightning Update Speed
  • Diffuse Color Boost

Оптимальні значення, звісно, залежать від конкретного проєкту та особливостей вашої сцени.

Застосування наведених методів підвищить шанси досягти прийнятної продуктивності навіть на mid-end обладнанні, не відмовляючись при цьому від Lumen і Nanite. Вони також можуть стати в пригоді багатьом починаючим розробникам, які використовують Unreal Engine для своїх проєктів і стикаються із проблемним етапом оптимізації рендеру.

Підписуйтеся на Telegram-канал @gamedev_dou, щоб не пропустити найважливіші статті і новини про геймдев

👍ПодобаєтьсяСподобалось4
До обраногоВ обраному3
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Якщо це ігровий проект, то все простіше.
1. Не використовуйте Lumen, користуйтесь SSGI різниці ніякої но в залежності від проекту це від 4 до 10 мс. Візуально різницю треба шукати під лупою. В Марвел Райвалс переключення на SSGI дає буст з 180 фпс до 260 фпс, це якщо приклад на практиці.
2. Не використовуйте Nanite, використовуйте LODs, різниця перформансу колосальна. Його варто використовувати лише коли кількість квадів перевалює за якісь безумні межі. Тому ніде окрім якогось мега супер 8к реалістичного архітектінгу це не використовується.

Взагалі по дуже короткій оптимізації візуалу в анріал 5 можете глянути цей відос, якщо цікавому кому.

youtube.com/watch?v=...​AP-mU?si=7485RQJchyKj-IsZ

А це хіба не про цього ж хлопа з відео мова йде?
x.com/...​tatus/1878184855097286711

Про цього, але у чому його проблема, окрім того, що він підмічає вузькі місця оптимізації? Часто бачу як його критикують, але нічого конструктивнішого за «ги ги, не вміє користуватися» не бачив

З частої критики дуже багато бачу саме девелоперів які люблять назвати оптимізацією викручування повзунків длсс, тому можливо просто не приязнь від таких людей. Тим не менше, завжди хочеться побачити на прикладі оптимізований люмен з нанітом хоча б в 1 грі, бо поки не бачив жодної такої гри. А бачити як апскейлер створений для реалізації 4к, стає необхідністю на 1080р просто добиває. Я уже не говорю про те яким чином люди налаштовують Lumen з його 8 мс нагрузкою до рівня DDGI з 0.6-0.8 мс? Що це за фантомні проекти і чому це чудо налаштування ще нікому не показали -_-.

Для того аби перевірити твіт на правдивість достатньо зайти в анріал ендж, виставити ті і інші налаштування і на живому прикладі побачити різницю. Цю двіжуху ми 100 раз перечекали, не тільки у наших проектах, але і в іграх від зарубіжних студій. Люмен і Наніт в 0 убивають оптимізацію. Їх адекватно використати неможливо в геймдеві, через це усі релізи на Анріал 5 виходять, ну такими якими виходять. Карти 30 серії більше всіх страждають від них, 40 теж пихтить страшно. Але я відкритий до дискусії, тому якщо маєте на примітці якусь гру на 5 Анріалі з адекватною оптимізацією, то радий би глянути її налаштування наніту і люмену через команд консоль.

П.С. Додам що відкривши форум Анріал по темам, можете також зауважити кількість девелоперів які фіксують ті ж самі цифри і проблеми з неможливістю адекватно налаштувати ці технології.

В такому випадку сенсу використовувати Неріальний Двіжок 5 немає і можна залишатися на 4 версії. Бо по великому рахунку крім Люмена, Наніта і ряду покращень по доступному інструментарію він більше немає переваг.
Якщо Наніт і його необхідність ще можна назвати перебільшеною, то Люмен це шикарна технологія яка дозволяє реалізувати трасування променів на будь якому GPU і виглядає на три голови краще ніж SSGI, краще виглядає тільки апаратне трасування.
У проектах типу Фортнайт або Марвел Райвалс дійсно буде мінімальна різниця, проте якщо мова про реалістичний проект там знову ж таки буде колосальна різниця і щоб досягти хоча б ± схожого візуалу із SSGI треба аб’юзити пост-процесінг, стоврювати фейкові невидимі джерела світла і так далі. До прикладу є Ready or Not які не використовують динамічне світло а все освітлення на рівні запікають. Але це не підійде до кожного проекту.

Проблема тут, на мою думку, полягає виключно в тому, що поки що доступне на ринку залізо не витягує Люмен. Хоча маючи хоча б карту рівня RTX 4070 вже можна нативно запустити будь яку демку від Епіків в нормальній кадровій частоті (Matrix City, Electric Dreams) де абсолютно ВСЕ це наніт разом із Люменом і VSM. Через 2-3 роки середньостатистичний юзер вже не матиме тих проблем із якими стикається його залізо на 5 анріалі сьогодні.
Більше лякає упор самих Епік Геймс на TSR і апскейлери, проте знову ж таки це лише питання часу, коли ми зможемо працювати із цими технологіями нативно без апскейлерів.

Багато корисної інформації, в тому числі про правильний юз кейс наніта можна переглянути тонну чудових відео від самих Епіків на Unreal Fest — www.youtube.com/@UnrealEngine/videos

Багато корисної інформації, в тому числі про правильний юз кейс наніта можна переглянути тонну чудових відео від самих Епіків на Unreal Fest — www.youtube.com/@UnrealEngine/videos

Так бачив, проте Наніт в 2к нагибає 4080S / 4090 в фортнайті, з виключенням Наніта буст перфоменс йде в +100%. А головне зникають статери, що піднімають 1% Low з 19 фпс до 100+ в залежності від карти та сцени.
Така ж ситуація з 4к, і це в їх же ключовому проекті.

такому випадку сенсу використовувати Неріальний Двіжок 5 немає

Анріал 5 це в першу чергу не про люмен і наніт, там є багато дійсно дуже корисних технологій

1. Метасаунд
2. World Partition
3. OFPA
4. Пакет роботи з анімаціями
5. Новий Хаос
6. Pixel Streaming
7. Підтримка нових АРІ
8. Нові покращенні інструменти для анімації / блупрінта і т.д. в рази кращі за попередню версію
9. DDGI / RTXGI

У проектах типу Фортнайт або Марвел Райвалс

З DDGI різниця і в мега реалістичному інвайрменті мінімальна, найбільш вагомий злегка гірші тіні на відкритих локаціях, різницю між якими 99% юзерів ніколи не побачить.

Проблема тут, на мою думку, полягає виключно в тому, що поки що доступне на ринку залізо не витягує Люмен

Якщо технологію не витягує адекватно GPU за більше 1000$+ то можливо проблема не в техніці, бо з РТ(RTXGI) у тебе буде краща картинка та більше продуктивності. На даному етапі на 4080S / 4090 фулл рт + path tracing 1440р йде краще ніж порізаний люмен+наніт в Сталкер 2 і лише на 10-15% гірше ніж Wukong.

Більше лякає упор самих Епік Геймс на TSR і апскейлери,

Вони тому і роблять упор на апскейлери, бо їх технологію скоріше за все неможливо оптимізувати. Чому я так думаю? Тому що у них ті ж самі проблеми з Люменом і Нанітом в Фортнайті, їх мультимілярдному проекті, що і у інді девелоперів. При чому вони кочують від проекту до проекту в незалежності від баджету.

Через 2-3 роки середньостатистичний юзер

Це чесно кажучи дуже поганий бізнес підхід. Давайте будемо чесними, ігри створенні для того аби продаватися, а основний консумер сидить на картах РТХ 3060 і їм аналогічним картам. А якщо дивитися на перспективу, то ріст продуктивності відеокарт з кожним роком стає все повільнішим, і якщо вірити деякими технічним спеціалістам ми доходимо до так званої технологічної стіни, яку буде нелегко подолати. Тому, ще не відомо що там буде через 3-4 роки, особливо коли Нвідіа випускає АІ інтерполяція замість чистої продуктивності.

Уточнення
Я можливо першочергово не коректно виразився, бо тема йшла про оптимізацію, проте якщо девелопер бажає бачити в своїй грі Люмен + Наніт, це не проблема. Це Ок. Але лише у тому разі якщо гра пропонує клієнту можливість відключення цього самого наніту та інші види світла, які його мід рендж ПК не ставлять в позицію дуже відому серед любителів чорно оранжевих сайті.

Метасаунд — поки що технологія без чіткого призначення і чесно важко уявити якийсь юз-кейс де Метасаунд дуже допоміг би, можливо якісь проекти де звук є ігровою механікою.

World Partition — технологія ще з 4 анріала, і слід зазначити що працює вона погано у порівнянні із тим же Левел Стрімінгом. Всім відомі статтери у проектах на анріалі — результат саме World Partition.

Пакет анімацій — я думаю ви про Motion Matching. Крута штука теж але зовім не гейм ченджер, ALSv3 що доступний ще з 4 версії із коробки показує ідентичний результат.

Кеос — взагалі не юзабельна технологія з точки зору продуктивності, якщо намагатися руйнувати ним щось більше за 1 на 1 метр куб — game thread одразу перенавантажується обчисленнями фізики. Anchor Fields для кулінгу зруйнованих частинок працюють м’яко кажучи через сраку, якісь частинки видяляються а якісь ні і продовжують існувати на рівні навантажуючи Game Thread.
Ми намагалися з ним працювати, але врешті вирішили робити звичайне стейджове руйнування із запіканням. Епіки перестали ним займатися ще роки три тому.

Про блупрінти — не знав що були якісь фундаментальні зміни, наче всі ноди як були так і лишились) Але якщо дасте посилання то буду радий ознайомитись.

А щодо RTXGI — він розроблявся саме під 4 Анріал, і 5 версія його вже не підтримує після релізу 5.0. Плюс це апаратне рішення яке вимагає RT ядра для роботи, на відміну від софтового Люмена.Тоді вже краще викорисовувати Standalone Ray Tracing.

За Threat Interactive стежу давно ще десь із перших відео, і він дійсно багато корисної інфи розповідає в роликах. Відео про те, як робили оптимізацію в Days Gone або покадровий аналіз Need for Speed — взагалі маст хев до перегляду.
Але у тому ж ролику по оптимізації сцени з Megalights — він не показав як Нанітні меші які він залишив на сцені будуть видавати шалені артефакти шейдінгу після вимкнення VSM, підозрюю, що не тільки Нанітні, бо оптимізація у ролику полягала в тому, що ми залишаємо Люмен але вимикаємо VSM на користь CSM, і міняємо TSR на TAA. Для сцени в його прикладі, де немає фоліаджу, скіннед мешів, джерел світла що не є статично зафіксованими, або навіть ландскейпу, така солянка спрацювала і він отримав 40 кадрів в нативних 4К. Але якщо застосувати методи з цього відео на реальний ігровий рівень то це просто не буде працювати. З SSGI замість Люмена сцена до речі виглядала би зовсім інакше
Ось саме відео —

видавати шалені артефакти шейдінгу після вимкнення VSM,

Якщо не помиляюся то з 5:02 він показує результати в моушені. Звісно в редакторі, але заради об’єктивності сцена сама по собі не ігрова теж. youtube.com/watch?v=...​si=8N3lnNOTViJROnhH&t=302

З SSGI замість Люмена сцена до речі виглядала би зовсім інакше

При правильному налаштуванні SSGI різниця буде мінімальною, консюмер в 99% не зауважить різниці, а з RTXGI картинка буде якісно краще, продуктивність у порівняні з Люмен Хардвер буде вище. Це якщо говорити про конкретно про використання у геймінгу. Для архівізу і початкова сцена була норм.

Підписатись на коментарі