Я работаю над ASSIMP скелетная анимация загрузчик и рендерер, и сейчас все данные правильно загружены и интерполированы в текущем таймфрейме. Однако есть еще одна часть, которая работает не так, как должна, и это этап вершинного шейдера.
Через ВБО Я прохожу в два vec4
s, которые содержат идентификаторы костей и веса для каждой вершины (максимум до 4 костей / веса на вершину), и вершинный шейдер имеет матричный массив 100 преобразования костей (предварительно рассчитанные на кадр), которые индексируются с помощью идентификаторов костей.
Однако, похоже, что униформа костей не содержит надлежащих преобразований. В целях отладки я покрасил модель значениями веса и значения идентификаторов костей, и они содержат цвет (и, следовательно, допустимые значения). Однако, когда я преобразовываю свою вершину с помощью преобразования кости и окрашиваю модель в результате, вся модель окрашивается в черный цвет, то есть все матрицы преобразования 0.0
, Так что они не инициализированы должным образом.
Я думаю, что проблема заключается в передаче матриц в единый массив, или, возможно, максимальный размер разрешено униформ (я также пытался установить число унифицированных матриц на 32 (количество костей в текущей модели), но безрезультатно)?
Перед передачей информации в шейдер, матрицы преобразования действительно являются действительными матрицами (не единичными / пустыми матрицами), поэтому ошибка, вероятно, должна быть в шейдере GLSL или прохождении униформ.
Следующий код взят из вершинного шейдера:
#version 330
layout (location = 0) in vec3 position;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec3 tangent;
layout(location = 3) in vec3 color;
layout(location = 4) in vec2 texCoord;
layout(location = 5) in ivec4 boneIDs;
layout(location = 6) in vec4 weights;
uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;
uniform mat4 bones[100];
out vec2 TexCoord;
out vec4 colorz;
void main()
{
vec4 newPos = vec4(position, 1.0);
colorz = vec4(0.0, 1.0, 0.0, 1.0);
if (weights != vec4(0.0, 0.0, 0.0, 0.0))
{
mat4 boneTransform = bones[boneIDs[0]] * weights[0];
boneTransform += bones[boneIDs[1]] * weights[1];
boneTransform += bones[boneIDs[2]] * weights[2];
boneTransform += bones[boneIDs[3]] * weights[3];
// newPos = boneTransform * vec4(position, 1.0);
vec4 test = vec4(1.0);
colorz = boneTransform * test;
// newPos = boneTransform * newPos;
}
TexCoord = texCoord;
gl_Position = projection * view * model * newPos;
}
Следующий фрагмент кода передает данные матрицы в шейдер GLSL:
// Sets bone transformation matrices
void Shader::SetBoneMatrix(GLint index, aiMatrix4x4 matrix)
{
glm::mat4 mat = glm::transpose(glm::make_mat4(&matrix.a1));
glUniformMatrix3fv(boneLocations[index], 1, GL_FALSE, glm::value_ptr(mat));
}
Также код, который получает все одинаковые расположения массива костей:
for(unsigned int i = 0; i < 100; i++)
{
string name = "bones[";
string number;
stringstream ss;
ss << i;
ss >> number;
name += number;
name += ']';
boneLocations[i] = glGetUniformLocation(this->program, name.c_str());
}
Хорошо, через glslDevil я столкнулся с непрерывным GL_INVALID_OPERATION
ошибка при установке костного матрикса в шейдер через glUniformMatrix
, Истоки проблемы действительно были на этапе, когда программа передает информацию шейдеру.
Это довольно глупая ошибка на самом деле, так как я использую glUniformMatrix3f
вместо glUniformMatrix4f
, Изменение этого действительно решило проблему, и анимации работают отлично прямо сейчас.
Других решений пока нет …