So, normally in OpenGL if we wanted to render 2000 of an object, we would call glDrawArrays 2000 times. Instanced rendering allows us to make a draw call only a single time, leading to less CPU overhead per draw call.
Therefore, it seems to me that we would always want to use instanced rendering for all objects, as opposed to only things like particles, etc. However, I read online that instanced rendering is actually worse when you have few instances. For example, if instead of 2000 of an object, we only had 5. I don't understand why this is the case (if it's even true) and would like some clarification if possible.
I suppose the question is: Does the DrawArraysInstanced method have any extra overhead, such that if we only draw one (or a small number of) instances of a lot of different models, it actually yields a performance hit? If not, does that mean DrawArrayInstanced is always a better (as in, scalable) function than DrawArrays?
It is worse in the sense that it takes more time to make a single object that is instanced than the same type of object that is not. After all there is more work to be done. However I assume with most gpus this isn't too problematic when measured.
Also in most cases if you are using instanced objects they'll have more data to be passed to the shader at once:
- A single object has a position, rotation, scale and color value
- Each instance of that object can vary in all above attributes
- However you do want each instance to have it's attributes relative (one instance is double in size, another is x units away from the origin position etc.)
- So most likely you'll end up with object attributes that are used on all instances of an object and instance attributes that use the object attributes to perform relative changes
Obviously this is most useful is you have enough instances of an object. For an object with a single instance the object attributes and instance attributes would be the same (or the instance values would be zero depending on implementation) and therefore redundant.
I would always use instances if I know I could have more than one instance of an object. After all, maybe I do have a level with a single tree, but five others with 10. Do I really need to make a completly different object creation and rendering path for this one level? That doesn't seem right to me. Unless of course I have measured that it is a problem. But I would never implement that for minor optimizations and prematurely.
In the specific case of the function DrawArraysInstanced having overhead: I don't know. Of course this always depends on the gpu, but I'm not sure if there is a typical and measurable overhead for most gpu.