[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?
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)
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.
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.
“You better spend well the little technical budget you have in VR” –Rubén Torres Bonet
Signs You Have Too Many Draw Calls
At any specific moment during gameplay, there are some important signs to watch for.
Over time, you'll develop a sixth sense that will spawn some chills running down your spine whenever you experience these situations.
However, symptoms are just symptoms. They do not always reveal a draw call problem, as bottlenecks can origin from many corners. To make the distinction more clear, I divided them in two categories.
Soft symptoms are a weak indication for high draw calls; they can perfectly come from other performance factors such as overdraw.
Lastly, hard signs are those that strongly show that your game might have too many draw calls.
Soft Sign: Battery Draining Too Quickly
Phone batteries usually last for a day or two under average use.
But games excel at stealing the energy from your users' lithium ions.
However, realize that power consumption varies across different games. Optimized games will relax your CPU and GPU so they consume fewer watts.
And optimizing your game is important because your users became pretty good at noticing how much battery your game takes for breakfast.
Even if you didn't care about your users (who doesn't?), this is still a relevant factor for you.
This is why...
Efficient games let your players play for longer sessions. And the more they play, the more money will land in your pocket (or your employer's). More In-App Purchases sold, more ads consumed, more word-of-mouth marketing, you name it.
Optimizing for battery is a good return on investment.
Soft Sign: Device Heating Up
Most of the energy you take from your users' devices is converted into heat (and light). Surprise.
This might be handy in winter to warm up your hands. But still, there are 3 seasons left where your users would prefer to go around without a portable battery pack.
I still remember my times in Berlin ordering Glühwein just to warm up my hands during winter. I didn't enjoy the wine-based drink, but I learned to appreciate the warm sensation in my hands.
So I kept buying it.
If you're targeting a VR headset, you should especially optimize for energy efficiency. That is, unless you're developing an application to replace a conventional face tanner.
Soft Sign: Game-Play Not Running Smoothly
You're playing a slow-paced multi-player shooter.
But as you're new to it, so everybody plays it better than you.
After hours of frustration, you finally have your chance: a distracted sniper.
You're sneaking upon him from behind. They didn't notice you yet, but you know it's only about time they turn their back to you. So you get ready to aim for the perfect head-shot.
You slowly move your mouse to aim a few pixels higher.
But after a delay of half a second, your cross-hair is now suddenly pointing at the sky.
The sniper notices you and by the time you realize it you're already dead.
What the hell has just happened?
Now, low performance could happen for multiple reasons, such as garbage collection, but a high amount of unity draw calls is surely one of them.
I remember the early days of Counter Strike where people with the beefiest GPUs threw smoke grenades to gain an unfair advantage. Players with low-end computers couldn't really handle smoke that well, so they ended up dying of low frame-rate. This was probably more due to overdraw than draw-calls, but I still find it memorable to mention.
Soft-Sign: VR Users Look Paler Than Ever
The lower your VR game performs, the worse your users will feel.
Wait, I can say this in a different way.
The more potential draw calls you have, the worse your worst case becomes.
Yeah, that's better.
“Performance spikes are the quickest way to convert VR players into patients” –Rubén Torres Bonet
Hard Sign: Unity Profiler Reveals a Render Thread Bottleneck
If your render thread is taking too long to execute, chances are you have too many draw calls. Or worse, you might have too many SetPasses (we'll see the difference in the next section).
Your main thread is probably just idling around while the render thread finishes processing all draw calls.
You can identify this situation through the Unity Profiler, as seen below.
Unity Draw Calls: Expensive Render Thread
The more of these signs you have, the higher the chances are that your game has way too many draw calls.
And we've been speaking about draw calls for a long time.
But what's exactly a draw call?
Wait... What's a Draw Call?
Simply put, a draw call is your CPU asking your GPU to draw something.
It's your CPU saying: hey, draw this chair in that corner over there with these textures and lighting information.
If you have many "things", then you prepare many draw calls:
- I want a chair in that corner
- And also another chair there in the other corner
- Oh, and a bookcase as well.
The issue is, preparing unity draw calls steals a huge portion of your CPU time and energy. Unity has to convert yo