Skeletal Animation - dealing with a large number of bones

Started by
13 comments, last by rouncED 14 years ago
Suppose I want to implement a skeletal animation system that works on VS 2.0 hardware. Even if I store the bones as 3x4 matrices, I can only use about 75-80 bones, which is not always enough. I know two ways to get around this: 1) Split the mesh into several parts so that each part uses less bones. This increases the number of draw calls. 2) Store the bones as a rotation quaternion and a translation vector. Then each bone only needs 2 constant registers. This makes the vertex shader more expensive. Which is the better method? Are there other techniques? BTW, if I also wanted to support VS 1.1, would method 2 still be an option? Thanks in advance.
Advertisement
You could split the mesh incurring the draw calls but could reduce the number of verts that each bone influences to mitigate the extra costs. It would save number of constants needed to pass in and reduce the number of matrices each vert has to be multiplied against. 2 for most and 3 would be the maximum. You can actually split your mesh based on that criteria having a dedicated vertex shader based on number of influences.
www.ghostdogstudio.com4 out of 5 professional pirates prefer it over scurvy!
Quote:
2) Store the bones as a rotation quaternion and a translation vector. Then each bone only needs 2 constant registers. This makes the vertex shader more expensive.

This is the way to go in my opinion. Even if your target hardware is VS 2.0, it would scale better with newer and better hardware where pixel shaders and memory bandwidth are more important than "simple" vertex shader like skeletal animation.

Quote:
1) Split the mesh into several parts so that each part uses less bones. This increases the number of draw calls.

This would have a "bad" influence on the architecture of your game/engine, an unnecessary influence you will not need on newer hardware. The fastest is not always the better solution ;-)

Quote:
BTW, if I also wanted to support VS 1.1, would method 2 still be an option?

Counter question: will a character with more than 100 bones fits into a game which targets VS 1.1 hardware ? GeForce4 is one of the last cards which supports only VS 1.1, that was around 2002-2003.
I agree with all GhostDogStudio's suggestions. The only thing is that switching vertex shader between calls can be expensive.

Quote:Original post by Ashaman73
Quote:
2) Store the bones as a rotation quaternion and a translation vector. Then each bone only needs 2 constant registers. This makes the vertex shader more expensive.

This is the way to go in my opinion. Even if your target hardware is VS 2.0, it would scale better with newer and better hardware where pixel shaders and memory bandwidth are more important than "simple" vertex shader like skeletal animation.


Since he sais he's targeting VS 2.0 there's no point thinking what's best for other configurations. I don't think this is a good idea and I've never seen any reasonable game do this. Also, you may not realize, but there's hardware like PS3 with terrible vertex shader performance even though it supports SM 3.0.

Quote:Original post by Ashaman73
Quote:
1) Split the mesh into several parts so that each part uses less bones. This increases the number of draw calls.

This would have a "bad" influence on the architecture of your game/engine, an unnecessary influence you will not need on newer hardware. The fastest is not always the better solution ;-)


"The fastest is not always the better solution" - from player's point of view it always is :)

There's many game developers who - for PC - still target SM 2.0 or even 1.1 because there's lots of customers who have that hardware. What's the point of having "great engine architecture" if that makes it useless in reality? Also, if you support mesh splitting it's going to work on SM 2.0 and 3.0 as well.

Matrix palletization is another thing you may want to look at.
Maciej Sawitus
my blog | my games
what on earth are you going to do with 80 bones in one draw call?
Quote:Original post by bzroom
what on earth are you going to do with 80 bones in one draw call?


I'm not sure what you mean. What does the number of draw calls has to do with it?

And thanks everyone for their replies so far, I will take them into consideration.
Well i assume the limit is only an issue because you're trying to use them all at once. What kind of mesh has > 80 bones that couldn't be broken up into groups with <= 80 bones each?
Quote:Original post by bzroom
Well i assume the limit is only an issue because you're trying to use them all at once. What kind of mesh has > 80 bones that couldn't be broken up into groups with > 80 bones each?


Yes, it can be broken up, that's what I said in method 1. The problem is that this increases the number of draw calls because you have to draw each part separately.

If you could somehow avoid splitting the mesh (for example, using method 2), you would need only one draw call.

On the other hand, method 2 makes the vertex shader more expensive (since you have to convert the quaternion + vector to a matrix), so I'm asking if that's a good trade-off.

Another advantage method 2 has is that it's easier to implement and use (I think - at least, dealing with the bone combination table in D3DX was a bit of a pain).
My overlying question is, what's the point? Do you really have a model with 80 bones that you can't figure out how to split into multiple draw calls at the artist level?

Quote:Original post by Gage64
Yes, it can be broken up, that's what I said in method 1. The problem is that this increases the number of draw calls because you have to draw each part separately.

If you could somehow avoid splitting the mesh (for example, using method 2), you would need only one draw call.


This doesnt sound like such a bad thing. You could skip some of the draw calls entirely saving a ton of bone uploading and transforming for something not even on screen.

And if you use one draw call you have a bone limit. Maybe you could spare another draw call? Or you could chop out 60 bones.

Quote:Original post by Gage64
What does the number of draw calls has to do with it? .
Quote:Original post by Gage64
On the other hand, method 2 makes the vertex shader more expensive (since you have to convert the quaternion + vector to a matrix), so I'm asking if that's a good trade-off.


You don't need to convert the quaternion into a matrix before applying the transform, just rotate the vertex directly by the quaternion, then add the position vector. Yes, it is still more expensive than preloaded matrices, but has other benefits like fewer draw calls or lower register usage.

You said, that you want it to work on VS2.0 hardware, but is it your fixed target hardware or should it just work on it for legacy support reasons ?

Sry, but it is just my opinion that cleaner and simpler (shader-)code leads to better and more robust games/software. Even if option 2 results in lower FPS on "legacy"(?) hardware, it will scale much better on newer hardware and the performance hit will eventually be negligible :-)

This topic is closed to new replies.

Advertisement