PDA

View Full Version : DualQuaternion skeletal animation



Ilian Dinev
09-25-2009, 12:01 PM
I recently found-out about dual-quats, and refactored my matrix-lerp shader code for skinmeshes to use DQs instead. It works great, and I refactored the whole animation-mixer to be using DQs. Some questions arise, though:

Most engines use quat-slerp, but I'd rather not use several thousand trigonometry-instructions per mixed anim. Meanwhile, DualQuats are really fast, but I don't see anyone using them much, yet. Specifically the ability to weighted-accumulate ( DQuat1+= DQ2*0.3) looks under-utilized.
=> Is there something one should avoid about DQs ?

My current code computes the final local-space bones via DQs, then converts each DQ to Mat4, then appends those Mat4 for the hierarchy, multiplies by the inverse Mat4 of the bind-pose, and finally converts the resulting Mat4s to an array of DQs to be used in the shader.
=> Is there a way to do the hierarchy-transforms only via DQs, instead of temporarily converting to Mat4 ?

P.S. as it stands, with DQs I can mix a bunch of anims without using even one trigonometry func! (or whatever other instruction that can take more than 10+ cycles)

Alfonse Reinheart
09-25-2009, 02:42 PM
Dual Quaternion is something you use when rendering a mesh, not when computing the matrices themselves. In other words, you should do "matrix-lerp" stuff in your animation code, then convert the matrices into dual quaternions before you upload it to your shader.

Ilian Dinev
09-25-2009, 03:03 PM
But the matrix-lerp way looks horrible in comparison. (of course, as the rotation part is no longer valid)

remdul
09-26-2009, 07:31 AM
I think what Alfonse means is that it is the vertex deformation that causes the warping (e.g. shoulder joints for humanoids). It shouldn't matter how you deform the skeleton, and thus whatever bone transforms you pass to the vertex shader (quaternions or matrices). What matters is how you deform the mesh, that's where you want to apply your dual-quaternion voodoo...

Disclaimer: I know very little about dual-quaternions.

Ilian Dinev
09-26-2009, 11:00 AM
That was the first thing I was doing, of course. I understood what he meant.
I also thought DQs are usable only for rendering - that's what the NV article did, after all, and everyone used quat slerps on the cpu for the anim-blend, but they're too slow for my purposes. Matrix lerps are all fine and dandy for anims that are not too different, or the recycle-bin (I didn't try normalizing their 3x3 part).
But like any transformation object, DQs are not limited to rendering. Implemented them quickly in my anim-mixer, found the importance of changing polarities on negative dot-product when accumulating, kept DQs in the shader, too - and it all just worked flawlessly. Thus, I wanted to know if it's too good to be true.

remdul
09-26-2009, 11:41 AM
Apologies, I misunderstood your post.

I guess matrices and regular quaternions are simply more widely known and no one bothered to try it?

But hey, if it works for you... :) I'd be interested to hear about your findings, have to touch animation blending sooner or later myself.

PS: For the interested: http://developer.download.nvidia.com/SDK...ionSkinning.pdf (http://developer.download.nvidia.com/SDK/10.5/direct3d/Source/QuaternionSkinning/doc/QuaternionSkinning.pdf)
And the original research paper (with nice example pics): http://isg.cs.tcd.ie/projects/DualQuaternions/

Ilian Dinev
09-26-2009, 12:24 PM
I started from those two samples, too.
Notice the shader-code in the latter:
if (dot(dq0[0], dq1[0]) < 0.0) dq1 *= -1.0;
This is must-have. Simply animations that are too different from each other will go haywire when blended otherwise.
Also, Kavan's code has the quaternions in wxyz layout in memory (old fashion).

DmitryM
10-01-2009, 09:39 AM
I've implemented support for Dual Quaternions in my skinning code on both CPU & GPU side (CPU for interpolating between joint keyframes, GPU for blending weighted transformations per vertex).

Quality: don't see much difference from linear position+rotation interpolation... but this might be revealed later when I have more animations to play with.

Performance: nearly the same, or maybe a little bit faster.

Conclusion: will stay with DQ until problems arise.

Ilian Dinev
10-01-2009, 10:54 AM
Try blending 3 animations in any ratio:
a) ballet + movement around (have the torso rotate around Y, too)
b) running
c) standing

;)

I was checking the quality with a 45k-triangle character, where I took great care on the skinning.

DmitryM
10-01-2009, 11:10 AM
I wonder, where do you get this high-poly characters with skin animations?

It would be nice to see some pictures showing the difference in your app.

Ilian Dinev
10-01-2009, 11:34 AM
Well, low-poly stuff from the net, or modeling them myself, then sculpting them (this produces the many polys), then rigging, and exporting with custom tools.
Just get Blender, fetch some base character-mesh from public-domain (base meshes require extreme experience+skill to make without nasty triangles T_T), sculpt it to take a desired form, texture-paint it, rig, and import free .bvh anims or make manual animation via rotoscopy.


The difference wasn't big when the blended anims were similar or constrained to 1-2 axes. But on a ballet.bvh + any other anim, during some complex frames the fingers would show how bad the rotation-parts of matrices have become :) : the fingers would turn into a triangle-soup.
There is some slight chance that my matrix-lerp code was imperfect, but general Maths hints that that tri-soup was inevitable. Anyway, the DQ anim-mixer is faster, more flexible and definitely would trump any matrix-lerp at visual quality (unless there's a pitfall that I haven't seen even after my extensive tests).