Extracting Character Transform Table into a TBO

Hi. I’m currently hitting a bottleneck with hardware skinning control. I’m planning to make a large dense forest of animated trees (with bones to simulate wind) and need control over the frame times and bone amounts for each instance. To fix this, I want to put the transform table into a TBO. currently i’m working like this:

uniform samplerBuffer TBO_TransformTable;
uniform int TBO_SkinningFrame;
uniform int TBO_NumJoints;

this will be passed into the shader. However, the TBO needs to store the entirety of the animation so that I can pass any frame number in and it will index the right position in the TBO. However I’m struggling to actually get the animation information extracted from the animated tree. How do I extract the bone data from Character and put it into the TBO?

I was thinking of storing each matrix row side by side in a rgba32 texture and reconstruct the matrix in the shader.

I’m using TBO for hardware skinning too, but I end up writing my own Character/Actor class alternative, which is represented as tree of bone nodes and I’m writing only the current animation frame into TBO - panda3d-kphys/kphys/core/panda/armature.cxx at master · kitsune-ONE-team/panda3d-kphys · GitHub
I’m using this simple structure for serializing the current frame of the animation into TBO - panda3d-kphys/kphys/core/panda/types.h at master · kitsune-ONE-team/panda3d-kphys · GitHub
The whole project could be overkill for your task, but maybe you can find some useful parts from it.

1 Like

yea that would be overkill. My trees only need one animation at once. And to reduce CPU overhead, it would be good to just put the entire animation in one TBO.

I noticed in your code, you also create another TBO _bone_id_tree_tex. I’m interested how you exactly referenced in uvec4 transform_index; in you shaders. What is you structure exactly?

I noticed in your code, you also create another TBO _bone_id_tree_tex.

I’m not using _bone_id_tree_tex atm. I made it for some future optimizations.

This is how I’m referencing the transform_index:

mat4 get_transform_matrix(samplerBuffer transform_tex, int bone_id) {
    int index = bone_id * 4;
    vec4 row0 = texelFetch(transform_tex, index);
    vec4 row1 = texelFetch(transform_tex, index + 1);
    vec4 row2 = texelFetch(transform_tex, index + 2);
    vec4 row3 = texelFetch(transform_tex, index + 3);
    return mat4(row0, row1, row2, row3);
}

I’m using only 1 animation frame, but you can put all the frames and calculate the offset by frame index.

So this is generic hardware skinning in vertex shader for up to 4 bones:

    mat4 skin_matrix = (
        get_transform_matrix(bone_transform_tex, int(transform_index.x)) * transform_weight.x +
        get_transform_matrix(bone_transform_tex, int(transform_index.y)) * transform_weight.y +
        get_transform_matrix(bone_transform_tex, int(transform_index.z)) * transform_weight.z +
        get_transform_matrix(bone_transform_tex, int(transform_index.w)) * transform_weight.w);
    model_matrix *= skin_matrix;
1 Like

hmm. Like you said you built your own Character class. How do you extract animation information that is in the correct order for transform_index? Could I potentially use the same method for the default Character class? I think storing the information won’t be too hard. Just need to multiply the frame time with the animation offset for the TBO as an extension to the function you showed.
I’m not actually to sure where to actually get the animation skinning data?