Свернутая сетка при рендеринге анимированной модели, загруженной с помощью Assimp в OpenGL

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

Вот короткое видео, иллюстрирующее проблему.

Как вы можете видеть на видео, у меня правильно отображается анимированная "фигурка". Однако наложение сетки, по-видимому, отображается только частично.

Как уже упоминалось в заголовке, я использую Assimp и OpenGL.

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

└───Scene
     ├───Camera
     ├───Armature
     │    └───Torso : [ ROOT_BONE ]
     │        ├───Chest : [ BONE ]
     │        │    ├───Neck : [ BONE ]
     │        │    │    └───Head : [ BONE ]
     │        │    ├───Upper_Arm_L : [ BONE ]
     │        │    │    └───Lower_Arm_L : [ BONE ]
     │        │    │        └───Hand_L : [ BONE ]
     │        │    └───Upper_Arm_R : [ BONE ]
     │        │        └───Lower_Arm_R : [ BONE ]
     │        │            └───Hand_R : [ BONE ]
     │        ├───Upper_Leg_L : [ BONE ]
     │        │    └───Lower_Leg_L : [ BONE ]
     │        │        └───Foot_L : [ BONE ]
     │        └───Upper_Leg_R : [ BONE ]
     │            └───Lower_Leg_R : [ BONE ]
     │                └───Foot_R : [ BONE ]
     └───Character: [ 1 MESH(ES) ]

Вот пример моей текущей структуры узлов моделей. Каждый из узлов имеет матрицу преобразования, а те, у которых [ROOT_BONE]/[BONE] рядом с ними, также включают матрицу смещения.

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

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

uniform mat4 uModelViewProjection;
uniform mat4 uBones[100];

in vec4 aPosition;

in  vec4 aWeights;
in ivec4 aBoneIds;

void main(void) {
    mat4 skinMat =
    uBones[aBoneIds[0]] * aWeights[0] +
    uBones[aBoneIds[1]] * aWeights[1] +
    uBones[aBoneIds[2]] * aWeights[2] +
    uBones[aBoneIds[3]] * aWeights[3];

    gl_Position = uModelViewProjection * skinMat * aPosition;
}

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

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

Я предполагаю, что я пропускаю шаг куда-то или делаю что-то в неправильном порядке. Я работал над множеством различных "учебных пособий" по этой теме, но им все довольно сложно следовать.(код повсюду с не самой лучшей документацией, и я не могу запустить ни одну из них, так как все примеры требуют разных языков / уже существующих фреймворков, или он просто сломан.)

Дополнительная информация:

  • Модель, которую я сейчас пытаюсь загрузить, представляет собой файл Collada (.dae).
  • Я использую привязки LWJGL для Assimp и OpenGL.

1 ответ

Решение

Я наконец понял проблему. Когда используешь ivec4 (или любой другой i префиксные типы данных) в качестве атрибутов в OpenGL Shaders, вы должны использовать glVertexAttribIPointer скорее, чем glVertexAttribPointer (Обратите внимание I). Если вы не укажете это, данные буфера будут отправлены в GPU как плавающие.

Другие вопросы по тегам