3d glTF'的含义;皮肤基质中的s逆(全局转换)

3d glTF'的含义;皮肤基质中的s逆(全局转换),3d,gltf,scenegraph,skeletal-animation,skeletal-mesh,3d,Gltf,Scenegraph,Skeletal Animation,Skeletal Mesh,我想用骨骼动画渲染网格。在设置动画之前,我只想使用动画的第一个关键帧渲染网格,即使用骨骼层次变换渲染网格。我忽略了glTF中的场景结构;我只是使用网格[0]来获取网格,使用蒙皮[0]来获取其骨架 据我所知,最终的蒙皮矩阵(作为制服馈送到顶点着色器)是经过计算的 for(骨骼中的骨骼){ bone.skin_-xform=反向(全局_-xform)*bone.global_-xform*bone.inv_-bind_-xform; } 当我完全这样做的时候,我看到我的模型是地面以下11.4(5.

我想用骨骼动画渲染网格。在设置动画之前,我只想使用动画的第一个关键帧渲染网格,即使用骨骼层次变换渲染网格。我忽略了glTF中的场景结构;我只是使用
网格[0]
来获取网格,使用
蒙皮[0]
来获取其骨架

据我所知,最终的
蒙皮
矩阵(作为制服馈送到顶点着色器)是经过计算的

for(骨骼中的骨骼){
bone.skin_-xform=反向(全局_-xform)*bone.global_-xform*bone.inv_-bind_-xform;
}
当我完全这样做的时候,我看到我的模型是地面以下11.4(5.7+5.7)个单位(Z=0的平面;世界上有+Z作为向上)。当我只渲染网格而不进行任何蒙皮时,即仅使用位置、法线和纹理坐标,它位于地面上。我还能够推断出为什么在剥皮时会发生这种情况

以下是gltf的相关部分

    "skins" : [
        {
            "inverseBindMatrices" : 6,
            "joints" : [
                0,
            ...
        }
    ],
    "nodes" : [
        {
            "name" : "Root",
            "rotation" : [
                0,
                0,
                1,
                0
            ],
            "translation" : [
                0,
                0,
                -5.709875583648682
            ]
        },
        {
            "mesh" : 0,
            "name" : "Body",
            "skin" : 0
        },
        {
            "children" : [
                0,
                1
            ],
            "name" : "Armature",
            "translation" : [
                0,
                0,
                5.709875583648682
            ]
        }
    ]
我读过glTF的,还有。虽然文档中根本没有提到这一点,但以下是教程和参考指南中关于
inverse(global\u xform)
的内容:

必须使用网格所附着节点的全局变换的逆变换变换顶点,因为此变换已使用模型视图矩阵完成,因此必须从蒙皮计算中取消

因此,
Body
的全局变换必须反转并使用。这将导致
translateZ(-5.7)
。Root已经有了一个
translateZ(-5.7)
的局部变换,所以我知道网格到地面的偏移量为-11.4。但是,如果我按原样使用
Body
的全局变换,而不使用反转,那么在上面的公式中就没有问题了

为什么参考指南要求我们反转根骨骼父骨骼的全局变换?我错过了什么?当我从Blender导入这个模型时,我注意到电枢对象上的变换确实是
translateZ(5.7)

你说的

我忽略了glTF中的场景结构;我只是使用网格[0]来获取网格和蒙皮[0]来获取其骨架

然而,(标准的相关部分)说(强调矿山)

顶点必须使用网格所附着节点的全局变换的逆变换进行变换,因为此变换已使用模型视图矩阵完成

因为您说您要从glTF中提升网格和骨架,而不需要场景结构
反转(全局变换)
。这是因为网格的
模型视图矩阵
对于
逆(全局变换)
没有非单位变换来抵消偏移。使用three.js可以很好地工作,因为它使用所有节点层次渲染整个场景,这与您的不同

然而,如果我使用身体的整体变换,没有反转,在上面的公式中没有问题

这是正确的用法,因为
Root
的全局变换是其所有父变换与
Root
的局部变换的串联

root.global_xform = armature.local_xform * body.local_xform * root.local_xform
根据您的评论,我看到电枢对象有一个非身份转换作为其位置。通常情况下,作为身份更好


这里有一个更详细的解释和计算。我们看到
根节点的局部变换为
TranslateZ(-5.7)
;它的父节点
电枢
节点的局部变换为
TranslateZ(5.7)
;他没有父母了。因此,
根的全局变换实际上是身份。以下是蒙皮顶点着色器中的方程式

point’ = P * V * Mesh *              Skin                  * point
point’ = P * V * Mesh * (InvMeshGlobal * Global * InvBind) * point
                  5.7 * (-5.7 * 5.7 * -5.7 * InvBind)
                  5.7 * (-5.7 * I * InvBind)
因此,只有在渲染整个场景层次时才需要
InvGlobalXform
(上面写为
InvMeshGlobal
),而您只需要获得网格及其骨架,忽略存在
mesh
skin
的节点之外的祖先节点。我可以想出两个解决办法

解决方案1
  • 出口前,确保网和电枢在搅拌器中应用了位置、旋转和刻度
  • Root
    及其父
    电枢
    局部变换都将成为标识,即Root的全局变换将是标识
  • 忽略
    Mesh
    InvMeshGlobal
    变换
  • 整个等式只需要
    InvBind
解决方案2
  • 存储根的祖先转换
  • 使用祖先变换得到根的适当全局变换;通常成为身份
  • 忽略
    Mesh
    InvMeshGlobal
    变换
  • 等式中需要
    Global
    InvBind

解决方案(1)仅在输入网格和骨架没有全局旋转或平移时有效;解决方案(2)在这里也适用。与解决方案(1)不同,解决方案(2)需要存储祖先变换。

这可能是因为(作为一名艺术家的我)工作流程不佳,电枢对象在Blender中不应进行翻译吗?当我选择电枢对象并应用位置并导出glTF时,一切正常。我还看到,
电枢
节点现在没有转换,即标识;它的工作原理与预期的一样。