формула анимации костей / суставов opengl - PullRequest
0 голосов
/ 29 апреля 2018

В настоящее время я работаю над анимацией модели с использованием веса суставов и вершин. Мой вопрос не зависит от программы, а основан на GLSL. В мой шейдер загружена следующая информация

uniform mat4 projection,camera,model;
in vec3 vertex;

struct Joint
{
 mat4 invBind;
 mat4 global;
};
uniform Joint transforms[16];
in ivec4 jointIndices;
in vec4  weights;

Здесь Соединение в структуре, которая используется для преобразования вершины. Имеет 2 типа информации

invBind: - эта матрица является инверсией локального преобразования связывания соединения в глобальном / модельном пространстве, которое используется для преобразования модели из пространства модели в локальное пространство соединения

global: - эта матрица используется для преобразования вершины из локального пространства соединения в его окончательное глобальное / модельное [или мировое] пространство

глобальный = parent_global_joint_transform * joint_local_bind_transform. Я загрузил свою модель из файла .dae блендера, и поэтому "joint_local_bind_transform" транспонирован и затем использовал

в ivec4 jointIndices: - список всех возможных суставов, которые влияют на эту вершину

в весах vec4: - вес, связанный с соответствующим суставом, воздействующим на эту вершину

У меня есть массив таких суставов размером 16, потому что в моей модели столько суставов

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

Было бы неплохо ответить на простой код вершинного шейдера. Спасибо

1 Ответ

0 голосов
/ 29 апреля 2018

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

//make a 4D vector from the vertex' position
vec4 position = vec4(vertex, 1.0);

//accumulate the final position
vec4 p = vec4(0, 0, 0, 0);
for(int i = 0; i < 4; ++i)
{
    Joint joint = transforms[jointIndices[i]];
    p += weights[i] * joint.global * joint.invBind * position;
}
gl_Position = p;

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

Чтобы уменьшить объем данных, передаваемых в графический процессор, вы также можете предварительно рассчитать joint.global * joint.invBind.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...