opengl骨骼/关节动画公式

时间:2018-04-29 10:48:06

标签: opengl

我目前正致力于使用关节和顶点权重设置动画模型。我的问题不是特定于程序,而是基于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;

下面 在用于变换顶点的结构中的关节。它有两种类型的信息

invBind: - 此矩阵是全局/模型空间中关节的局部绑定变换的逆矩阵,用于将模型从模型空间转换为局部关节空间

全局: - 此矩阵用于将顶点从关节的局部空间转换为最终的全局/模型[或世界]空间

全球= parent_global_joint_transform * joint_local_bind_transform。 我已经从blender .dae文件中加载了我的模型,因此“joint_local_bind_transform”被转置然后使用

在ivec4中的jointIndices: - 是影响这个顶点的所有可能关节的列表

in vec4权重: - 是与影响此顶点的对应关节相关联的权重

我有一个16号这种关节的数组,因为我的模型中有很多关节

所以这些信息如何计算gl_Position?是否有更多需要作为制服或顶点属性加载的信息?对不起我的noobish问题,但许多教程没有给出直接的答案。

一个简单的顶点着色器代码答案会很好。谢谢

1 个答案:

答案 0 :(得分:1)

如果没有任何正确性保证,以下内容应适用于简单的线性混合蒙皮。如果不能直接使用,您应该能够理解正在发生的事情并相应地进行调整:

//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;

在循环中,您迭代所有有影响的骨骼。对于每个骨骼,您可以计算骨骼坐标系中的顶点位置,并根据当前帧中骨骼的方向将其转换回全局坐标系。最后,您只需将所有影响骨骼的结果混合在一起。

要减少传输到GPU的数据量,您还可以预先计算joint.global * joint.invBind