我正在为一个低多边形3D人物模型旋转骨骼内的网格。在顶点着色器中应用如下。
glsl:
vec4 vert1 = (bone_matrix[index1]*vertex_in)*weight;
vec4 vert2 = (bone_matrix[index2]*vertex_in)*(1-weight);
gl_Position = vert1+vert2;
bone_matrix[index1]
是一个骨骼的矩阵,而 bone_matrix[index2]
是另一个骨骼的矩阵。 weight
指定了 vertex_in
对这些骨骼的成员身份。问题在于当应用旋转时权重越接近0.5, 肘部直径就会缩小得越多。我通过测试大约有10,000个顶点的圆柱体(具有梯度权重)来验证了这一点。结果看起来像是弯曲一个花园水管。
我从以下来源获得了我的加权方法。实际上这是我能找到的唯一方法:
http://www.opengl.org/wiki/Skeletal_Animation
http://ogldev.atspace.co.uk/www/tutorial38/tutorial38.html
http://blenderecia.orgfree.com/blender/skinning_proposal.pdf
左边是形状开始的样子,中间是上述方程旋转它的样子,右边是我的目标。中间点的权重为 0.5
。弯曲得越多,情况就会变得更糟糕,在180度时直径为零。
- 我尝试在着色器上组装矩阵,以便将权重应用于旋转而不是最终顶点。它看起来像右边图片中的完美效果,但需要为每个单独的顶点组装矩阵(代价高昂)
- 我研究过四元数,但是GLSL不支持它们(正确我如果我错了)并且它们很令人困惑。这是我需要做的吗?
- 我考虑每个关节使用三个骨骼,并在每个骨骼之间添加一个“膝盖”。这不能消除问题,但可以减轻问题。
- 我正在考虑在旋转后投影顶点到其距离轴线的原始距离。这在180度处会失败,但代价(相对)较小。
因此,考虑到选项或我可能没有考虑到的其他选项,其他人如何避免这种夹紧效应?
编辑:我已经通过使用四元数使 SLERP 工作,但我选择不使用它,因为GLSL不支持它。我无法像Tom所描述的那样让几何SLERP起作用。我在前90度中让NLERP起作用,所以我在每个关节之间添加了一个额外的“骨头”。因此,为了弯曲前臂40度,我将肘部和前臂各弯曲20度。这消除了夹紧效应,但代价是骨骼数量增加了一倍,这不是理想的解决方案。