This is a question I've never been able to find the answer to. Batching objects with similar states is a major performance gain when rendering many objects. However, I've been learned various rules when drawing objects in the game world.

  1. Draw all opaque objects, front-to-back.
  2. Draw all alpha-blended objects, back-to-front.

Some of the major parameters to batch by, as I understand it, are textures, vertex buffers, and index buffers. It seems that, as long as you are adhering to the above two rules, there's little to be done in regards to batching.

I see one possibility to batch, while still adhering to the above two rules. Opaque objects can still be drawn out of depth-order, because drawing them front-to-back is merely a fillrate optimization, meanwhile state changes may very well be far more expensive than the overdraw of drawing out of depth-order. However, non-opaque objects, those that require alpha-blending at least, must be drawn back-to-front in order to avoid rendering artifacts.

Is the loss of the fillrate optimization for opaques worth the state batching optimization?


You might want to read Christer Ericson's excellent blog post on draw call bucketing: http://realtimecollisiondetection.net/blog/?p=86

Alpha blended objects will have to be draw back to front to avoid artifacts.

State batching will not help with reducing the amount of alpha blended objects being rendered.

If you're looking for a way to discard objects that do not visually contribute to the scene, then what you're looking for is culling.

What state batching will help with is to ensure that your alpha blended objects are actually drawn last and in reverse depth-order.

It will also ensure that within both your alpha and non-alpha buckets all objects are sorted so as to keep expensive state changes to a minimum (primitive, shader, texture, shader constant, etc.).

As for rendering opaque objects front-to-back (with depth testing enabled): If your pixels are expensive to compute (read: complex pixel shaders), then not having to compute the same pixel multiple times can be an enourmous gain - which gives rise to the idea of an early depth-only rendering pass (Z-Pre-Pass).

  • \$\begingroup\$ So, effectively, draw all fully opaque objects with Z-write and Z-read, but no color-write, then render objects based on batching? I'm amazed that drawing all opaque objects twice, even if only to a single buffer, doesn't undo the benefits of batching state changes. \$\endgroup\$ – Sion Sheevok Mar 1 '11 at 19:30
  • \$\begingroup\$ You'd batch for minimal state changes anyway - whether you do early-z or not. Weighing one against the other isn't really meaningful. Early-Z isn't something that always makes sense - it's a tool you can use to give you some extra performance iff you're making extensive use of pixel shaders. You will have to actually profile it and then decide whether to turn it on or off depending on your data. \$\endgroup\$ – SmoCoder Mar 2 '11 at 9:20

If you can render your opaque pass front to back then you are probably fine, but for a lot of scenes this might not be worth the processing time. What people usually to is render a Z-only pass to fill the Z-buffer, and then render opaque with optimized state changes to only render visible pixels. Transparent can then be rendered back to front.

It's all up to the scene and render layout. Check performance counters before trying to optimize.


http://developer.nvidia.com/docs/IO/8230/BatchBatchBatch.ppt is a great presentation by NVIDIA on batching costs.

On the first slides it says that the wisdom that state changes are expensive is wrong. Its about how many batches you have.

Its not the state that goes with each batch, its the batch itself that costs. So how might you put lots of objects into a single batch? (slide 30 onwards...)

  • \$\begingroup\$ I'd read that article, but he seems to act as if there were no relation between the number of batches and the size of batches. If I have 300 objects, I can have between 1 batch of 300 and 300 batches of 1. The fewer batches, the better. Between each batch is a set of state changes. I'll give it a reread while I'm at it, but state changes are still a heavy expense. \$\endgroup\$ – Sion Sheevok Mar 1 '11 at 19:19
  • \$\begingroup\$ Yeah, he does point out that 300 batches of 2 triangles is like 1500x from the potential throughput of some arbitrary card. The numbers will all of course move upwards and onwards with Moores law, but still. \$\endgroup\$ – Will Mar 2 '11 at 7:59
  • \$\begingroup\$ The number of batches is directly related to the number of state changes though: Once you change state you have to start a new batch. \$\endgroup\$ – SmoCoder Mar 2 '11 at 9:26
  • \$\begingroup\$ Yes, and their slides ask the audience how you can avoid state changes, and hint to other people's GDC talks, for example collaging textures into a single large texture and so on. But the unit is the batch, not the state change. \$\endgroup\$ – Will Mar 2 '11 at 12:46

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.