WebGL / GPU Skinning / Skeletal Animation

时间:2013-08-13 19:42:34

标签: animation opengl-es webgl collada skeletal-mesh

我很沮丧地接近在WebGL中使用骨架动画。

背景

我有model zombie walk animation我免费获得。我在一个Collada文件中下载了整个文件。我编写了一个解析器来获取所有顶点,法线,关节影响索引/权重和联合矩阵。我可以通过

来渲染角色的绑定姿势
joints[i].skinning_matrix = MatrixMultiply(joints[i].inverse_bind_pose_matrix, joints[i].world_matrix);

其中关节的世界矩阵是关节的bind_pose_matrix乘以其父级的世界矩阵。我做了inverse_bind_pose_matrix:

joints[i].inverse_bind_pose_matrix = MatrixInvert(joints[i].world_matrix);

所以真的,在绑定姿势中渲染角色只是将Identity矩阵传递给着色器,所以也许我甚至根本就没有这样做。但是,我计算的逆绑定姿势矩阵几乎与Collada文件提供的矩阵相同,所以我很确定它们是好的。

这是我绑定姿势的模型:

bind pose

问题

一旦我继续尝试使用动画的单帧计算蒙皮矩阵(我随机选择第10帧),它仍然类似于男人,但肯定是错误的。

我使用的是我在第一时间计算的相同的inverse_bind_pose_matrix。我正在使用一个新的世界矩阵,而是通过将每个关节的关键帧/动画矩阵乘以其父代的新世界矩阵来计算。

我没有在我的整个代码库中的任何位置进行任何转置,但我认为我已经尝试过几乎任何矩阵组合的转置都无济于事。

这是我的模型在他的动画框架10姿势:

anim pose

一些相关代码

顶点着色器:

attribute float aBoneIndex1;
// up to aBoneIndex5

attribute float aBoneWeight1;
// up to aBoneWeight5

uniform mat4 uBoneMatrices[52];

void main(void) {
  vec4 vertex = vec4(0.0, 0.0, 0.0, 0.0);
  vertex += aBoneWeight1 * vec4(uBoneMatrices[int(aBoneIndex1)] * aPosition);
  vertex += aBoneWeight2 * vec4(uBoneMatrices[int(aBoneIndex2)] * aPosition);
  vertex += aBoneWeight3 * vec4(uBoneMatrices[int(aBoneIndex3)] * aPosition);
  vertex += aBoneWeight4 * vec4(uBoneMatrices[int(aBoneIndex4)] * aPosition);
  vertex += aBoneWeight5 * vec4(uBoneMatrices[int(aBoneIndex5)] * aPosition);

  // normal/lighting part

  // the "/ 90.0" simply scales the model down, problem persists without it.
  gl_Position = uPMatrix * uMVMatrix * vec4(vertex.xyz / 90.0, 1.0);
}

您可以在GitHub上完整地看到我的解析器(如果您真的想要...),您可以看到模型直播here

0 个答案:

没有答案