Is it possible to support skeletal animations without shaders?

Hi

I know that some Java engines that rely on several Java bindings for the OpenGL (and OpenGL-ES) API support skeletal animations with the programmable pipeline. I know that there are less and less graphics cards not supporting GLSL. I’m interested in skeletal animations and I wonder whether it could be implemented with the fixed functions. I already know how to support key frame animations with the fixed pipeline. Has somebody already done that? My main concern is that storing one mesh per frame can require a lot much memory than storing the data of bones and joints for each frame. If the support of such animations is too difficult to implement with the fixed pipeline, I’ll go on using key frames.

Sure it’s possible. The process is quite the same. Calculate all bone matrices on the Cpu, then instead of applying them via a vertex shader on the Gpu, apply them to the vertices on the Cpu, the upload the transformed vertices via a vertex array or streaming vbo. Note that on some GL ES chips there’s a matrix palette extensiom available for fixed function, probably available on some desktopm gpus as well. Bit limited.

Downsides to Cpu side skinning: transforms are usually slower, and you need to reupload transformed vertices for each model instance every frame.

Thank you for your reply. I already have to modify the morph mesh every frame most of the time when using key frames. What is this palette extension? How can it be useful to support skeletal animation?

The matrix palette extension allows you to upload multiple matrices and the have the gpu transform your vertices with them. all in fixed function.

ahain, not worth the trouble. transform on the cpu, then upload just like you do with morphs. eventually switch to the programmable pipeline :slight_smile:

The problem is, that when you use no shaders, you need to transform every vertex on the cpu, making it really slow.
I have tried this approch, it took 0,5 ms to rebuild a simple model, imaging how slow this would be with more and more complex models.
Combine this with older cards, and your game is unplayable.

When you send at least the transformation matrix to move and rotate the vertrices for each bodypart, this slowdown is completely gone.
Then you only need to calculate its start position and send other data to the shader.

Thanks RobinB. Supporting skeletal animations without shaders seems to be not worth a try.

Spine will do skeletal animation with 2D meshes on the CPU, but the mesh only has a handful of vertices (well, as many or as few as you like).

Most of the complexity in models and animations that you are able to achieve on an amateur level will work perfectly fine using the CPU. Half-Life did it’s skeletal animation on the CPU and it worked fine on machines with less power than any current smartphone has (even when using the high definition pack for the models).

Ok but if my implementation doesn’t scale (I’m not Carmack after all), it will be useless for Ardor3D. My models are usually composed of hundreds of vertices.

I currently use the old method of:


glPushMatrix();
glMultMatrix( boneMatrix );
// draw limb and all child limbs
glPopMatrix();

Only works nicely for models where each vertex only belongs to a single bone…

This was one of the projects I was just working on (although in 2D).

I’d say that skeletal animations are easier to do with immediate mode (or display lists) rather than the programmable pipeline, but obviously not as efficient.

This is basicallt how I did it.


class Joint
{
    public void render()
    {
        //Rotate here
        bone.render();
    }
}

class Bone
{
    public void render()
    {
        //Draw from [x, 0, z] to [x, length, z] or similar
        //Translate to [0, length, 0]
        for(Joint j : joints)
        {
            glPushMatrix();
            j.render();
            glPopMatrix();
        }
    }
}

I’m not sure how you skin the skeletons (are the skins static on the bones, or do they stretch between them), but I think any problems could be solved with interpolation.

This method is however not very efficient, and can’t handle many skeleton before you start to get lag.