Game Development Stack Exchange is a question and answer site for professional and independent game developers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

In Panda3d, I load a model and place 10000 references to it in the scene-graph. It runs at (say) 2Hz.

I load a 3d model containing 10000 copies of that exact same object, and it runs at (say) 60Hz. As does using the flattenStrong() command which is effectively the same thing but at runtime.

So the question is: is this behaviour a peculiarity of Panda3d, or is it a fundamental law which applies to all games engines?

share|improve this question
It really depends on the technology being used; it isn't clear what actually adding "10000 references" means in practice and it's certainly not a concept with a universal implementation. – Josh Petrie Oct 22 '12 at 22:24
up vote 4 down vote accepted

I believe that what you're talking about is a large number of individual draw calls to the rendering api vs a single large draw call to the rendering api.

There is CPU overhead associated with setting up the rendering state (binding vertex buffers, textures, shaders etc) as well as the actual draw call itself it is generally more efficient to render a large amount of geometry in a single call.

Note that Panda3D most likely attempts to reduce rendering api state changes such as bound texture and shaders by grouping renderables together so these need to be set the minimum number of times. But even with this optimisation if you are drawing many single objects, you must call draw in the rendering api which incurs unavoidable CPU overhead while communicating with the GPU.

The CPU-to-GPU overhead is something we want reduce as much as possible when using rendering apis such as OpenGL and DirectX. This is done in many ways but some optimisations that generally yield good results are to minimise unnecessary state changes and to batch geometry together to reduce the number of draw calls. This is what the flattenStrong command is doing for you.

To say it again, it is generally more efficient to render 1,000,000 vertices in a single draw call than it is to render 1,000 vertices in 1,000 draw calls. Therefore you could call this a fundamental law of the rendering apis which most game engines use under the hood.

share|improve this answer

It's a matter of the number of draws being performed by the GPU. There is a large amount of overhead involved in telling the CPU to tell the GPU to draw something. On the other hand, GPU's are very good at drawing a lot of stuff all at once. So, even though your model with 1000X the vertices may take a few extra microseconds to transfer into video memory, it takes the same amount of time to draw it.

The Mythbusters demonstrated an analogy for the expense of preparing for a GPU draw, versus the speed at which it draws.

You are reloading the mega-paintball launcher 1000 times with your 1000 draw calls.

share|improve this answer

Seems that your slowdown is coming from the 9999 extra world->view transforms that are being performed, one per object.

share|improve this answer
What prompts you to suggest this? The actual cost of the matrix operation is likely to pale in comparison to any other operations involved, such as the actual submission of the draw call. If, indeed, these extra nodes in the scene graph even translate into additional draws and aren't culled out. – Josh Petrie Oct 23 '12 at 2:08

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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