微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

理解glTF联合矩阵

如何解决理解glTF联合矩阵

我阅读了 glTF 的 github tutorial 中的 Skins 部分,但未能理解 jointMatrix 的工作原理。

在教程中,它被定义为

jointMatrix(j) =
  globalTransformOfNodeThatTheMeshIsAttachedTo^-1 *
  globalTransformOfJointNode(j) *
  inverseBindMatrixForJoint(j);

我对 globalTransform 和取消感到困惑。在我看来,jointMatrix 就像

jointMatrix(j) =
  jointSpacetoModelSpace(j) *
  jointTransform(j) *
  modelSpacetoJointSpace(j);

在顶点着色器中

// assume 'joint' is a matrix computed from weighted aggregation of all jointMatrix(j)
vertex_world_space = model-view-proj * joint * vertex_model_space;

我的问题是

  • 为什么 jointMatrix 是这样定义的?
  • 我的版本有什么问题?

解决方法

要记住的一件事是顶点着色器在蒙皮网格节点的上下文中执行,而不是在骨架根或关节。这意味着模型视图矩阵可能处于“无意义”的位置:这个蒙皮节点可能已经进行了转换,但它不会受到影响,因为它的所有顶点都由关节控制。如果皮肤节点不是根节点,glTF 验证器甚至会发出警告,因为这个原因,应用到皮肤本身的变换是无操作的。

因此,皮肤中任何特定顶点所需的步骤是:

  1. 撤消皮肤的世界到节点转换(如果有)。
  2. 应用关节的世界到关节转换。
  3. 撤消关节的“静止”位置。

这三个步骤对应于您在教程中列出的三个步骤。

让我们谈谈第三个。每个关节都有一个“休息”位置。例如,手臂骨骼可能静止在皮肤原始形状(绑定姿势)的左臂中,而腿部骨骼可能位于右腿中。这些骨骼不在原点,它们散布在模型周围。但是我们不希望它们在处于静止位置时拉动顶点,例如手臂骨骼可能在原点的上方和左侧,但在静止时不应向上和向左拉动任何顶点。

所以每个关节都有一个“逆绑定矩阵”,它可以消除关节在其自身静止位置自然产生的影响。当关节移动时,它会相对于其自身的静止位置移动,而该增量(第 2 步和第 3 步之间的差异)将应用于目标顶点。

如果皮肤本身尝试移动,则什么也不会发生。在教程的着色器结束时将这种变换应用于 u_modelViewMatrix,并且在步骤 1 中应用该变换的逆变换,因此它们相互抵消。如果您想移动整个蒙皮网格,当然正确的方法是重新定位整个骨架,而不是蒙皮节点。移动根关节将对网格中的所有顶点应用步骤 2 中的新变换。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。