Анимация
May 11

Вершинная анимация и плагин AnimToTexture

Обзор вершинной анимации

Когда вы впервые поддаетесь искушению разместить десятки или сотни персонажей в одной сцене, вы очень быстро поймете, что прощаетесь с высокой частотой кадров. Скелетные модели обеспечивают потрясающую гибкость для сложных анимаций, но они обходятся гораздо дороже, чем статичные модели, поскольку приходится определять вес кости, выполнять постобработку, обновлять анимацию и т. д. Существуют методы оптимизации, такие как LODs и обмен анимацией, но достичь желаемого уровня производительности при определенном количестве персонажей может быть сложно или невозможно.

Обычно разработчики, работающие в режиме реального времени, обходят эту проблему при работе с большими группами анимированных сеток с помощью техники, которая обычно называется вершинная анимация. Это когда вы запекаете данные из скелетной анимации в файлы текстур, которые могут быть легко прочитаны материалом статической модели для перемещения отдельных вершин. Если вы еще не смотрели видео Джозефа Аззама о Симуляции больших толп на Niagara, это замечательный ресурс, позволяющий увидеть потенциал этого метода. Он может создать армию из 1 миллиона персонажей с высокой частотой кадров в реальном времени.

Моделирование большого скопления людей в Niagara | Unreal Engine

AnimToTexture

В течение многих лет Epic поставляла Vertex Animation Tool с Unreal Engine, который позволял разработчикам легко запекать анимацию. Однако он ограничен использованием в 3Ds Max и поддерживает только модели до 8192 вершин. В UE 5.1 появился экспериментальный плагин AnimToTexture, который может выполнять все операции по запеканию и воспроизведению данных анимации из редактора. Этот плагин был первым представлен в демо-версии City Sample и использовался для пешеходов на средних и дальних расстояниях. Цель этого руководства - повысить осведомленность об этом инструменте и показать, как его использовать.

ВНИМАНИЕ: Плагин AnimToTexture помечен как "экспериментальный", поэтому он с большой вероятностью может быть изменен, не имеет официальной документации и может не обладать поддержкой и стабильностью для работы в производстве. Представленная здесь информация не является исчерпывающей или гарантированной, и может быть устаревшей. Она предоставляется как есть для ваших собственных экспериментов.

Плагин AnimToTexture

Чтобы настроить плагин в собственном проекте, откройте любой проект версии 5.1 или более поздней, перейдите в раздел Edit > Plugins и найдите AnimToTexture. Включите его и перезапустите редактор.

Для начала лучше всего изучить работу плагина, используя готовый контент в папке плагина. Чтобы увидеть этот контент, убедитесь, что в Настройках в правом верхнем углу браузера контента включены Показывать содержимое движка и Показывать содержимое плагина.

Затем в браузере содержимого вы должны перейти в раздел Engine > Plugins > AnimToTexture Content.

В папке Characters > Mannequin вы найдете все ассеты и данные, необходимые для преобразования скелетной модели с анимацией в статическую модель, которая анимируется с помощью материалов. Вы можете открыть одну из двух статических моделей, чтобы посмотреть, как они работают. Также в этой папке находится утилита редактора с простым примером использования некоторых пользовательских узлов Blueprint, которые требует плагин.

Как это работает

Давайте рассмотрим основные моменты настройки системы. В этом разделе я буду ссылаться только на существующий пример контента и освещать некоторые настройки. Вы можете настроить все необходимые элементы вручную, но позже мы рассмотрим, как автоматизировать это для вашего собственного проекта.

Ассет данных

В основе этой системы анимации лежит Data Asset, примеры которого вы можете найти в папке Mannequin > Data. Data Asset выступает в качестве контейнера для хранения различных параметров и ссылок на другие ассеты, а у этого плагина есть свой особый тип, который в дальнейшем используется скриптами автоматизации. Здесь есть два включенных ассета, чтобы показать разницу между анимацией "Bone" и анимацией "Vertex", соответствующие двум моделям в родительской папке.

Модели

Первое, что нужно определить в Data Asset, - это Skeletal Mesh, на который должны ссылаться ее анимации. Вам также понадобится соответствующий Static Mesh. Если автоматизировать этот процесс с помощью Blueprints, в состав плагина входит узел Convert Skeletal Mesh to Static Mesh, но вы также можете сделать это вручную с помощью кнопки Make Static Mesh в верхней части любого окна редактора скелетной модели.

На момент написания статьи AnimToTexture запекает только один LOD, поэтому для начала вам следует убедиться, что количество треугольников в выбранном LOD достаточно низкое. Более высокое количество полигонов приведет к тому, что в режиме анимации "Vertex" потребуется больше места для текстур, а проблемы с производительностью при большом количестве моделей на экране легко усугубить.

Параметр UV Channel - важный параметр, на который следует обратить внимание. В этот слот будет вставлен новый UV-набор, хранящий информацию о позиции для каждой вершины, и это может нарушить работу других функций, основанных на UV, таких как лайтмапы или специальные эффекты материалов.

Текстура

Здесь мы определяем, как будут храниться данные об анимации.

Enforce Power of Two не является строго необходимым, но я обнаружил, что он помогает сделать воспроизведение анимации более плавным и лучше использовать сжатие текстур.

Важным параметром здесь является Mode, который может быть "Bone" или "Vertex".

Режим Bone

Режим Bone является более гибким вариантом, поскольку положение и влияние отдельных костей не привязано строго к идентификаторам вершин. Это означает, что большая часть запеченных данных может быть повторно использована для любого персонажа или модели с аналогичными пропорциями и всех их LODов. Однако для каждого отдельного статичного меша или LOD, необходима своя текстура Bone Weight. Другим преимуществом использования Bone является то, что общий объем памяти результирующих текстур будет меньше, потому что количество костей, которые нужно отслеживать, меньше, чем количество вершин в модели.

Режим Vertex

Режим Vertex записывает положение каждой вершины во время анимации, независимо от того, как движутся кости. Если у вас сложный риг, постобработка анимации, морф-цели или симуляция, происходящие внутри скелетной модели, то вы можете лучше передать это, запекая положение каждой вершины каждый кадр. Компромисс заключается в том, что вам понадобится гораздо больше текстурного пространства для всех этих вершин, и разные модели будут иметь совершенно разные вершины, которые нужно запекать отдельно.

Bone Precision - это еще один компромисс между памятью текстур и точностью анимации в конечном меше. Вы можете увеличить это значение до 16 бит, чтобы убедиться, что все выглядит гладко.

Вся суть текстурной вершинной анимации заключается в том, что все данные анимации запекаются в текстуры, но AnimToTexture в настоящее время не создает эти ассеты для вас. Вместо этого он хочет получить ссылку на существующие файлы. В зависимости от выбранного режима вам потребуется две или три текстуры для хранения данных. Вы можете создать эти текстуры одним из трех способов:

  1. Дублировать существующие файлы текстур (содержимое и настройки будут перезаписаны в любом случае)
  2. Создайте новый объект Render Target, затем щелкните на нем правой кнопкой мыши и Create Static Texture.
  3. Используйте скриптинг. В Blueprints есть узел Create Asset, доступный в Editor Utility Blueprints.

Анимация

Теперь вам нужно выбрать, какие анимации вы хотите запечь в текстуры. Это может быть разобрано позже в материале, поэтому можно сохранить несколько.

Sample rate можно настроить выше, если вам нужно более точное воспроизведение, или ниже, чтобы сэкономить память и стоимость исполнения материала.

Anim Sequences - это место, где вы добавляете желаемые анимации. Убедитесь, что выбранные анимации работают со скелетной моделью, указанной ранее, поскольку этот список не фильтруется на предмет совместимости.

Вам нужно использовать Custom Range только в том случае, если вы хотите обрезать что-то из анимации. Плагин будет знать начальный и конечный диапазон каждой анимации автоматически.

Информация

Остальная часть Data Asset ниже Info предназначена только для хранения и считывания информации плагином. Здесь нет ничего, что можно было бы редактировать.

Слой атрибутов материала

Когда все данные анимации будут запечены (позже!), они будут перемещаться по нашей статичной модели изнутри материала. Для этого используется пользовательский Material Attribute Layer, предоставляемый вместе с содержимым плагина под названием "ML_VertexAnimation" или "ML_BoneAnimation", и его нужно вставить в родительский материал статической модели.

Вам нужно использовать узел GetMaterialAttributes, чтобы разделить вывод Normal и вывод World Position Offset, а затем включить их в остальную часть графа материалов. Ниже приведен базовый пример того, как все это работает в редакторе материалов. Чтобы упростить себе задачу, вы можете скопировать & вставить соответствующие узлы из файлов примеров, приведенных ниже, или из материала Mannequin, входящего в состав плагина.

Более того, все конечные параметры, которые попадают в слой атрибутов, зависят от того, является ли материал экземпляром материала. Итак:

  1. Убедитесь, что использование атрибутов материала включено во всех родительских материалах,
  2. Убедитесь, что вы создали экземпляры материалов,
  3. Убедитесь, что модель использует экземпляры материала!

Обработка

Теперь, когда у нас есть Data Asset, загруженный всей необходимой информацией о запекании, и на нашем меше есть материалы, которым нужны запеченные данные, мы можем завершить весь процесс. Внутри содержимого плагина находится простой Editor Utility Blueprint под названием "BP_AnimToTexture", который показывает минимально необходимую обработку. Если щелкнуть правой кнопкой мыши на блюпринте и запустить его, появится узел Animation To Texture, который запечет заданный Data Asset, а также два узла Update Material Instance from Data Asset. Вместе они наполняют наши анимационные текстуры соответствующими данными и указывают материалам, как их читать. Утилиты редактора на данный момент являются единственным способом работы с этим плагином и создания финальных ассетов.

Изменение параметров слоя

Если вы хотите увидеть или отредактировать эти параметры, откройте экземпляры материалов на ваших моделях (или на примере Mannequin) и переключитесь с вкладки Details на Layer Parameters. Здесь вы можете отредактировать и настроить некоторые параметры, например, указать UV-канал, который он использует (чтобы соответствовать Data Asset), убедиться, что он действительно установлен на Animate, когда вы этого хотите, переключиться между UseFourInfluences или UseTwoInfluences по причинам качества / производительности. По умолчанию ваша модель будет циклически повторять все включенные анимации. FrameOffset и NumFrames могут быть использованы для указания определенного диапазона воспроизведения (считайте, что это как Start Frame и End Frame). А TimeStartOffset можно использовать для того, чтобы убедиться, что все модели не анимируются в унисон.

Если вы откроете слой ML_BoneAnimation, то сможете увидеть, как используются и изменяются некоторые из этих параметров. По умолчанию все это определяется PerInstanceCustomData, который можно программно или вручную редактировать для каждого меша в вашей сцене. Это то, что вы можете использовать для создания динамических толп, где каждый персонаж движется по-своему.

Вы также можете продублировать весь этот слой материала и жестко закодировать в нем различные значения. Вот пример, где я вставил узел PerInstanceRandom, который будет менять время начала анимации каждого экземпляра в диапазоне от 0 до 1 секунды, придавая разнообразие и жизнь персонажам, появляющимся в виде листвы (foliage).

Автоматизация

На момент написания статьи AnimToTexture является экспериментальной функцией и не имеет документации, а пользовательский интерфейс не доработан. Ручная настройка и управление всеми необходимыми данными для окончательного запекания - дело утомительное и очень специфичное для вашего проекта, поэтому для эффективного использования этого инструмента вам понадобится умение работать с утилитами редактора или скриптами Python.

Создатель Кевин Ромонд сделал отличный виджет Editor Utility Widget и Blueprint spawner для своего собственного обзорного видео по этой функции, которое поможет вам сгенерировать необходимые ассеты.
Работает только в Unreal Engine 5.1 - 5.2 Его файлы свободно доступны для загрузки на GitHub и могут послужить отличной отправной точкой для вашей собственной работы.
https://github.com/kromond/AnimToTextureHelpers

Мой вариант автоматизации

Параллельно я работал над собственной методикой автоматизации работы с AnimToTexture. Она может работать не в каждой ситуации, и я еще не автоматизировал все шаги, но я надеюсь, что в своем незаконченном виде она все же поможет кому-то использовать инструмент или узнать о утилитах редактора.

Мой подход был следующим:

1. Создать Утилиту действий с ассетами для выполнения заскриптованных действий правой кнопкой мыши на соответствующих ассетах. Например, я хочу щелкнуть правой кнопкой мыши на ассете Skeletal Mesh и одним махом преобразовать его в вершинную анимированную модель.

2. Пользователь может выбрать, какие анимации он хотел бы запечь.

Диалог появляется потому, что функция, вызываемая в редакторе, имеет переменные входные данные.

3. В каталоге меша создается новая папка, содержащая все необходимые ассеты.

4. Затем запускается цепочка функций для создания новых ассетов. Скелетная модель преобразуется в новую статическую модель, создаются новые пустые текстуры для данных анимации, все соответствующие данные и ссылки помещаются в новый Data Asset, создаются новые материалы, все данные запекаются и вставляются в материалы.

Недоработанная часть этой автоматизации с известными ошибками находится в материалах.

В первую очередь необходимо убедиться в том, что существуют нужные экземпляры материалов и что правильно назначены родительские материалы (скорее всего, это не так).

А затем убедитесь, что созданные экземпляры материалов назначены в новой модели. Помните, что нам нужны экземпляры, а не базовые материалы. Так как настройки слоёв и сам слои доступны только в иэкземплярах.

Далее необходимо добавить специальный слой - экземпляр ассета ML_BoneAnimation, описанный в разделах выше, ко всем экземплярам-материалам. Создайте экземпляр ассета ML_BoneAnimation из папки движка /All/EngineData/Plugins/AnimToTexture/Materials и назначте в слой Background. Если папки нет, то включить плагин AnimToTextures.

Далее нужно полуить атрибуты этого слоя и назначить материалу.
Его можно скопировать и вставить из примера материала "A2T_MaterialNodes" в моем проекте.
Для автоматизации этого процесса необходимо провести некоторые исследования и разработки, но технически вы можете получить доступ к узлам редактора материалов через утилиты и скрипты Python.
Откройте мастер материал и внесите изменния.

Следующий шаг: В слоях экземпляров материалов по-прежнему отсутствуют все параметры анимации, поскольку этот слой не существовал во время остальной части автоматизации. Я также создал скриптовое действие, которое можно использовать для экземпляров материалов, чтобы обновить соответствующие данные из Data Asset.

6. Теперь анимированная статическая модель готова к внедрению в любые системы, которые вам нравятся. Это может быть компонент Instanced Static Mesh, Foliage mesh или рендерер Niagara mesh.

7. Если вы хотите изменить какие-либо настройки и заново запечь данные, есть еще одно скриптовое действие под названием "Rebake Anim Textures", которое можно использовать для Data Asset. Затем следует выполнить последующие действия и снова обновить экземпляры материалов.

Add some PerInstanceRandom HueShift and it’s a party.

Вопросы и соображения

  • В некоторых сценариях освещения, например в редакторе статичных сеток, модель будет самозатеняться на основе исходного поля расстояния. Поле расстояния не перемещается вместе с моделью.
  • Иногда WPO не очень хорошо работает с виртуальными картами теней. Вы можете увидеть артефакты отбрасывания теней.
  • Nanite поддерживает WPO начиная с версии 5.1, но не надейтесь на это слишком сильно. Сейчас при использовании техники AnimToTexture инстансные модели не могут вращаться должным образом при включенном Nanite. Статические сетчатые актеры будут работать и анимироваться с Nanite, но как только Nanite начнет схлопывать вершины по мере удаления, появятся дикие артефакты.
  • Для запуска определенных анимаций в списке запекания существуют другие узлы Blueprint, которые я здесь уже затрагивал. Посмотрите видео Кевина выше, чтобы узнать больше.
  • Вы определенно можете включить это в симуляцию Niagara для реалистичной динамики пешеходного потока!

Надеюсь, это руководство помогло вам начать работу с этим новым плагином. Я считаю, что это очень крутая встроенная функция движка, которая откроет людям возможности вершинной анимации. Эта техника существует уже давно, но теперь вы можете делать все это, не выходя из Unreal Engine.

Ниже приведена ссылка на скачивание файлов примеров, которые я использовал для этого урока. Не стесняйтесь изменять их под свои нужды и доводить начатое до конца.

ФАЙЛЫ ПРОЕКТОВ