Unity: The little default setting that kills mobile performance I wished I knew sooner (TLDR: It's Vulkan)

Hey all! I just found out about something that quite possibly gave me the biggest "BRUH" moment in my career as a Unity developer. I just want to share this experience of discovery with you all and who knows? Maybe this is new to you too (it probably isn't).

So let's talk about an innocent little default setting of any newly-created mobile project. Here it is:


 

This doesn't look wrong on its face, right? Vulkan is a low-level graphics API that usually sees better graphical performance and power efficiency in desktop and console games. Surely this is the better choice for graphics API. Or so I thought, so did my colleague think. The thought of Vulkan being the culprit of our game constantly dipping below 50fps even with a very simple scene never crossed our mind.

What my colleague thought was going on was a combination of Linear color space, post-processing effects and HDR causing this performance impact. He ticked on Auto Graphics API, which doesn't let you build with Linear color space, so he switched the color space to Gamma, along with disabling post-processing and HDR to produce a build. Sure enough, it performs better, maintaining 60fps for at least 100 3D objects on the screen.

But something doesn't seem right to me. I made my own build with HDR and post-processing disabled, but left the default values on the Player settings for Android and... the old performance dips return. Huh... So Linear color space is the culprit after all? That can't be right, Linear color space has some overhead comparatively to Gamma, but none this bad that I've ever heard of. That's when I started wondering something: What is it really using when I tick on "Auto Graphics API"? Through some runtime print-debugging using Unity In-Game Debug Console (Disclosure: I am a contributor to this project, the author of this project did not sponsor me to promote it), I found out that it was running on OpenGLES3.

This gave me an idea to start an experiment. I'm going to compare 2 builds: Build #1 with Gamma color space, HDR and post-processing disabled, BUT Auto Graphics API turned off, making Build #1 use Vulkan. Build #2 goes in the opposite direction - Linear color space, HDR and post-processing enabled, even MSAA 2x thrown in for good measure, all the performance overheads we thought were the issue. Build #2 has one more difference: I enforced it to only use OpenGLES3 as the graphics API.

The results are wildly beyond my preconceived expectation: https://imgur.com/a/iEDeKsv

Build #1 and #2 are represented in screenshot #1 and #2 respectively. The FPS number in both screenshots are on the top-left corners. Unity Vulkan performance is so bad and slow that stacking the overhead of Linear color space, post-processing, HDR and MSAA 2x on top of OpenGLES3 is still faster.

This is when I started searching around to see if anybody has seen worse performance on Unity Vulkan on mobile and sure enough, I found some, but not enough:

https://forum.unity.com/threads/vulkan-works-very-slowly.479189/

https://forum.unity.com/threads/vulkan-api-poor-performance.501381/

Well, add this post to the list of complaints toward Unity Vulkan for mobile. Please spread this awareness around. It's bad enough that a nominally low-level graphics API could run so unexpectedly slow on this engine, but the fact it is set as the default graphics API for mobile should be a source of shame.

Unity Technologies, your Vulkan renderer is not ready for production, not even in your LTS releases, and not even in your latest 2021 releases. Yes, I tried the Vulkan renderer in 2021.1.18f1 too, the performance is still bad. The least you could have done is putting OpenGLES3 on top the list of default graphics API and mark Vulkan as one of your preview/experimental features.

Thank you for reading. This post was written after many hours of building and experimenting on my own. I hope my time was not wasted and hope this awareness spread far and wide among Unity mobile developers.

Comments

Popular posts from this blog

A better way to get letterboxing in Unity

CSS-like layout for Unity UI - Lessions from web development workflow

SortedAction - Guaranteeing order of execution in pure C# delegate