Increasing the Bone Count

Jul 22, 2008 at 6:49 AM

My project has characters with more than 80 bones, but version 0.7.0.0 only supports 80.

Is this a hard limit or is it possible to increase it by recompiling the source?

The bone count limit of 80 is embedded in SkinnedModelEffect.fx.  Do I need to convert the binary generated from this file into a c# structure to be used in SkinnedModelBasicEffectCode.cs?  If so, do you have any recommendations on a good way to do this?

Thanks!

---Xeno (http://www.xenocollide.com)

Jul 22, 2008 at 7:08 AM
I think I may have found the answer to my question, but I'd like to verify...

In the XNA help file, under the Effect() constructor that takes compiled code in the form of a byte array, it says this:

Obtaining the compiled byte code for effectCode is a two-part process. First, you must compile the effect by using the static method Effect.CompileEffectFromFile or Effect.CompileEffectFromSource, either of which returns an instance of CompiledEffect. CompiledEffect.GetEffectCode returns the compiled byte code from the compiled effect.

Is this the proper way to obtain the compiled byte code?

---Xeno (http://www.xenocollide.com)
Jul 22, 2008 at 7:57 AM
Ok -- I may be missing something else.

I replaced the code to initialize the SkinnedModelBasicEffect with a version that compiles it on-the-fly:

        public SkinnedModelBasicEffect(GraphicsDevice graphicsDevice, EffectPool effectPool)
            : base(graphicsDevice, Effect.CompileEffectFromFile("SkinnedModelEffect.fx", null, null, new CompilerOptions(), TargetPlatform.Windows).GetEffectCode(), CompilerOptions.None, effectPool)
        {
            // ...
        }

This works when the maximum bone count is set to 80 or below in SkinnedModelEffect.fx and SkinnedModelBasicEffect.cs.cs.  However, if I try to raise both constants to 85, I get an exception saying that I need to set a valid effect before drawing mesh.  Did I miss another constant that needs to be changed, or have I hit a hard limit of some kind?

---Gary
Coordinator
Jul 22, 2008 at 6:10 PM
Hi. Sorry for the late reply. You currently cannot handle characters with more than 80 bones, and it is a hardware (GPU) limitation! The vertex shader that is used to animate the model's mesh has a fixed number of constant registers that are used to store the bones data, and 80 is the maximum number of bones that you will be able to handle with it.

If you need to handle more than 80 bones in a single mesh you will need to do software skinning, which is currently not supported.  But keep in mind that 80 is a big number of bones, many games uses models with less than 30 bones.
Jul 22, 2008 at 11:07 PM
Thanks for the response, Bruno!

I was worried that would be the case.  A better solution than software skinning would be to carve up the mesh into smaller pieces that each uses fewer than 80 influencers and then use hardware skinning with a different matrix set on each section of mesh.

Although 80 seems like a lot, the important characters in most mainstream games are far beyond that now.  The human characters in the mainstream games I'm working on average around 150.  I'll need fewer for XNA games, but to get decent hair and facial animation, I still may need to push 90-95 bones in some cases.

Thanks again for the fantastic animation library!

---Xeno (http://www.xenocollide.com)
Coordinator
Jul 23, 2008 at 3:22 PM
Edited Jul 23, 2008 at 3:22 PM
Hi. Yeah, splitting the mesh might be a better solution. I know shader model 4 supports a a big number of constant registers, but unfortunately, XNA only supports DirectX 9.
If you need a big number of bones for facial animation and hair you could also try morphing it might be faster. In the further I might support morphing on XNAnimation.

Thanks! =D
Aug 3, 2008 at 6:26 PM
Edited Aug 4, 2008 at 3:38 AM
Well,thank you the reply.
I found the MeshSplitter.cs in XNA Animation Component Library.May be it could do it?
Maybe XNAnimation will support meshsplit?
Coordinator
Aug 4, 2008 at 3:41 PM
Hi Robin. I will check this mesh splitter, I didn't know about it. In the future I will implement software skinning on XNAnimation, it appears a better approach for me to handle big skeletons.
Aug 13, 2008 at 5:16 PM
The logic required to achieve mesh-splitting is really convoluted and hard to follow. I tried going through the code in the XNA Animation Component, but I couldn't break through the mesh-splitting code.

One of the best things about your library, Brad, is that it's a straight-forward code base. It's a great teaching tool for developing 3D animation systems. I would be saddened to see its code get convoluted by introducing mesh-splitting. Just adding that functionality alone would keep code from being a good learning tool.

I don't have a useful opinion as to what you should do. But I wanted to point out what I think you'd be losing in order to gain mesh-splitting as a feature.
Coordinator
Aug 14, 2008 at 8:06 PM
Hi. Sorry for the late reply. I will look for further solutions for skinning characters with a long number of bones. My thought about it is that you should use less than 80 bones on old cards (SM 2~3) and any number of bones that you want on recent hardware (SM 4).

Other possible options would be software skinning that I'm planning to implement in the further, or GPU skinning using textures. GPU skinning with textures might be slow and will require SM3 but you will be able to use many bones!