1
\$\begingroup\$

I have an animated model with a maximum of 60 bones. That means i have an array of 60 matrices when i want to render the model. Previously i would just create a uniform with the fixed size (mat4[60]), but now i want to render the model via instanced rendering, which means i need to write 60 matrices per instance into the VAO of the model.

This would mean i have to create 240 vertex attributes each containing 4 floats because thats the maximum number of floats an attribute can have. This is obviously a ridiculous solution, besides the fact that i think it exceeds the maximum number of attributes a VAO can have.

So how do i render animated models via instance rendering?

\$\endgroup\$
  • 2
    \$\begingroup\$ Could we rephrase your question's title to something like "How to provide many bone matrices for instanced skinned mesh rendering"? Focusing on the ultimate problem to solve can often yield better quality answers, faster. \$\endgroup\$ – DMGregory Feb 26 at 19:42
1
\$\begingroup\$

The solution is to not use a vertex attribute to store this data.

As you've correctly observed, this is going to overflow the maximum number of attributes, and is indeed ridiculous.

Instead you should use some other form of object - e.g. a UBO or SSBO - to store it, and then use the value of gl_InstanceID to index into that storage in your shader.

So for example you might use something like:

mat4 bones[600];

Which would give you sifficient storage for 10 instances. Then using gl_InstanceID * 60 + bonenumber to retrieve the correct bone matrix for each instance.

This of course is going to put an upper limit on the number of instances you can draw, but that's OK.

\$\endgroup\$
  • \$\begingroup\$ UBO has minimum max size of 16kB, so I don't think this will scale. I think the issue here is that OP is simply not using bones correctly, ideally they should be able pass one matrix per joint and instance render the whole rig instead of having to pass all matrices at once. \$\endgroup\$ – whn Feb 27 at 19:14
  • \$\begingroup\$ @opa - correct; I refrained from recommending a specific object type for this exact reason; different types will have different performance characteristics, scalability, and suitability for dynamic updates. \$\endgroup\$ – Maximus Minimus Feb 28 at 9:43
  • \$\begingroup\$ Well, i have one matrix per joint. But since one model can be affected by multiple joints i have to have the whole matrix array for each model. I've read an NVIDIA paper about it and they suggest to simply use a texture to sample the matrices, but i've come to the conclusion that it's just not worth the effort since i'm planning to introduce character customization, which will result in a lot less instances per unique body part and i don't think that instance rendering those would make much of a performance improvement. \$\endgroup\$ – Masy Mar 3 at 11:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.