Game Development Updates

Unity Android Performance Choices

Publishing a game on Android for as large an audience as possible means you need to get your game running on the widest range of devices as you can. You also need to balance that with making something that is fun and appealing and makes good use of the technology. Its 2019 and when I started my projects I looked around to try and find a sensible target device that would allow me to test my game’s performance. I didn’t want to just pick the latest and greatest phone (eg, Samsung’s flagship, currently an S10) but something that would represent a reasonable amount of users.

Phone spec’s haven’t changed dramatically, number of cores have generally doubled (quad to octa) and CPU speed has risen by about 15% (2.4Ghz to 2.8Ghz), GPU speeds have increased by around 30% (550Mhz to about 750Mhz).

I looked at a range of current mid and budget priced android phones, and settled on supporting OpenGL ES3. I chose to try and support reasonable 5 year old phones, something around the spec of a Samsung Galaxy Note 3 or a OnePlus 1.

The GPUs get recycled over time. Right now I can buy a Xiaomi Redmi 7A from Giffgaff for £99. A 5.45 inch 720 x 1440 phone, with Snapdragon 439, 2.0 GHz (2 quad core) Cortex-A53 and an Adreno 505 GPU (650MHz OpenGL ES 3.1 ).

Test Devices

Device CPU Memory GPU 3D API Screen Year Type
Nexus 7 Quad-core 1.2 GHz Cortex-A9 1 Gb Tegra 3 T30L (12-core 416 MHz GeForce ULP) OpenGL ES 2.0 800 x 1280 2012 7 inch Tablet
Samsung Note 10.1
Quad-core 1.4 GHz Cortex-A9 2 Gb Mali-400MP4 (1 Vertex / 4 fragment processors) 440 MHz OpenGL ES 2.0 800 x 1280 2012 10.1 inch Tablet
HTC One X 1.5 GHz quad-core ARM Cortex-A9 MPCore 1 GB Tegra 3 T30 (12 Core 520 MHz GeForce ULP) OpenGL ES 2.0 720 x 1280 2012 4.7 inch phone
Samsung S4
Quad-core 1.9 GHz Krait 300 2 Gb Adreno 320 (16 core 400 MHz) OpenGL ES 3.0 1080 x 1920 pixels 2013 5.0 inch phone
LG G2 Quad-core 2.26 GHz Krait 400 2 Gb Adreno 330 (32 cores 450 MHz) OpenGL ES 3.1 1080 x 1920 2013 5.2 inch phone
OnePlus One Quad-core 2.5 GHz Krait 400 3 Gb Adreno 330 (32 cores 450 MHz) OpenGL ES 3.0 1080 x 1920 2014 5.5 inch phone
Nvidia Shield Quad-core 2.2 GHz Cortex-A15 2 Gb GeForce Kepler (192 cores 950 MHz) OpenGL 4.4 (Shader Model 5) 1200 x 1920 2014 8 inch tablet
Moto G5 Octa-core 1.4 GHz Cortex-A53 2 Gb Adreno 505 (48 cores at 450 MHz) OpenGL ES 3.1 1080 x 1920 2017 5.0 inch phone
Nexus 6P Octa-core (4x2.0 GHz Cortex-A57 & 4x1.55 GHz Cortex-A53) 3 Gb Adreno 430 (192 cores at 650 MHz) OpenGL ES 3.1 1440 x 2560 2015 5.2 inch phone
Sony Xperia XZ Quad-core (2x2.15 GHz Kryo & 2x1.6 GHz Kryo) 3 Gb Adreno 530 (256 cores at 624 MHz) OpenGL ES 3.1 1080 x 1920 2016 5.2 inch phone

My test devices have been; a OnePlus 1 (2014), Nexus 7 (2012) and a Samsung Galaxy Note 10.1 (tablet 2012). My aim was for smooth play on the OnePlus, and a playable but compromised experience on the older tablets.

I hadn’t appreciated the major difference in specification between OpenGL ES2 and 3. Lots of optional technology in 2 is guaranteed in 3, the most noticeable is having a depth texture, this is used to provide real time shadow support in Unity, without a depth texture there is no shadow map. So to support OpenGL ES2 devices you need to support not having a depth texture, so blob shadows or build your own tech. Trying to get shadows working on my OpenGL ES2 devices used up a lot of my time, I’d recommend being pragmatic about it and taking a path of least resistance, those devices are slowly disappearing don’t expend energy on it!

In an ideal world, keep your vertex count under 100,000, shader passes to under 100, particles count less than 100 (and simple).

Final point; I used the mobile shader variants - but I also tested with the Standard Shader and that change didn't have huge impact, not sure if the standard shader falls back to lambert when compiling for Android?