I have a collection of 2d objects with transparency. Each object has a depth value to determine draw order and a material. I'm trying to batch them in an optimal way to minimize draw calls. Assume that objects with the same material can be batched together in a single draw call.

A naive way of batching is to sort all objects by depth first, then sort by material if the depth values are the same. Consider the following set of objects with 'z' representing depth and the color of the object representing its material. In the right set, blue objects have been translated along x such that they don't overlap with red.

enter image description here

Sorting by [depth,material] results in the sorted object list: { Red, Blue, Red, Blue } for both the left and right set of objects. Either left or right would result in 4 draw calls (objects of the same material need to be adjacent in the sorted list to be batched)

However if you look at the objects on the right, its clear you can use two draw calls because there's no overlap. The ordering based on depth doesn't matter if the blue and red objects don't overlap in between a given batch's depth range. This would also hold true if you had a red object with (z > 4) or (z < 2) anywhere in the right set.

So, assuming each object has a material that can be compared, a depth value, and a bounding box (lets say each object is an axis aligned quad), what is an efficient way to get a list of draw objects with both a correct ordering for transparency and optimal groupings based on material?

Also just to note, I don't have instancing support so that's not an option here.

  • \$\begingroup\$ Could you give an example of a way you find inefficient and explain why you find it inefficient? \$\endgroup\$ – Andreas Apr 12 '16 at 21:18
  • \$\begingroup\$ A quick answer would be that you might be pre-maturely optimizing. Always try to profile and identify the bottleneck. Now assume this is indeed the problem ... it's a sorting problem data base people been trying to solve since forever. What you are trying to do is that you want your objects to be grouped together by certain attributes (depth or material types) yet the attributes might conflict. It seems like the key difference between the two pictures you have shown is that the left has things over each other while the right one doesn't. So if they don't overlap, sort them by material? \$\endgroup\$ – ChaoSXDemon Jul 28 '17 at 16:50
  • \$\begingroup\$ Ultimately transparent objects needs to be rendered from back to front ... so really the best you can do is sort by depth. You may be able to squeeze more performance if they are static .... \$\endgroup\$ – ChaoSXDemon Jul 28 '17 at 16:52

If batching is a bottleneck then you might want to sort them by depth and material and also perform a bounds check to see if they overlap. But you're probably going to spend way more time in sorting and checking than just plain sorting and having a less performant batching.

I guess your mileage may vary but if you're writing a generic batcher I'd stick to simple sorting and ignore the bounds check.


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.