Привязка К Графическому Процессору. Как Перенести Всё И Немного Больше На Видеокарту. Анимации

Когда-то было огромным событием появление на графическом процессоре модуля мультитекстурирования или аппаратного преобразования и освещения (T&L).

Настройка конвейера с фиксированными функциями была магическим шаманством.

А те, кто умел включать и использовать расширенные возможности конкретных чипов посредством хаков API D3D9, считали себя познавшими Дзен.

Но время шло, появились шейдеры.

Поначалу они были очень ограничены как по функционалу, так и по длине.

Тогда появляется все больше и больше возможностей, больше инструкций, более быстрое выполнение.

Появились вычислительные технологии (CUDA, OpenCL, DirectCompute), и сфера применения мощности видеокарт стала стремительно расширяться.

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

Первая часть будет посвящена системе анимации.

Все, что описано, основано на практическом опыте, реализовано и работает в реальных игровых проектах.

Ох, снова анимация.

Об этом уже сто раз написано и описано.

Что тут такого сложного? Упаковываем костные матрицы в буферы/текстуры и используем их для скиннинга в вершинном шейдере.

Это было описано еще в GPU Gems 3 (Глава 2. Анимированный рендеринг толпы) .

И реализовано в последнее время Презентация Unite Tech .

Можно ли сделать это по-другому?



Техническая демо от Unity

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

Параллельная работа — это все хорошо, мы ее не рассматриваем.

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

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

Скелеты слева, рыцари справа.

Сорт так себе.

Каждый юнит состоит из 3 LODов (~300, ~1000, ~4000 вершин каждый), а на вершину влияют только 2 кости.

Система анимации состоит всего из 7 анимаций для каждого типа юнитов (напомню, что их уже 2).

Анимации не смешиваются, а переключаются дискретно из простого кода, который выполняется в job'ax, на что акцентируется внимание в презентации.

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

Скелетная анимация, как я уже писал, основана на технологии, описанной еще в 2009 году.

Инновационный? Хм.

Прорыв? Эм.

Подходит для современных игр? Ну разве что похвастаться соотношением фпс к количеству юнитов.

Основные недостатки такого подхода (предварительного запекания матриц в текстуры):

  1. Зависимость от частоты кадров.

    Если вам нужно вдвое больше кадров анимации, удвойте объем памяти.

  2. Никакого смешивания анимации.

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

  3. Нет подключения к конечному автомату Unity Animator. Удобный инструмент для настройки поведения персонажа, который можно подключить к любой системе скиннинга, но в нашем случае из-за пункта 2 все очень усложняется (представьте, как смешать вложенные BlendTrees).



GPS

Система анимации на базе графического процессора.

Я только что придумал название.

К новой системе анимации предъявлялось несколько требований:

  1. Работайте быстро (ну это понятно).

    Вам нужно анимировать десятки тысяч различных юнитов.

  2. Быть полным (или почти) аналогом анимационной системы Unity. Если там анимация выглядит вот так, то и в новой системе она должна выглядеть точно так же.

    Возможность переключения между встроенными системами CPU и GPU. Это часто необходимо для отладки.

    Когда анимации «глючат», то перейдя на классический аниматор можно понять: это глюки новой системы или конечного автомата/самой анимации.

  3. Все анимации настраиваются в Unity Animator. Удобный, проверенный, а главное готовый к использованию инструмент. Мы будем производить велосипеды в другом месте.

Давайте переосмыслим подготовку и запекание анимаций.

Мы не будем использовать матрицы.

Современные видеокарты хорошо работают с циклами и помимо float поддерживают int, поэтому работать с ключевыми кадрами мы будем как на процессоре.

Давайте рассмотрим пример анимации в модуле Animation Viewer:

Привязка к графическому процессору.
</p><p>
 Как перенести всё и немного больше на видеокарту.
</p><p>
 Анимации

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

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

Позиция — Vector3, кватернион — Vector4, масштаб — Vector3. У нас будет одна общая структура ключевых кадров (для упрощения), поэтому нам нужно 4 числа с плавающей запятой, чтобы соответствовать любому из вышеперечисленных типов.

Нам также нужны InTangent и OutTangent для корректной интерполяции между ключевыми кадрами в соответствии с кривизной.

Ах да, и не забывайте о нормализованном времени:

   

struct KeyFrame {

Теги: #Разработка игр #unity #Работа с 3D-графикой #GPGPU #рендеринг #разработка игр
Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.