I am wondering how to efficiently render multibody objects like vehicles or skeletons. I am mostly focused on rigid bodies linked using joints.
The goal is to minimize draw calls while allowing each part of an object to have its own transform matrix. The problem is that there are many objects made of many movable parts, each having many subsets with unique materials which require their own colors and textures being set up in shader. This results in tens or hundreds of draw calls which has a noticeable impact on the performance.
My ideas (let's consider a car with movable wheels and doors for example):
- The whole car geometry is put in one vertex buffer. Each movable part has its own range of triangles in the index buffer. There's one extra variable in the vertex buffer used for part index, so each part has its own index stored in its vertices in vertex buffer. Finally, I can render the car with one draw call: The vertex shader accesses an array of transforms using the part index and transforms each part's vertices using the correct matrix. The possible number of multibody elements is therefore limited by the number of constant registers (but it's sufficient in most cases). However, this works only if the object uses only one material...
- So why not access different materials in a similar way? I could use another variable in vertex buffer as a subset id and store materials in shader constants. Then, in vertex shader, I'd choose the proper material settings depending on the subset id and pass them to the pixel shader. But the whole idea seems to be very limited by the number of constant registers - it's much more obvious than with the previous idea, as there are so many material variables like ambient, diffuse, specular, even textures! - colormap, normalmap, etc. So it may work but only for a little number of materials. And for example, the materials could be limited to diffuse only and use one texture atlas for all subsets.
What do you think about it? Is it common in games to use skinning (or at least something similar to it) for rigid multibodies like vehicles? What about the efficiency of using shader arrays accessed by index variables stored in vertices?