Как Zugalu Entertainment снизила использование ОЗУ с 20 ГБ до 500 МБ для Процветай: Тяжесть короны

Эта веб-страница была переведена с помощью машинного перевода для вашего удобства. Мы не можем гарантировать точность или надежность переведенного контента. Если у вас есть вопросы о точности переведенного контента, обращайтесь к официальной английской версии веб-страницы.
Процветай: Тяжесть короны — это средневековый строитель города с элементами стратегии в реальном времени. Игра, в которой судьба королевства зависит от каждого решения, принимаемого игроком, имеет как однопользовательский, так и кооперативный многопользовательский режим. Игроки могут стратегически расширять свою территорию и королевство, а затем строить на большой карте.
Когда команда начала разрабатывать игру, они столкнулись с препятствиями при улучшении производительности. После обширного тестирования они узнали, где находятся узкие места, и что им нужно сделать — создать систему запекания анимации и кастомную систему растительности. Вот как они улучшили анимацию персонажей в игре.
ПРОБЛЕМА:
Преодоление узких мест производительности, вызванных анимацией персонажей
ПЛАТФОРМА:
ПК
МЕСТОПОЛОЖЕНИЕ:
Альберта, Канада
СОСТАВ ПРОЕКТА:
16
Процветай: Тяжесть короны: Кейс Unity
Как студия оптимизирует производительность, анимируя сотни персонажей?
Когда игра начала принимать форму, команде Zugalu Entertainment стало ясно, что производительность будет их самой большой проблемой. Они нацеливались на довольно низкие системные требования – видеокарту NVIDIA GeForce GTX 750 Ti для GPU и четырехъядерный процессор, который является чипом с четырьмя независимыми единицами, называемыми ядрами, которые читают и выполняют инструкции ЦП.
«В любое время, когда вы хотите нацелиться на систему, предпочтительная частота кадров составляет 60 FPS. Были части нашей системы, которые мы не могли действительно изменить, которые занимали огромную часть производительности, поэтому нам пришлось искать выгоды откуда только можно», - говорит Джеки Ли, ведущий концепт-художник и технический художник в Zugalu Entertainment.
Пока они искали области для повышения производительности, они решили, что огромное количество анимаций персонажей необходимо исправить, так как они использовали большое количество ОЗУ и вызывали сбои многих игровых систем.

Результаты
- Сократили использование ОЗУ с 20 ГБ до 500 МБ
- Анимировали тысячи персонажей на экране одновременно
- Сократили количество вызовов отрисовки персонажей с 1000 до 20 экземпляров вызовов отрисовки
- Увеличили производительность с примерно 3,5 миллисекунд на видеокарте GTX 750 Ti до 0,35 миллисекунд на видеокарте 2080 Ti
Миграция от вершинного к запеканию костей
Чтобы оптимизировать процесс анимации персонажей, команда создала систему запекания анимации. Им нужно было иметь сотни анимированных персонажей на экране одновременно и изначально они рассматривали решения для активов анимации вершин. Это была огромная проблема для их использования VRAM и ОЗУ. Они не могли найти другое решение, поэтому решили построить свое собственное.
Для системы анимации команда начала использовать запекание вершин, которое включает в себя получение всех ключевых кадров их анимации и запекание этих данных на каждую вершину. «Одна текстура будет содержать одну анимацию, но размер текстуры для этой одной анимации довольно большой. Стоимость памяти является фактором количества вершин, умноженного на количество запеченных кадров. Таким образом, 5000 вершин умножить на 100 кадров будет текстура размером 6 МБ в формате 32-битного float RGB», - говорит Ли. «Когда вам нужно много различных анимаций, умноженных на большое количество разнообразных персонажей, стоимость памяти начинает становиться экстремальной.»
Им нужно было сильно сократить это, но при этом сохранить возможность использовать GPU для ускорения анимаций. Они решили перейти к запеканию костей, что обеспечивало простой способ использовать меньше данных, так как рендерер мешей Unity использует кости для трансформации вершин.

Процветай: Тяжесть короны | Zugalu Entertainment | PlaySide Studios
«Все, что нам нужно было сделать, это взять процесс скиннинга сетки, привязать 3D-сетку к скелету или каркасу, позволяя сетке деформироваться и двигаться реалистично, когда скелет анимирован, и перенести его на GPU», - говорит Гаррет Хау, технический директор Zugalu Entertainment.
Затем они взяли трансформации костей на кадр и запекли их как текстуры. Запекание такой информации сэкономило им много памяти. «С помощью запекания костей разные персонажи с одинаковой костной структурой могут делиться запеченными данными анимации. У нас были персонажи, такие как фермер и рабочий, чьи костные структуры были одинаковыми. Мы повторно использовали одни и те же запеченные данные для нескольких персонажей, чтобы получить еще больше экономии», - объясняет Ли.
В конце концов, несмотря на то, что в игре много персонажей и анимаций, они сократили использование оперативной памяти с 20 ГБ до 500 МБ.

Предварительный просмотр запеченных анимаций в редакторе
Преимущества инстансирования GPU
Когда дело дошло до анимации, команда сосредоточилась на рендеринге кожи, применяя материалы, шейдеры и текстуры к сетке, чтобы смоделировать цвет кожи, затенение и текстуры. Ли объясняет, что «преимуществом рендеринга кожи на основе вычислений GPU является то, что у нас был доступ к инстансированию GPU. Вместо того чтобы рендерить каждого персонажа по одному, каждый из которых является отдельным вызовом отрисовки, мы рендерили нескольких персонажей с разными анимациями, используя один вызов отрисовки.»
Это было возможно, поскольку они взяли данные анимации, текстуры и упаковали их в один единственный массив текстур. Это выглядит как одна текстура для GPU. «Возможно отрисовать каждого персонажа с помощью одного вызова отрисовки, но для большей гибкости у нас было всего четыре персонажа, которые делили кости.»

Запись инстансированного вызова отрисовки
При переходе от запекания вершин к запеканию костей команда сократила количество вызовов отрисовки персонажей с 1000 до 20 инстансированных вызовов отрисовки. «Запекание вершин было сложным, поскольку каждая отдельная подсетка считалась разной. «Персонаж может иметь несколько частей, и каждая из них будет иметь вызов отрисовки», — говорит Хау.
С учетом запекания костей, это зависит от того, сколько различных типов персонажей есть в игре. Каждый персонаж будет иметь максимум один вызов отрисовки, так как он объединяет все подмеши в одну сетку. «Например», объясняет Хау, «даже если на экране 10 различных типов персонажей и у каждого есть несколько подмешей, будет только 10 вызовов отрисовки.»

Процветай: Тяжесть короны | Zugalu Entertainment | PlaySide Studios
“«Unity имеет много API, которые делают именно то, что вам нужно. Это включает в себя получение конкретной информации из импортированного FBX, легкое переключение ключевых слов шейдеров и создание пользовательских инструментов редактора с простыми в использовании API инспектора.»”
Jackie Li - Zugalu Entertainment
Lead Concept Artist and Technical ArtistКонструирование матричного преобразования
Изучение скиннинга мешей помогло команде преодолеть их большие анимационные трудности. Они использовали API Unity, чтобы помочь им на этом пути.
Чтобы получить преобразования костей, они получили доступ к публичному свойству SkinnedMeshRenderer.bones. Этот API возвращает массив преобразований, который содержит информацию, как и любые другие преобразования GameObject. Для измерения производительности они использовали автоматическое обнаружение сборок разработки Unity Profiler, работающих на других компьютерах в локальной сети. Это позволило им профилировать игру на системе с минимальными требованиями, работая с их основными компьютерами.
Команда тестирования производительности также применяла ProfilerMarker.Begin() и ProfilerMarker.End() API для выборки производительности на кадр. Эти можно использовать, создав ProfileMarket.struct, а затем вставив предыдущие два вызова методов в место, где они хотели протестировать время ЦП. Этот результат затем появился в Unity Profiler.

Процветай: Тяжесть короны | Zugalu Entertainment | PlaySide Studios
Ли говорит: «API Unity были отличными. Они помогли сделать определенные части разработки бесшовными.» Единственный баг, с которым столкнулась команда, был связан с координатным пространством в GPU. «Мы получали мировое пространство, но нам нужно было пространство костей.»
Во время выборки кадра трансформации кости во время запекания им нужна была трансформация относительно начальной позиции кости, известной как bindpose. Для достижения этого они построили матричную трансформацию. Сначала они получили матрицу bindpose из SkinnedMeshRenderer.sharedMesh.bindposes. Затем они умножили матрицу мирового преобразования кости на матрицу преобразования bindpose (например, boneTransform.localToWorldMatrix * bindpose).

Снимок персонажа в редакторе шейдера в Shader Graph
“«Shader Graph — это ответ Unity на создание шейдеров без глубокого понимания самого кода шейдера. Это было действительно удобно, так как нам не нужно было переписывать весь шейдер самостоятельно.»”
Garrett Hau - Zugalu Entertainment
CTOСоздание шейдеров с легкостью
Когда дело дошло до производства шейдеров для анимации, команда выбрала Shader Graph. «Это ответ Unity на создание шейдеров без глубокого понимания самого кода шейдера. Это было действительно удобно, так как нам не нужно было переписывать весь шейдер самостоятельно», — говорит Хау.
Для скиннинга мешей им пришлось делать много математических расчетов шейдеров, и узлы, которые предоставляет Shader Graph, позволили им это завершить. Ли объясняет, что «это выборка текстур и математика матриц. Если вы захотите, вы также можете использовать пользовательский узел функции Unity, чтобы написать сам код.»
Для инструментов редактора анимационный директор имел конкретные требования для запекания анимаций, так как он создавал их все сам. «С помощью C# и API Unity было довольно легко включать и выключать интерполяцию для шейдеров. Они также помогли нам изменить количество костей для запекания и количество кадров для их запекания», — говорит Ли. «Удобные API инспектора позволили легко добавить эти функции редактора в инструмент запекания.»

Сэмплирование матричных текстур в Shader Graph
Оставайтесь оптимистичными и внимательными
В конце концов, хотя разработка игры была полна взлетов и падений, команда улучшила производительность GPU с примерно 3,5 миллисекунд на графической карте GTX 750 Ti до 0,3 миллисекунд на графической карте 2080 Ti.
Как говорит Ли: «Мы в восторге от экономии производительности и от того, как получилась игра.»

Процветай: Тяжесть короны | Zugalu Entertainment | PlaySide Studios
Загрузите Unity Pro сегодня
Начните создавать игры, которые конкурируют с большими студийными релизами и превосходят их по качеству и успеху с помощью мощных инструментов, поддержки, проверенных партнеров и яркого сообщества.