我在实现双四元数蒙皮时遇到问题。我还在学习这个主题,所以目前我正在从骨骼矩阵转换为双四元数 CPU 端,然后再转换回着色器中的矩阵。
转换显然适用于单个骨骼,但如果我尝试在双四元数之间线性混合,我会得到这个工件:http: //imagizer.imageshack.us/a/img838/8671/nun.gif 我不知道这是什么原因造成的。也许这与我如何规范化对偶四元数有关,也许与我如何从对偶四元数转换为矩阵有关。我试过搜索实际的双四元数代码,但我发现的只是一堆难以阅读的数学定义。
我包含了一些着色器代码,因为我很确定这就是问题所在。希望精通四元数数学的人可以看穿它!
混合双四元数。Boneweight2 = (1.0 - boneweight1),所以它们总和为 1。
vec4 blendReal = boneReal[bone1] * boneWeight1 + boneReal[bone2] * boneWeight2;
vec4 blendDual = boneDual[bone1] * boneWeight1 + boneDual[bone2] * boneWeight2;
float blend_norm_real = length(blendReal);
blendReal /= blend_norm_real;
blendDual /= blend_norm_real;
从对偶四元数创建矩阵:
mat4 MatFromDualQuat(vec4 rq, vec4 dq)
{
//Source: Section 3.4 http://www.seas.upenn.edu/~ladislav/papers/sdq-i3d07/sdq-i3d07.pdf
//rq = real quaternion
//dq = dual quaternion
mat4 M;
M[0][0] = 1.0 - 2.0 * (rq.y * rq.y + rq.z * rq.z); //
M[1][0] = 2.0 * (rq.x * rq.y + rq.w * rq.z);//
M[2][0] = 2.0 * (rq.w * rq.y - rq.x * rq.z);//
M[3][0] = 0.0;
M[0][1] = 2.0 * (rq.x * rq.y - rq.w * rq.z);
M[1][1] = 1.0 - 2.0 * (rq.x * rq.x + rq.z * rq.z);
M[2][1] = 2.0 * (rq.y * rq.z + rq.w * rq.x);
M[3][1] = 0.0;
M[0][2] = - 2.0 * (rq.x * rq.z + rq.w * rq.y);
M[1][2] = 2.0 * (rq.y * rq.z - rq.w * rq.x);
M[2][2] = 1.0 - 2.0 * (rq.x * rq.x + rq.y * rq.y);
M[3][2] = 0.0;
M[0][3] = 2.0 * (-dq.w * rq.x + dq.x * rq.w + dq.z * rq.y - dq.y * rq.z);
M[1][3] = 2.0 * (-dq.w * rq.y + dq.y * rq.w + dq.x * rq.z - dq.z * rq.x);
M[2][3] = 2.0 * (-dq.w * rq.z + dq.z * rq.w + dq.y * rq.x - dq.x * rq.y);
M[3][3] = 1.0;
return M;
}
然后我将它与绑定姿势顶点位置相乘。