[Find the original post at Unity Draw Calls]
Draw calls are never a problem. That is, until you add one more element and suddenly your render thread becomes your new bottleneck. Can you guess why keeping Unity draw calls at bay is today more relevant than ever?
Unity-Draw-Call-Reduction-Thumbnail
Warning: this is an in-depth post, make yourself comfortable and grab a tea. Use the table of contents if you're in a rush.
Quick Navigation (redirects to my blog)
Signs You Have Too Many Draw Calls
Soft Sign: Battery Draining Too Quickly
Soft Sign: Game-Play Not Running Smoothly
Soft-Sign: VR Users Look Paler Than Ever
Hard Sign: The Profiler Reveals a Render Thread Bottleneck
3 Reasons to Keep Draw Calls at Bay
Fight the Battle: Batching Unity Draw Calls
Requirement: Merging Unity Materials
Technique 4: Run-Time Batching API
See Draw Call Batching in Action
IMG_20200107_205117
Taken with my Nokia 3210
My Background Story
Just a few years ago, I was an inexperienced young lad... Especially when it came to game programming.
I was working on one of my first professional assignments and my task was clear.
I just had to improve and implement several gameplay systems for an existing game.
Fair enough.
So that's what I focused on for months. Creating fun for my players it is.
The thing is, every other area in game development remained pretty much unknown to me.
And I couldn't stop asking myself...
What if I have to put off a fire in one of these areas I have no idea about?
That simple thought made me very uncomfortable. After all, I didn't want to disappoint my boss. He hired me for a reason so they he expected me to know my stuff.
Yet I knew it was only about time I had to face problems I never dealt with.
And I didn't feel prepared.
In any case, I happily kept adding content and worried no further. Everything was going smoothly and I received good feedback on my work.
Even better, performance was great all long...
Until it wasn't.
After several months, I noticed something was off.
I went to the stores and started noticing more and more negative reviews.
I was used to a certain proportion of negative reviews. That's always part of exposing your work to the world.
But the trend worried me. It was getting worse than ever.
More users started complaining about battery draining faster, the device heating more than ever and the gameplay feeling too slow.
It took me some time to connect the dots.
That must be the performance thing, I thought.
I started worrying that I messed up the user experience.
Even worse, what would my client think of me? It surely had to be the work I did on gameplay.
Worry quickly transformed into stress.
I was used to stress. After all, I often spent over 12 hours a day at the University just a few years before.
But this time it was different. It was not about me anymore. It was about real people that I was disappointing.
Armed with courage, I started digging into the unknown world of performance.
And that I did especially over my free time.
I quickly learned about the Unity Profiler. That valuable tool showed me how the render thread appeared to be taking just too long. But I didn't know why.
So I kept investigating.
However, no matter how much time I put in, problems arose faster than I could fix them.
I was about to give up.
Maybe game development wasn't for me, after all.
But then, I became one of the luckiest developer of the world.
I was lucky enough to come across a great online article about technical debt. And I realized I dug my own graveyard.
But at the same time, I became inspired.
Over time, I introduced content that exploded the amount of unity draw calls I had in the game. And draw calls were supposed to be kind of requests to draw something on the screen.
Are 130 draw calls too much? Yeah, that must be it, I thought. I added non-optimized content that is causing the battery drain and slow gameplay, so now I just need to optimize it.
So I got to work and started the long journey of optimizing my materials. After all, draw calls were highly related to the material setup in Unity. The juicy over-hours were on me. I caused that problem, so I was ready to suck it up.
I couldn't stop thinking about the long-term problems, though.
If I had this problem, chances were other people had it as well.
As I saw it, the only way to solve this problem was to create processes to continuously monitor performance metrics.
That was my second job.
In a matter of days, I implemented a prototype system to continuously monitor the number of unity draw calls in the game. I wanted to make sure people submitted only optimized content in the future, especially myself.
Still, I struggled to keep the deadlines.
I knew I had to be resilient. And that I became.
With endless effort, I unified game materials substantially and greatly reduced the number of shaders.
This long journey brought me to a draw call count well under 60.
Performance was great again, as everyone held to the performance guidelines. The processes made sure of that.
And I was proud of that.
However, I still had my inner voice reminding me about these players that I upset.
They used to have great times playing the game. They made friends through it. They went as far as to strengthen their relationships with their family members.
That's why I worked hard to alleviate the pain they showed through the reviews.
But these players never came back. I lost them forever.
And that was heart-breaking.
Losing these players taught me how important it was to monitor performance all along the project.
Loading times, frame-rate, performance spikes, battery and power efficiency... All of that way matters more than I thought.
This was one of the defining moments that made me focus so heavily on game performance optimization. I learned the lesson.
The game is still performing well today. And thanks to the optimizations, the ports to weaker platforms became much easier.
Ever since then, I monitor the performance of my games almost daily.
But I don't do this alone.
I have systems in place that report me these numbers automatically. When something is off, I go and investigate.
Monitoring unity draw calls is now more important than ever with Virtual Reality gaining so much traction. We have to render at consistent frame-rates of 72, 90 or even 144 Hz. Those timings don't give you a substantial CPU budget.