OpenGL : Bone Animation, Why Do I Need Inverse of Bind Pose When Working with GPU?
Asked Answered
G

2

15

I implemented an MD5 Loader with software skinning. Bind pose in md5 is final, absolute position and rotations, you just need to do computations for weights which are joint dependent.

I tried to implement GPU skinning but i am stuck at a point. Since these coordinates are final, why can't i just convert my 3d vectors and quaternions into a matrix and just upload it to the shader ? As I have read here : http://3dgep.com/?p=1356 , i need to multiply my skeleton with inverse of the bind pose. But I don't understand this part because I always thought that only thing I need to do is upload the final matrices to the GPU and calculate the rest there (sum of weights etc. etc.)

Can you explain me the behavior of inverse bind pose ?

Gametogenesis answered 15/6, 2013 at 21:20 Comment(0)
P
27

As the original author of that article, I will try to explain what multiplying by the inverse bind pose does:

The "inverse bind pose" basically "undoes" any transformation that has already been applied to your model in its bind pose.

Consider it like this: If you apply the identity matrix to every joint in the model then what you will get is your model in the bind pose (you can try this by sending a skeleton frame filled with identity matrices. If what results is the bind pose, then you are doing it right).

If you apply the bind pose matrices (uninverted) to every joint in the model then what you will get is spaghetti because you would be applying the bind pose twice!

So to fix the spaghetti model, you simply multiply the resulting joint transformations by the inverse bind pose to "undo" the transformation that have already been applied to your model.

I hope this clears it up a bit...

Placentation answered 30/9, 2013 at 19:37 Comment(0)
E
11

Honestly, the article is a bit much to completely work through. It seems that the inverse bind pose matrices are used to transform vertices to the bones' local coordinate systems.

This is necessary, because the bones' transformations are local (relative to their parent joints). So in order to animate a vertex, you have to transform it to a bone's local coordinate system, calculate the bone's local transforms and transform it back to the world system.

Elliott answered 16/6, 2013 at 9:8 Comment(8)
In that time, i think i understood the idea behind. We already upload the vertices of bind pose, all i need to transform them and according to the current skeleton. Since all of my vertices are already in world space, i need to convert my new skeleton's absolute matrices to joint space because i need the offset, then multiply the result with my vertices, lastly multiply with modelview matrix.Gametogenesis
Hi, I have a question for performance reason. Why not pre-multiply the vertices with the inverse of the bind pose. Then the bone matrices can directly be the local2world for skinning. So there is no need to multiply the inverse bind pose each frame?Idyllic
@watson: This is possible if every vertex is influenced by exactly one bone. If there are multiple bones (e.g., around joints), this will not work anymore because the inverse bind pose matrix is specific for every bone.Elliott
Thanks, you are right. 4 matrices transform a vertex by weight is not linear function(I am not sure?). So I pre-transform inverse bind pose matrix by weight at load time is not correct.Idyllic
One more question: I store the delta matrices(The bone world matrix * inverse bind pose), or the delta (offset, quaternion, scale) as the animation key frame. So I can avoid multiply the inverse bind pose every frame?Idyllic
@Idyllic The latter is usually preferred because animating rotations between the key frames is more realistic. If you just have a single matrix, blending the matrix will cut through the shortest path and may introduce undesired scaling.Elliott
@NicoSchertler If I store the bone (Local2World * InverseBindPose) in (offset, quaternion, scale) form as keyframe data to avoid multiply the InverseBindPose in each frame. I think it good for performance. But most tutorial and game engine is not implement in this way.(For example Unity3D: docs.unity3d.com/ScriptReference/Mesh-bindposes.html) There must be some reason, to calculation animation in local space the multiply the InverseBindPose each frame.Idyllic
Even if some bone controlled by IK, I can only masked and multiply the InverseBindPose only for that bones, but to multiply the InverseBindPose for all my skeleton bones. Only if I store 'delta' values in my animation channel.Idyllic

© 2022 - 2024 — McMap. All rights reserved.