使用ASSIMP和GLSL的骨骼动画:骨均匀阵列大小

时间:2013-12-27 15:43:03

标签: c++ opengl glsl skeletal-animation

我正在研究ASSIMP 骨架动画加载器和渲染器,现在所有数据都在当前时间帧内正确加载和插值。但是,仍有一部分不能正常工作,那就是顶点着色器阶段。

通过 VBO 我传入两个vec4 s,其中包含骨骼ID和每个顶点的权重(最多 4 骨骼/每个顶点的权重)和顶点着色器有一个 100 骨骼变换的矩阵数组(每帧预先计算),它们通过骨骼ID索引。

然而,似乎骨头均匀不包含适当的变形。出于调试目的,我使用权重值和骨骼ID值为模型着色,它们包含颜色(因此也是有效值)。但是,当我通过骨骼变换转换顶点并使用结果为模型着色时,整个模型将显示为黑色,这意味着转换矩阵都是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());
}

1 个答案:

答案 0 :(得分:1)

Oké,通过glslDevil,我通过GL_INVALID_OPERATION将骨骼矩阵设置到着色器时遇到了连续的glUniformMatrix错误。问题的根源确实在程序将信息传递到着色器的阶段。

实际上这是一个非常愚蠢的错误,因为我使用的是glUniformMatrix3f而不是glUniformMatrix4f。改变这确实解决了问题,动画现在正在完美地运作。