Optimizing skeletal animations with Maya

The place for artists, modellers, level designers et al to discuss their approaches for creating content for OGRE.
Post Reply
User avatar
HexiDave
OGRE Expert User
OGRE Expert User
Posts: 1538
Joined: Sat Jan 14, 2006 8:00 pm
x 1

Optimizing skeletal animations with Maya

Post by HexiDave »

I'm still not 100% sure what is causing the slowdown with my animations, but I'd assume it's due to an un-optimized mesh (weighted skin problems.)

Has anyone got any advice for optimizing meshes/animations in Maya specifically related to the OGRE slow-downs? I can watch 1 animation at 300fps, then 2 at ~180 and it gradually slows down to about 40-50 fps in full view of the SkeletalAnimation demo. If you've got any sites that explain techniques or just simple tips I'd really appriciate it. I'm also aware of Hardware skinning but that seems like it's not applicable with complex animations (correct me if I'm wrong - I haven't begun to mess with Shader technology yet.)

I'm not on par with the great masters of programming and animation, but I'm trying :lol:
User avatar
xavier
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 9481
Joined: Fri Feb 18, 2005 2:03 am
Location: Dublin, CA, US
x 22

Post by xavier »

Is your mesh in a single piece, or multiple? How many vertices? If you do not add the shader pass in your material script you are using software skinning (the demo tells you what is being used) and you will notice a slowdown very quickly for anything of any complexity.
User avatar
HexiDave
OGRE Expert User
OGRE Expert User
Posts: 1538
Joined: Sat Jan 14, 2006 8:00 pm
x 1

Post by HexiDave »

The mesh has 11 pieces and 1681 verts and yes, it does display Software Skinning - I'm not sure how to work with Shader passes yet and how they coincide with what I'm doing. Do any of the Sample meshes/materials do what you say? If so, could you point me to one that does what a hardware pass?

The main issue I'm having here is that I don't know what I would be having the pass for - does a shader automatically make use of the hardware since I tell it to run the texturing through a shader pass rather than just let it keep the Maya Exporter defaults?
User avatar
xavier
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 9481
Joined: Fri Feb 18, 2005 2:03 am
Location: Dublin, CA, US
x 22

Post by xavier »

The 11 pieces is going to multiply, obviously -- when you get to 10 models, that's 110 individual meshes on the screen (and 110 different rendering batches just for the models). If you fuse each model into a single mesh (either before or after exporting) you would obviously only have 10.

One thing we've done is for models that are exported as multiple bits, I run the XML files through a script that fuses them back into one mesh and updates the vertex indexes, etc. You can do this using the HardwareVertexBuffer stuff but it was simpler for me to do it in PHP. ;)

The hardware skinning pass tells Ogre to pass the bone matrices onto the GPU where the vertex shader does the transformation of the vertices based on the bone positions. You can do this out of the box via the sample shader with any skeletally animated mesh that uses fewer than 24 bones (vs1.1 limitation -- you can edit the shader and profile if you need more). Simply take your fixed-function material file and do something like this:

Code: Select all

vertex_program HardwareSkinningOneWeight cg
{
	source skinning.cg
	entry_point hardwareSkinningOneWeight_vp
	includes_skeletal_animation true
	profiles vs_1_1 arbvp1
}

vertex_program HardwareSkinningOneWeightShadowCaster cg
{
	source skinning.cg
	entry_point hardwareSkinningOneWeightCaster_vp
	includes_skeletal_animation true
	profiles vs_1_1 arbvp1
}

material Space_Panels
{
	// Hardware skinning technique
	technique
	{
		pass
		{
			vertex_program_ref HardwareSkinningOneWeight
			{
				param_named_auto worldMatrix3x4Array[0] world_matrix_array_3x4
				param_named_auto viewProjectionMatrix viewproj_matrix
				param_named_auto lightPos[0] light_position 0
				param_named_auto lightPos[1] light_position 1
				param_named_auto lightDiffuseColour[0] light_diffuse_colour 0
				param_named_auto lightDiffuseColour[1] light_diffuse_colour 1
				param_named_auto ambient ambient_light_colour
			
			}
			// alternate shadow caster program
			shadow_caster_vertex_program_ref HardwareSkinningOneWeightShadowCaster
			{
				param_named_auto worldMatrix3x4Array[0] world_matrix_array_3x4
				param_named_auto viewProjectionMatrix viewproj_matrix
				param_named_auto ambient ambient_light_colour
			
			}
			
			texture_unit
			{
                    texture fx3_Panels_9F.jpg 
			}
		}
	}

	// Software blending technique
	technique
	{
        pass
        {
            ambient 0.0 0.0 0.0
            diffuse 0.4 0.4 0.4
            specular 0.9 0.9 0.9 10000.0
            emissive 0.0 0.0 0.0
            texture_unit
            {
                texture fx3_Panels_9F.jpg 
            }
        }
	}
}

This script includes the reference to the single-weight program located in the skinning.cg file (which is in the sample media folder). The line "includes_skeletal_animation true" tells Ogre that you want to use this program to do hardware skinning. I copied the vertex program references at the top from one of the sample material script files (I forget which one). The pass at the bottom, the software fallback, is what you have in your material script now.
User avatar
xavier
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 9481
Joined: Fri Feb 18, 2005 2:03 am
Location: Dublin, CA, US
x 22

Post by xavier »

One mistake...skinning.cg is a filename we're using; you'll find the skinning programs in Samples\Media\materials\programs\Example_Basic.cg.
User avatar
HexiDave
OGRE Expert User
OGRE Expert User
Posts: 1538
Joined: Sat Jan 14, 2006 8:00 pm
x 1

Post by HexiDave »

That does make a lot of sense - one problem for me is that I need the mesh in seperate pieces as the body parts get switched around for different pieces of armor. I'll look into having enumerated meshes (with gloves, bicep and bracer, one with gloves, bracer and no bicep, one with no armor, etc.)

The other thing is that my model has more than 24 bones currently, but from the way that material looks I could have those passes for each material already defined on the mesh or does the 24 bone limit encompass the whole material file (does the 24 bone limit mean for each weighted sub-mesh - like the gloves - or 24 bones in the entire skeleton for the whole body?)

Say for instance the hand has:

2 Joints for the Thumb
2 Joints for the Index finger
2 Joints for the rest
1 Joint that is the parent for the 6

For a total of 7 joints (6 bones.) The only thing those 7 joints are weighted to are the gloves sub-mesh (I'm considering each body part a sub-mesh and the entire suit of armor as the mesh) - would that count towards the 24 total for just the gloves sub-mesh or every sub-mesh in the whole suit of armor?
User avatar
HexiDave
OGRE Expert User
OGRE Expert User
Posts: 1538
Joined: Sat Jan 14, 2006 8:00 pm
x 1

Post by HexiDave »

Oh, I just noticed you mention the HardwareVertexBuffer for fusing meshes - that'd actually be a fine solution to my problem - are there any API calls off the top of your head that I should start with or should I just brush up on the Manual? :D

Thanks for the help, by the way, this is a very good starting point.
User avatar
xavier
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 9481
Joined: Fri Feb 18, 2005 2:03 am
Location: Dublin, CA, US
x 22

Post by xavier »

24 bones is a limit only if you want to support DX8-level hardware (Vertex Shader 1.1). If you can support VS2.0 and up you can use up to 96 bones.

The best place to look is definitely the manual for figuring out what to do with the hardware vertex and index buffers.
User avatar
HexiDave
OGRE Expert User
OGRE Expert User
Posts: 1538
Joined: Sat Jan 14, 2006 8:00 pm
x 1

Post by HexiDave »

Hmm, well I suppose I could let the software run the bone structure if VS 2.0 isn't available and have hardware take over if it is present, couldn't I? I'm sure that'd make a few people sad about performance issues, but I'm catering to a very small group of people anyways and if they want to complain about a free game... well that's just too bad :lol:

I remember reading a bit about the Vertex buffers when reading the manual so I'll go over it again now. You've been a tremendous help to me (again.)

Thanks again :D
User avatar
HexiDave
OGRE Expert User
OGRE Expert User
Posts: 1538
Joined: Sat Jan 14, 2006 8:00 pm
x 1

Post by HexiDave »

Ok got VS 2.0 skinning working and got about +10-20 FPS per animation! Not too shabby!

I also noticed a couple of horrible mistakes on my part with exports from Maya (Did you know your left pinky is partly connected to your knee? Well, mine apparently is :cry: ) which are mostly from when I was first experimenting with moving an animated mesh from Maya -> Ogre.

Absolutely awesome stuff - I'm already picking these things apart and learning some pretty cool stuff about shaders.
User avatar
xavier
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 9481
Joined: Fri Feb 18, 2005 2:03 am
Location: Dublin, CA, US
x 22

Post by xavier »

You'll notice a significant increase when you make everything a single mesh, too.
User avatar
HexiDave
OGRE Expert User
OGRE Expert User
Posts: 1538
Joined: Sat Jan 14, 2006 8:00 pm
x 1

Post by HexiDave »

Oh sure, I just have to figure out how to do that first (as in merging them in the Vertex buffer.)
User avatar
HexiDave
OGRE Expert User
OGRE Expert User
Posts: 1538
Joined: Sat Jan 14, 2006 8:00 pm
x 1

Post by HexiDave »

While shuffling through the API/Manual trying to find out how to create a shared vertex buffer, I saw this:
VertexData* Ogre::Mesh::sharedVertexData


Shared vertex data.

Remarks:
This vertex data can be shared among multiple submeshes. SubMeshes may not have their own VertexData, they may share this one.

The use of shared or non-shared buffers is determined when model data is converted to the OGRE .mesh format.

Definition at line 223 of file OgreMesh.h.
That last line about determining shared/non-shared data at convesion - what is that about?

From what I've gathered I have to:

1.) Create a new vertex buffer
2.) Iterate through the sub-meshes of the armor and add their vertex data to the new vertex buffer
3.) Somehow pass the new vertex buffer in place of the original, multi-mesh armor.

Again, the need is that my .mesh file will have body/armor parts all attached to one skeleton (various heads, arms, legs, torsos, etc) OR I could have a file for each suit of armor and body just saved with the same skeleton and then interchange parts when you equip the item (thus replacing whatever you had before.) I assume if I were to use the second method I would just load each piece of the body I need and add it to a SceneNode and just set the animation?

I'm clearly not used to all of these concepts, but I'm trying to gather information and try it out - I'm just struggling to find the right functions and methods to use here. Anything anyone can input (even small snippets of code giving me an idea of what calls need to be made) would be very helpful.
tonyhnz
Greenskin
Posts: 101
Joined: Fri Feb 25, 2005 3:54 am
Location: Florida

Post by tonyhnz »

I just wanted to summarize this thread for my clarification :

For best performance individual (body part) meshes need to be merged into one for batching purposes.
There are two ways to achieve this :
(i) Preprocess the parts into one .mesh prior to loading. The problem with this approach is that if you have a lot of varieties of each part, then you would need a lot of different combined meshes to cover all the combinations.

(ii) Merge the meshes once they have been loaded.This obviously adds some loading overhead to merge the vertices but results in a unique mesh for the combination of parts required.

Option ii seems to be the better approach if there are a number of different parts/variations of each part.
Post Reply