Most efficient way to render models

I am trying to find an efficient way to render the models of a scene and i want your opinion of what could be the best option.

I am going to start telling you what i have:

  • A models manager, which knows how many objects are using the same model. We will use it to know how many times we need to render every model and what is the model matrix of every object with this model.
  • We can add a new objects after initialization, then the number of objects using a model can change(the number of instances is not static).
  • I want to pass a model matrix to the shader (i dont want to pass instanced vectors).

The solution that i came to is:
1º Create a dynamic uniform buffer which contains an array with the model matrices. The instance index is used to access the model matrix of the object being rendered.
2º Update the dynamic uniform buffer every time we want to render a new model, which will contain the model matrices of the objects which use this model.
3º Render all the objects with the same model using indirect draw.

The problem with this solution is the number of objects which use a model and the dynamic buffer. I have to set the size of the dynamic buffer before creating it, but the number of objects using the same model can change.

The solution is to specify a dynamic buffer size which is big enough, but i am then:

  • Placing a limitation at the number of objects using the same model.
  • Wasting the space which is not being used. For example, if i fix it to 2000, but just 1 object use this model, i am wasting 1999 positions of this buffer.

Another solution could be to change the dynamic buffer size, but it wont be much efficient i guess.

Then, what do you recommend me to do? Is this solution ok for you? Or there are better options

I implemented this, and i did just a small change:

Create a dynamic uniform buffer

At the end i created a readonly buffer, because then i can pass a variable array instead of a fixed one.

then i changed:
layout (binding = 1) uniform modelMatrix
{
mat4 model[(X)];
} uboInstance;

Where X was a constant int.

To:

layout (binding = 1) readonly buffer modelMatrix
{
mat4 model[];
} uboInstance;