I want to render a mesh with skeletal animation. Before animating, I want to just render the mesh with just the first keyframe of the animaton i.e. render mesh with the bone hierarchy transforms in place. I'm ignoring the scene structure in the glTF; I'm just using meshes[0]
to get the mesh and skins[0]
to get its skeleton.
I understand that the final skin
matrix, fed as uniforms to the vertex shader, is calculated
for (bone in bones) {
bone.skin_xform = inverse(global_xform) * bone.global_xform * bone.inv_bind_xform;
}
When I do exactly this I see that my model is 11.4 (5.7 + 5.7) units below ground (plane at Z = 0; world has +Z as up). When I render just the mesh without any skinning i.e. with only position, normal and texture coordinates it rests on the ground. I was also able to deduce why this happens when skinning.
Here's the relevant part of the 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
]
}
]
I've read glTF's documentation, tutorial and the reference guide (PDF). While the documentation doesn't speak about it at all, here's what the tutorial and reference guide had to say about inverse(global_xform)
:
The vertices have to be transformed with inverse of the global transform of the node that the mesh is attached to, because this transform is already done using the model-view-matrix, and thus has to be cancelled out from the skinning computation.
As per this, Body
's global transform has to be inverted and used. This results in translateZ(-5.7)
. Root already has a local transform of translateZ(-5.7)
, so I understand the -11.4 offset of the mesh into the ground. However, if I use Body
's global transform as-is, without inversion, in the above formula there're no issues.
Why does the reference guide ask us to invert the global transform of root bone's parent? What am I missing? When I imported this model from Blender, I noticed that the transform on the armature object was indeed translateZ(5.7)
.