Bug Smash #2: If you want something doing properly...

The only real downside to using a pre-built engine is that it's usually been made with someone else's project in mind.

That truth manifested once already when Unity's UI layout engine ground to a halt when faced with 1000 movable notes and associated furniture. This time it's not performance that's the issue, it's the fact Unity simply can't be made to understand what I want.

As I mentioned in an earlier blog, Unity performs dynamic batching to reduce the number of draw calls. It combines the geometry of the note backgrounds, borders and other sprites and draws them all at once. This is nice and fast but, of course, there's a wrinkle.

For things to look nice when they overlap, they need to be drawn in back-to-front order. You can draw them front-to-back and use Z-masking (in fact that's generally more efficient), but then you miss out on nice anti-aliased edges and corners.

For a while now I've been trying to achieve this rendering order by rearranging the order of the child 'note' objects in the scene and moving them towards and away from the camera. Unfortunately, Unity's dynamic batching has other ideas.

It seems (though I have not been able to confirm this) that they have been really clever. Suppose you have four 100-vertex objects, A B C and D, all using the same material. The batching will combine them into a single 400-vertex lump. Now suppose only C is moving around. You don't want to waste CPU updating the 300 vertices belonging to A B and D, so you just update vertices 200-299 - the ones belonging to C. And because children might come and go in the hierarchy containing A B C and D, you want to remember that C uses vertices 200-299 regardless of what else happens.

The upshot of this, so far as I can tell, is that once an object has been assigned to a sub-range of the dynamic uber-mesh, Unity won't change its mind.

Fixing this means bypassing the dynamic batching entirely and rolling my own note-furniture renderer with a procedural mesh. And bypassing the 'update' function of the notes and pumping them in an explicit order, because Unity cares not for how things are arranged in your scene hierarchy; it will update them in whatever order it damn well pleases :)

Comments

Popular Posts