逆绑定矩阵的正确映射是什么?

What is the correct mapping of inverse bind matrices?

glTF 文件为每个皮肤定义了一个逆绑定矩阵数组和一个关节列表。

假设关节列表是:

{2,5,7,4,3,6}

如果我们移动它以便索引从 0 开始,我们得到

{0,3,5,2,1,4}

在这种情况下 inverse_matrix[2] 可以指代两件事之一。它可以引用数组中的第二个关节,即关节5,也可以引用关节2。

这个完全相同的问题适用于权重数组。

换一种方式。如果一个人从 gltf 文件中获取数据并将缓冲区加载到着色器中。我需要弄清楚如何将着色器中的顶点索引映射到其对应的 4 个皮肤矩阵。

所以如果joints[2] maps to (3,1,0,0)

我需要知道我是否应该在 ibm[3]ibm[1]ibm[2]ibm[3] 处获取逆绑定矩阵(因为 [= =16=] 是 2).

我希望这不会造成混淆。

glTF 2.0 specification § Skins 说(强调我的)

Each skin is defined by the inverseBindMatrices property (which points to an accessor with IBM data), used to bring coordinates being skinned into the same space as each joint; and a joints array property that lists the nodes indices used as joints to animate the skin. The order of joints is defined in the skin.joints array and it must match the order of inverseBindMatrices data.

这直接回答了你的问题。我会在这里给出更详细的解释:

  • 有两个ID:节点ID和关节ID
  • 节点 ID:nodes 数组中节点的索引
  • 关节 ID:joints 数组中关节的索引
    • joints数组中的关节用节点ID指定;虽然关节 ID 不同
    "nodes" : [
        {                           // 0
            "name" : "Cave"
        },
        {                           // 1
            "name" : "TailBone",
        },
        // snipped for brievity
        {                           // 29
            "name" : "Root"
        }
    ],
    "skins" : [
        {
            "inverseBindMatrices" : 6,
            "joints" : [
                29,
                1,
            ]
        }
    ]

对于此.glTFinverseBindMatrix[0]将针对joint[0],此关节由节点29给出; inverseBindMatrix[1] 将用于 joint[1],此连接由节点 1 给出。

If we shift it so that the indices start at 0 we get

{0,3,5,2,1,4}

我认为这是不正确的。你为什么换班?您基本上只需要节点 ID 到骨骼 ID 之间的映射,直到您将 glTF 数据消化并加载到您自己的结构中(之后节点 ID 与骨骼 ID 不同)

Node   Bone
29      0
1       1

当您计算 skin 矩阵时,请确保您遵循 joints 数组的顺序。在上面的示例中,skin[0] 应该用于 joints[0] 即节点 29.