I'm trying to render a large number of identical rigged entities with independent animation.
Compared to standard skeletal animation, I can't compute the pose of each entities and send it to the GPU for each frame. This would demand too much work for the CPU and saturate the VRAM very quickly. Let's say I have 5000 entities with 20 bones, I would have to compute and send 5000 * 20 * (size of matrix/quaternion-translation/dual-quaternion) poses to the GPU, each frame.
I recently found this article/paper : https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch02.html Their idea is to load animations to the GPU in order to access them independently with each instance. Correct me if I'm wrong but I think this is equivalent to move the interpolation part to the GPU.
I pre-computed all the bone transformation in local space for each frame for each animation and packed it into texture buffers. It works as expected.
However, I experience strange results with my animated models... In fact the interpolation is necessarily wrong ! I am trying to interpolate between poses in local space, not in bone space like with standard CPU interpolation. There is no problem with translations, but with rotations. (the axis is shifted to the local space origin).
I imagine I could send the bone space transformations AND the bone hierarchy. But that would impose to parse the hierarchy for each vertex (in vertex shader), in order to re-compute the interpolated bone transformations.
One other idea I had is to upsample the animations in order to have smaller interpolation intervals, but again, it will use more VRAM.
To be honest I'm not sure I understood well the paper (especially in the interpolation part)...
Any suggestion ?
EDIT 1 : It's maybe unclear : by "local space" I mean entity space, so it is more like "global space"...
EDIT 2 : To provide more details about my implementation :
In the CPU (c++) pre-process part, I pre-compute all the bone transformations in local space for each frame (natively, I get bone-space transformations using Assimp library so I have to do a bit of work here).
Then, I send this information as an array to the GPU (array of numFrames * numBones * numAnims dual quaternions). In the vertex shader, I get information about the current instance using gl_instanceID. I get world position, current animation and time in current animation.
Then I compute the interpolated pose of the bones influencing the current vertex. I do that by finding the bounding frames using the instance's time. I interpolate my pairs of transformations (pairs of dual quaternions) for each concerned bone.
(I know there is a mistake because the interpolation must be performed in bone space).
Once they are interpolated, I blend linearly the transformations into one using the bone weights attached to my vertex (and I normalize my final dual quaternion).
It worked when i was doing interpolation in bone space in CPU, I'm just trying to move the interpolation part on the GPU.