• Unity
  • Starting new project: Need advice on optimizing draw calls

  • Изменено
Related Discussions
...

I'm about to start a new project in Unity that is a sequel to a game I made in LibGDX. It's an overhead view, where layers use y-order to render, aka things on a layer are rendered starting at the top (highest y-value) and then going downward (smallest y-value).

Screenshots from the original game:


I'm trying to figure out a strategy so that I can minimize shader-swaps / draw-calls. When I render the "main layer" that has stuff like characters, trees, rocks, etc. there will be a mixture of Spine animations and regular Sprites. I'm semi-new to Unity, but I believe I'll be getting a new draw call every time it switches from rendering a Spine animation to a Sprite (and vice-versa). With lots of objects, plants, and characters, it seems like the number of draw calls would quickly stack up to potentially 100+.

With LibGDX I didn't have to switch the shader between rendering sprites and Spine animations, so this wasn't an issue.

Is there any strategy to prevent this? Appreciate any help, and would be glad to provide more info if needed!

You are correct, when sorting order switches from a Spine material to a Unity sprite or vice versa, it needs to start a new batch. However, I would assume that there will be a lot of batching remaining in the scene above. I would not worry too much about it.

Jamez0r написал

With LibGDX I didn't have to switch the shader between rendering sprites and Spine animations, so this wasn't an issue.

Please be aware that it's only beneficial if the objects share the same atlas texture. It will also not gain too much if the vertex count is higher. I assume you are aware of this, just mentioning for the sake of completeness.

Hey Harald! Thank you for answering this question and the one on my other thread. Seriously appreciated! I'll be testing out your suggestions on that other thread, but I wanted to ask one more follow up question here:

Harald написал

Please be aware that it's only beneficial if the objects share the same atlas texture. It will also not gain too much if the vertex count is higher. I assume you are aware of this, just mentioning for the sake of completeness.

The objects will share the same texture atlas, but I'm curious about you mentioning the vertex count. I'm reading that Unity's batching system won't continue a batch if it goes over 300 vertices: https://docs.unity3d.com/Manual/DrawCallBatching.html

Are you saying that if within a batch you go above a certain vertex count, that it becomes less and less important to "continue adding stuff to this batch"? On my previous project I would try to cram as much stuff as possible into a single batch, lol

Jamez0r написал

The objects will share the same texture atlas

Glad to hear that. 🙂

Jamez0r написал

Are you saying that if within a batch you go above a certain vertex count, that it becomes less and less important to "continue adding stuff to this batch"? On my previous project I would try to cram as much stuff as possible into a single batch, lol

Sorry that I didn't explain myself too well there.
What I meant is that:

  • If the vertex count of an object is low, e.g. only a quad or 50 vertices, and you have many objects (e.g. 10+) then batching should be very beneficial, as there is not as much data to be copied to the new vertex and index buffer of the batch drawcall.
  • If the vertex count is higher, e.g. close to the limit of 300 vertices, and you have only 3 objects, it will not be too beneficial to copy the data over to another batch vertex and index buffer. If it were beneficial to batch more than 300 vertices, Unity would likely batch these, however this seems to be about the break even point where the copy operation gets more expensive than the draw call was.

Anyway, the whole batching and drawcall overhead depends largly on the generation of hardware and rendering API used, as you can almost ignore the number of drawcalls in recent APIs, and thus ignore batching entirely.

So in summary: if your most frequently used objects are all sharing the same texture - perfect. If the large batch (e.g. 150 objects) gets split into 6 medium-sized ones (25 objects) - still good.