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 (N8010) |
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 (GT-I9505) |
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?