hardware animation is it possible?

BlitzMax Forums/MiniB3D Module/hardware animation is it possible?

Pete Carter(Posted 2011) [#1]
Is it possible to add hardware mesh animation to minib3d, as far as i know the leadwerks engine is writen in blitzmax and does it so does anyone have any ideas as to how this could be done? Sorry if this is one of those question that gets on some people nerves but im really happy with minib3d the only thing holding me back is the number of animated meshes you can have running at a good frame rate in software.

Last edited 2011


ima747(Posted 2011) [#2]
Anything's possible, it's a matter of how reasonable it might be with the current structure... bearing in mind that adding it might impact the min specs (such as OpenGL revision) of minib3d as a whole...

It's never going to make it into the official version I can virtually guarantee that, but it could be worked into a variant or extension (like the old MiniB3D extended from klepto that had shader support...)


Pete Carter(Posted 2011) [#3]
I will look into it and post my findings.


Pete Carter(Posted 2011) [#4]
Just out of interest did then max3d that mark had on googlecode have hardware or software animation support?


AdamRedwoods(Posted 2011) [#5]
You would need to write an ARB_Vertex_Shader to do this in hardware (for per-vertex operations). This requires a minimum of Opengl 2.0. I don't think max3D does this.

A PDF on vertex shaders:
http://developer.nvidia.com/docs/IO/8230/GDC2003_OGL_ARBVertexProgram.pdf

Last edited 2011


Kryzon(Posted 2011) [#6]
See this nVidia demo to try it for real.

One thing you'll need to remove from MiniB3D is the VertexDeform() function which performs the actual deforming - this is the operation that would be done in the vertex shader.
The software side still has to calculate the bone matrices for the current frame, and that is done in the AnimateMesh() and AnimateMesh2() functions of TAnimation.

You'd need to pass all bone matrices as an uniform array of matrices to the vertex shader. A uniform is a type of container that is used by all vertices being rendered, so they can all access it.
You'd need, however, an attribute - which is a vertex-specific property, every vertex has their own - to specify which bones in that array the vertex uses, and the weight they apply.

This costs memory.
- You need that uniform array of matrices (lots of floats), so that's why some engines limit bone quantities to 256 and less.
- You need a 4-float attribute for the bone indices - it's an attribute because every vertex will use their own set of 4 bones (even if they're influenced only by one, or none).
- You need a 4-float attribute which corresponds, respectively, to the weight those 4 bones apply to that vertex. This is why most engines limit weights to 4 - it's a convenient and efficient format.
You can even recycle standard vertex attributes if you're not going to use them: texture coordinates, for instance. That's an attribute in the form of a 4-float value, and you can use that to store bone indices (e.g.: "1.0 35.0 13.0 27.0"). Then use any of the other gl_MultiTexCoord'n' attributes to store the ordered weights and there you have it.
More about attributes.

Most of the math done by VertexDeform() can be used as reference, there isn't much difference to a shader version except accessing the values.

PS: You'll need to brush up on your GLSL because this is complex as hell!

Last edited 2011


Pete Carter(Posted 2011) [#7]
Thanks for the info and links, if i can get my head round the idea ill have a go

Last edited 2011


GNS(Posted 2011) [#8]
I started looking into this a few months back. Animation performance starts to be a real bottleneck, especially when you're processing a lot of bones each frame.

While looking over my options, I stumbled across a couple of Intel articles that talk about vastly improving performance of software (CPU) skinning. The articles are here and here.

The first article is a bit outdated (it references 'current hardware' as being the Radeon 9800/GeForce FX) but the techniques should still be valid. The paper makes use of some clever tricks to reduce matrix math (which might be directly applicable to minib3d), SSE optimizations and multi-threading to offload the work to another thread (and hopefully another processor/core).

On the other hand, hardware (GPU) skinning is probably the 'standard' way of doing things now. Some of the limitations hardware animation used to suffer from have been taken care of and the hardware support required to do it is extremely common. Implementing vertex shaders into minib3d also gets you access to some really nifty options.

Both options have their advantages and disadvantages.


ima747(Posted 2011) [#9]
I would personally push towards shader support and by extension offloading to the GPU. This would give you by far the largest bang for your buck as well as opening the door to many more options in the future for other things.

That said raw math optimizations are ALWAYS a good thing. Faster is faster. I would just expect lower returns on investment here and it only goes so far. This is however the only option that doesn't place additional requirements on a system (such as having SSE support, or multiple cores, etc.) and therefore is in keeping the the core minib3d goals.

Offloading to another thread and CPU is a possibility, but there are a few problems. First the multithreading in bmax has always opened a pandora's box which is the multithreaded GC. There be dragons in there... wee little dragons that come and nip at you when you least expect them. Additionally minib3d is designed for a controlled loop, so syncing the multithreading could be a real big hassle without overhauling a lot more than one might want. However if one wanted to brave those waters there are other gains to be had in multithreading as well, I use a multithreaded texture loader in one of my projects for example... but the whole project has to be built around it and sync management for texture loading... I could see a multithread focused offshoot of minib3d being very valuable for projects that are less traditional in structure, or are willing to break out of that box to leverage some heavier hardware.


GNS(Posted 2011) [#10]
I agree ima, going the shader route is probably the best choice overall in most cases. Even implementing just vertex shader support opens up a number of spiffy possibilities. I figured I'd toss in some info about a possible alternative just for the sake of discussion and because I suspect some of the optimizations mentioned might be applicable to minib3d without fundamentally changing anything, which would be a win for everyone.

My own plan was to stay away from the multi-threaded approach if I could help it because, as you said, there are some very... interesting surprises that pop up.


Pete Carter(Posted 2011) [#11]
Haven't really looked at this as much as id hoped yet, but thanks for posting the info its very interesting.