Рубрика ээээээксперименты в Unreal Engine
Идя по парку одним томным вечером, предаваясь размышлениям о ничтожности трупа на троне, который мешает рождению нового истинного бога, у меня как это часто бывает, мысли резко свернули не туда...
Предыстория
Ранее в комментах к одному из постов Ярослава я упомянул что в версии 5.7 появилась фича Nanite Assembly, которая юзается эпиками просто для сборки деревьев в единую скелетную сетку. Однако она на самом деле гораздо интереснее чем кажется на первый взгляд.
Например на тот момент я её использовал для сборки пушек на корабле. Как можно увидеть в левом верхнем углу, скелетная сетка занимает технический минимум в 64 треугольника, несмотря на то что одна пушка занимает почти 2к треугольников. Переиспользование ресурсов, укуси меня селедка!
Да, вы можете задаться вопросом: а на кой черт ты это все в скелетную сетку запекаешь, почему не ISM? И это правильный вопрос, который нужно было мне задавать 3 года назад =)
Из этого можно сделать вывод: мы можем собрать практически что угодно из разных скелетных сеток, объединить это и получить хорошую оптимизацию за счет экономии вызовов на отрисовку и памяти. Да? Пи...
Вот и я так подумал в тот злополучный день. Эта ересь проникла в мой разум и начала меня разъедать. Или это были комары...?
Разумеется поскольку я был не за компом, то проверить ручками это не мог, еще и идти до дома почти час, а я умирал от любопытства. Поэтому я открыл чатгпт и задал ему этот вопрос. Ответ убил:
На тот момент я подумал: "А, ну тогда просто подожду следующей обновы.". Как вы понимаете 5.8 этой фичи не завезла. А 5.9 с большим шансом уже и не будет, т.к. там 2 года будут пилить пососную 6.0. Получается... тупик?
Да нет конечно! У меня что, зря подписка на чатгпт за 100 бачей простаивает? Тут как раз и гпт5.6 соляра вышел, че бы не сжечь токены на то чтобы доработать движок, правильно?
Nanite Assembly Character
Для начала пару слов о том что мне захотелось сделать. В UE есть инструменты для того чтобы мержить скелетные сетки в рантайме. Например старый добрый однопоточный SkeletalMergingLibrary::MergeMeshes и относительно новый многопоточный Mutable. Последний скорее целый завод чем инструмент.
Плюсы очевидны, вы можете прямо во время игры менять облик персонажей по вашему желанию, но за это игроку придется платить производительностью CPU. А если у вас там какая то мудреная логика или очень много костей(привет метахюман) то это может даже приводить к статтерам. Неприятно. Поэтому частенько просто создают пресеты различных комбинаций одежды и напрямую их отдают в игру без лишней склейки и обработки.
Так же вы разумеется можете вообще ничего не объединять и отдавать на одном персонаже сразу несколько сеток, но каждая такая сетка жрет CPU, и не какой нибудь там 11 поток у которого работа принеси-подай, а игровой поток, который напрямую влияет на итоговый фпс.
Вроде как в UAF с этим получше, но я еще не щупал это сам.
В демке моей игры собственно юзается Mutable, поэтому мне пришлось сильно ограничить дальность прорисовки нпц чтобы минимизировать статтеры. Получилось так себе... Поэтому я решил что лучше пусть у меня будет большое кол-во пресетов которые я буду юзать напрямую.
Но каждый такой пресет - дублирование полигонов что негативно сказывается как на размере игры, так и на объеме потребляемой памяти. Что еще немаловажно: если я изменю какую то часть одежды, мне придется заново перегенерировать все пресеты где она использовалась. Прям тоже очень не очень получается...
Ну и вы могли уже догадаться какую задачу нейросетке я поставил: Доработай Nanite Assembly для объединения скелетных сеток с множеством костей. И нейронка в целом справилась на ура. Пришлось сделать несколько правок в логику существующей библиотеки по сборке скелетных сеток в Assembly, но основную задачу она закрыла с первой попытки.
Болтовня-болтовня, хватит эту болтовню слушать! Давайте лучше к цифрам.
Дано: 5 скелетных сеток(голова, руки, верхняя одежда, штаны, обувь) у всех настроен LOD соответственно самый дальний персонаж у нас требует меньше 2к треугольников(на настройках High и Epic у меня полигонаж считается примерно как х2 так что имейте ввиду в итоговых цифрах) и 120 акторов на сцене.
Да я знаю что тут надо показывать различные варианты одежды и бла-бла-бла. Но концептуально от этого ничего не изменится.
Цифры не очень, в первую очередь из-за большого кол-ва Draw вызовов. Такова доля стандартных скелетных сеток...
Ладно-ладно! Вы меня поймали. Сравнивать стандартный LOD и Nanite в данном кейсе нечестно, т.к. последний группирует все вызовы на отрисовку и тем самым сильно оптимизирует конкретный демонстрируемый кейс. Если вы и так собираетесь использовать префабы персонажей, и не ограничены морфами, то вы и сами вполне могли бы просто сконвертировать сетки в нанит и получить ту же производительность в этой ситуации. Вы бы смогли увидеть разницу только на большой вариативности одежды, а мне пока что не до того.
Так что да, я насрал сырым отчетом.