Skeletal animation performance related

Hi



I am planning to program a soccer game. So for a while I was trying to evaluate game engines and some scenegraphs. I tried two other (one free and one commercial java engines and C++ Ogre.)



I tried JME last, because the website is not selling type. Take it as a friends advice, for java ones jme is the most performant with a lot of cool features. (I started to looak at before .10 is released and even web site wasn't showing some cool things what jme can.)



Alright back to start, soccer game. 22 sketal animated players, and  a soccer pitch; my objective is obtainig a very smooth playing game with cool phsiscs and networking. I am making some test, in learning phase so far.



My models have lower than 1000 triangles. I exported the run animation to ms3d format and it works.



This is my test result with 20 players on a simple plane with 640x480 screen on my laptop(shared intel graphics card, 1gb ram, 1.7mhz intel cpu with 533 mhz fsb) with run animation:



the commercial engine: 10 fps

JME                        :  20 fps

Ogre                        : over 100 fps



jme is the best in java field but comparing to ogre, there is a huge gap. Also I must add that, I am not a expert on all of the engines I simply make changes in example apps.



Dont think I am advertising sth, cause I dont have an intension to work C++; after comfort of java for 9 years. I am trying to come to the point:


  • Is there a possibility that i am doing sth wrong. Should I expect better performance?


  • What can you offer me increase the performance (except reducing the poly count), keep in mind that I am pretty new to 3d, game engines and most importantly JME.


  • Is there a possibility to  expect improvements in this part of jme for near future (lets say 6 months). I am asking this because if I am not doing sth wrong , the gap cant be explained just blaming the java being slow. It must be some algorithms or whatever works in the back.(I am not get in the code that deep so far.)





    Sorry for my Engrish, and Please dont feel offended as I said before, JME is best in java area; and I am planning stick with it for a while. 



    Thank you.

    Ahmet

have you done any profiling with your game? just to make sure that the low fps is due to jme things and not somewhere else in your code…

seeing where the the power is put would help alot in helping you  :slight_smile:

if it is the same file why load it 20 times, just load it once and copy it to 20 nodes but that'll only help load times.

It seems that I shouldn't expect 2 much. :frowning:



Maybe a simpler game, like 2 on 2, without goalkeepers  :stuck_out_tongue:



Has someone tried above code? Maybe it works fine on other computers?


Now this isn't an area I've really delved into yet, but what about shared meshes?  Can those be used in this case instead of duplicating the spatials for the models entirely?


ahmetyetgin said:

It seems that I shouldn't expect 2 much. :(


I've seen some extraordinary things done in jME without sacrificing FPS.  Don't give up hope yet, jME is the best in Java, and if there's some problem causing it not to keep up then we need to fix it.

darkfrog

I'm no expert or anything but, I've heard it said hear a couple times that intel's gl support isn't all that great have tried updating the drivers

Profiling your example shows that the culprit is the continuous recalculating of boundings for every segment of every model on every frame.



Adding this to the for loop in your test boosts the frame rate by a factor of 2 on my end:


((JointController)node.getChild("ms3d file").getController(0)).setModelUpdate(false);



You may want to simply set the node's cull mode to SceneElement.CULL_NEVER in your case rather than use the bounds because of those bounds calculations.

In addition, the JointController has a throttle on it to control how often it updates.  There's no real reason for it to update EVERY frame since the human eye can trick the brain into seeing smooth animation at somewhere around 20-30 fps.  The default throttle is pretty high (100 fps) so you can set this lower.  Unfortunately there is not an accessor method for this at the moment, so you have to do it like:

((JointController)node.getChild("ms3d file").getController(0)).skipRate = 1/30f;



The two lines combined boost my frame rate on your example test from about 44fps to about 190fps.  Judicious use of shared mesh could perhaps boost it higher depending on what you need it to do. (eg. if you had several models acting in unison)

Awesome!



Above test code produces 70-80 fps on my machine; and my game test (22 model+soccer field+skybox) produces 30-70 FPS according to where camera is, which is quite good. (a shared memory card makes the difference i guess.)



Maybe doing some calculations only on load (with animation), and using more memory might be a hard but interesting experiment, however i must delve the JME code very far. (This might not make sense, just an idea.)



You cant guess how happy i am, neither giving up the project nor leaving java.



Using shared meshes, seems like a tough task, but i ll look at it later. Currently I should work on some physics.



Keep up the good work guys.



Thanks for the responses.



Ahmet


SharedMeshes from what I've done with them are EXTREMELY easy.  I've been really impressed.  However, I've only used it with simple TriMeshes, so I don't know if there's any way to do it easily with a Node.



darkfrog

SharedNode makes a copy from an existing Node (using SharedMeshes). So it's not that hard…



The problem with sharing an animated object, like Renanse said, is all animation will be synchronized.

oh…that's not good. :o



darkfrog

Just thinking out loud here but in the background couldn't you have a model for every animation, running, kicking, and um well there isn't much else in soccer is there  :smiley: just kidding.  So basicly if a model runs it becomes the shared node in the background(might need 2-3 diffent models on same animation so everybody isn't in sync). So basicly key press shadedNode Running, key release shadedNode Standing.  Then it's just a matter of transforming the nodes based on a array that holds position and rotation.

Patrick,



the problem there would be in animations sequences that either run to a completion of an event and if one model is already partially through that sequence and another model switches to start it would either restart the animation or pick up half-way through.  Either way that's pretty hacky. :-p



darkfrog

well that isn't a shared mesh/node problem or even a animation problem thats a coding problem.  Just gotta code it so they return to the idle state or something.  Generate the animation on the fly would be pretty easy right?  Put in x number of frames you want it to happen over, start Position(the skeleton half way thur a run lets say ,and end Position(idle) and just have it divide like kneeStart by kneeEnd by 2 x numbers of times.  Then do it again but one less time. Intill done.  I'm glad he brought up the issue saved me a post in the future.

And how is that different from how (keyframe) animation works right now, Patrick? Do you suggest to do all this before the animation starts? (then why call it "on the fly"?)



The biggest way to speed the whole thing up would probably be to use vertex shaders.

llama said:

The biggest way to speed the whole thing up would probably be to use vertex shaders.


Dont know much about them, but this should happen in jme core i guess?

Actually vertex shader you have write yourself support for them is in jme.  Vertex shaders allow you to manipulate position, color, normal and other stuff in real time per-vertex,per-fragment or per-pixel can do a bit more but same idea.  It would be fairly hard for somebody to use vertex shader for animation if you never have, glsl is the highest level launge supported but there are a lack of tutorals on there.  You could find source on matrix4x4 animation on nvidias developer site under CG demos.  Another way of doing it is putting animation values into a texture sending them to the vertex shader and reading the values(required pixel shader 3) the transforming the vertex to the position in texture or calculated from texture.


not every card supported vertex shaders for animation in the past...maybe I am always about really crap cards as target. I think Warcraft3 was done with that using dx 8.1, but dont quote me on that....

BTW, haven't read whol thread, but in general, when one one wants to do stratey like games, is not allways bad idea to use vertex animation insterad. And use impostors or lod, or something, to reduce the performance thing when you see much stuff in screen, when camera goes up, etc. If ur camera never gets as near as an fps, then do very low pol count meshes, with very few keyframes (all stuff I speak here is ARTIST SIDE, not code, except the lod and impostors thing, though probably artists will have to provide several lod meshes unless automatic lod can be used. The impostor in strategy games at the end can be a tri with the character rendered there ;) )


BTW, about vertex animated formats in JME that I know of, you can use surely three, you may do better with the 3 in low machines than with shaders or bones and weights , at least in low machines, are: md2, md3, hevee's format. If you use Blender, I'd go with Hevee's.

I have posted long ramblings about it here, just now :

http://www.jmonkeyengine.com/jmeforum/index.php?topic=3330.0


I maybe wrong, because I am partially crazy ;)

No, maybe that could help.

About performance, I am seing in our tests incredible resullts with JME in *really* low machines. It's obvious to me that is also that Tora is a great coder :) (though he tends to say he isn't but this is as he think he need  to be humble or something :D  ) We're yet waiting to see still our tests with loading md5 files, (bones and weights  GREAT format) If that thing doesn't kill so great results (not lower than 40 fps, lol ) man, would I be happy. :)

But for many animated characters at once I most surely would go with a vertex animation format. is not our case.


Oh, and milkshape doesnt have weights calculation, but I imagine those bone rotations calculation or whatever, maybe the interpolation, a programmer would know, also kills performance...So I guess with weights would be even more (but milkshape animation format hasnt )



when moving the skinning(the bone animation is allways done on the cpu) over to the gpu on the xbox, we could have 40 instead of 5 animated characters…dunno how good performance you can squeeze out of todays cards but it's probably an even bigger boost compared to the cpu…