Directx 11 скелетная анимация
Я заблудился со скелетной анимацией. Я читал кое-что об этом, но я все еще не понимаю их. Это выводы, которые у меня есть. Я видел 3 способа анимировать меш с костями:
У меня есть класс Mesh, который содержит вершины, буфер вершин, индексный буфер и текстурный шейдер, а также матрицу преобразования. Я мог бы использовать класс для каждой кости, добавить вес, и мне было бы легко анимировать модель. Но это означает, что используется слишком много памяти, потому что некоторые сохраненные вещи используются некоторое время, когда они должны быть только один раз.
Используйте вершинный шейдер. Добавьте вес и индекс кости во входном параметре вершины и используйте матричный массив в качестве глобальной переменной, поэтому в шейдере мне просто нужно использовать матрицу кости. Мне кажется, что это решение более эффективно, но я помню, что в руководстве по directx 11 (от Rastertek) он сказал, что HLSL должен быть быстрым, потому что он использует много времени, и я думаю, что это будет слишком тяжело. В любом случае, это решение, которое я попробую, по крайней мере, узнать, работает ли это или нет.
Используйте матрицу и обратную матрицу для каждой кости. Что касается чтения, это способ взять. Но так я не поняла. Почему здесь используется обратная матрица, и как матрицы "связаны" с вершинами. Я имею в виду, если я переместлю матрицу для правой кости, что сказано в коде, что будут использоваться только правые вершины?
Итак, мои вопросы:
- Является ли второй способ жизнеспособным? или это будет слишком много для GPU с какой-то сеткой и анимацией?
- Может кто-нибудь объяснить, как матрицы связаны с вершинами и почему используются обратные матрицы? Или связать мне что-нибудь по этому поводу.
Надеюсь, ты меня понял, потому что не уверен, что хорошо объяснил. И, пожалуйста, извините за мой английский, я сделал все, что мог. Заранее спасибо.
1 ответ
Первый подход может работать, если в модели есть только жесткие части. Как только появляются деформируемые детали, вы получаете отверстия или другие артефакты. Например, если у вас есть модель руки, и вы поворачиваете предплечье, в локте будет отверстие, а в изгибе - треугольники, перекрывающие друг друга.
Что касается второго подхода - ну, я действительно не знаю, как вы собираетесь это сделать. Пиксельный шейдер - определенно неподходящее место для этого. Все, что нужно сделать, можно сделать в вершинном шейдере.
Что приводит нас к подходу 3.
Я признаю, что скелетная анимация немного сложна для понимания. Рассмотрим приведенный выше пример: модель руки, состоящая из плеча и предплечья. Для этой модели нам понадобятся две кости: одна от плеча до локтя и одна от локтя до кисти.
Каждая вершина должна быть связана как минимум с одной костью. Это делается с весами вершин. Давайте предположим, что есть некоторые вершины плеча, на которые влияет только плечо. На вершины локтя влияют обе кости, а на вершины кисти влияет только кость предплечья. Это дает следующие веса:
bone: | upper arm bone | forearm bone
--------------------+----------------+--------------
shoulder vertices: | 1 | 0
elbow vertices: | 0.5 | 0.5
hand vertices: | 0 | 1
Первое, что нужно сделать, это рассчитать положение и ориентацию всех костей. Это делается с помощью матрицы для каждой кости. Обычно за расчет этих матриц отвечает аниматор. Эта матрица поместит кость из некоторой исходной позиции в ее текущую позицию. Референтная позиция одинакова для всех костей и может быть выбрана произвольно.
Следующее, что нужно сделать, это вычислить результирующие позиции вершин. Мы знаем, что вершины движутся вместе со своими костями. Поэтому нам нужны позиции вершин в локальной системе координат кости. Однако обычно положения вершин задаются в мировых координатах в позе связывания. Вот для чего обратная матрица. Он трансформирует вершины из мирового пространства (позы связывания) в локальное пространство кости. Существует одна обратная матрица для каждой кости.
Когда у нас есть вершина в локальной системе кости, мы должны преобразовать их в соответствии с движением кости. Для плечевых и ручных вершин эта задача тривиальна. Мы можем использовать матрицы костей и умножить их на обратные матрицы.
Для локтевых вершин это не так просто. На самом деле существует множество методов для расчета преобразования. Нам нужно смешать преобразования двух костей с заданными весами. Самый простой способ сделать это - умножить матрицы на их веса и сложить их вместе. Это дает окончательное преобразование, которое можно использовать для преобразования положения вершины.
Шаги (только для одной влияющей кости):
- Преобразуйте положение вершины из позы связывания в местную костную систему.
- Рассчитать матрицу трансформации кости с помощью аниматора.
- Преобразуйте положение вершины из локальной костной системы в анимированную позицию с помощью костного матрикса.
Если имеется более одной влияющей кости, матрицы должны быть смешаны. Связь костей и вершин достигается с помощью веса вершин. Обычно вершина не сохраняет веса для всех костей. Вместо этого максимальное количество влияющих костей ограничено, например, 4. Затем вершина хранит индексы первых 4 наиболее влияющих костей и их веса.