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.
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.