Huge FPS Drop in Android

Hey,

We are trying to create a simple ball game for android and we are facing a big problem with the FPS of our game.

Everything runs smoothly on Editor but when we compile and play with an android device we get 11-16 FPS!
It’s too low to play the game comfortably!

cell: Galaxy S5 Neo
tablet: Galaxy Tab E

We decided to create a simple demo project for anyone that want to check the problems with a sample.
The project is a simple menu with a scroll view to select the level.
2 scenes, first one use unity terrain and the second one use pure 3d cube to create the terrain.
UI is made with uGUI.

We have 45-50 FPS in the main menu.
With a Title and a Scroll View with 14 buttons.
Why do we lose that much FPS for almost nothing ?

In the unity terrain scene we have a drastic fps drop, we have 10-15 FPS.
The terrain is quite simple and is using 2 textures on the terrain and 3 prefabs for rock, tree, chest.
There is not a lot of those object in the scene.

In the 3D Cube terrain the FPS is not quite bad, 35-45 FPS!
We used different textures to show more textures that we are using in our real game.

  • We use “solid color” for our camera because we have seen that it could cause an FPS drop but it didn’t change anything.
  • We also tried a lot of other solutions found on the internet, but nothing got it back to a good FPS.

We did check the profiler, but we didn’t really get anything to help us to find the problem.

  • Device.Present taking so much time
  • Camera.Render.Drawing take a bit of time but it’s not too bad i guess

We are doing a pretty simple game and we don’t know why our FPS are that low.

Here is the project demo.
https://www.dropbox.com/s/gg76w3x4yxqsgox/BMDemo.zip?dl=0

all password for android build are => maison

Thx in advance to all of you that will help.
We are in need of community help! :slight_smile:

1 Like

Device.Present could mean 2 things as described in:

I’ll open the demo project later, kind of busy right now

Let me know when u will check the demo!

Just downloaded it, going to check it out right now
It will take some time analysing, so have some patience

no problem :wink:

we really appreciate your time, as a new team, it will help us to understand what’s wrong.
And which thing we need to work or check when building for mobile! (Android atm)

1 Like

I love optimizing things, I am not a total expert thats just a heads up.
I am sharing my experience that I’ve gained over the years of development.
If anyone from the community notices I’m wrong, please do correct me :slight_smile:

[Setup]
I used Unity 5.6.0p3 (didn’t have 5.5.x installed)
I use an iPhone 6s as testing device and Metal as Graphics API
Used IL2CPP as scripting backend

[Target Frame Rate]
The mobile devices always use V-Sync this can cause the FPS to be locked at 30.
I’ve set Application.targetFrameRate = 60;
In a Start method. (You might want to try that as well, since you’re trying to target 60 fps)
Might want to put a log there as well get the target frame rate before setting it to 60.
So that you know whether it is standard set lower than you want.

The only thing noticable besides that is that according to the profiler culling took its sweet time when tiny noticeable spikes occurred while moving the ball a bit more quick.
Camera.Render totally took 53.1% at that frame (3.06 ms)
Culling took 29.3% (1.69 ms)
whereas Drawing only took 15.9% (0.91 ms)

Device.Present is renamed to Gfx-WaitForPresent in later versions
The following is a quote from a Unity representative somewhere on the forum
Two reasons why it would show up:

Device.Present doesn’t necessarily mean that that is the problem.
The CPU is probably waiting on the GPU to be finished.

I couldn’t really find anything else slowing the FPS.
I don’t have an other device laying around with lower specs.

[Result]
I’ve reached 60 fps on my iPhone 6s without a problem

Just some other things worth noting (sharing my general experience):

[Player Settings]
Use IL2CPP as scripting backend, it may be slow building but it is faster
Do take in mind that IL2CPP builds you can’t get a stacktrace from logs.
So debugging will be a little bit more difficult if you want line numbers but you can fix that in the msg itself if you’re smart.

[Texture Sizes]
The button graphic is 2k * 2k in the import settings, you probably don’t need it to be that big for a button, 512x512 would be more than enough. could even try to go for lower suiting the graphics quality you want.
Might also not want to put that into the Resources folder unless it has to be loaded at runtime using Resources.Load / Resources.LoadAsync
If you move it to an other folder you can still use the textures.

[Shaders]
I see you are using specular lighting, this can be quite heavy
Consider using an other shader that is less expensive (Even the normal standard shader can be quite expensive when I was developing for the HoloLens it was quite clear that the normal standard shader was expensive and an unlit the cheapest)

[Lighting]
Bake lighting as much as you can where possible, it saves real-time calculations which could be heavy on the mobile platform.

[Draw Calls - Static Objects]
Make objects that don’t move static, it’s a way of saving draw calls.

[Draw Calls - Dynamic Objects]
if you have a lot of the same object with the same material, you might want to consider using an GPU Instancing enabled shader.
The standard shader has the Enable Instancing boolean at the bottom (I don’t know if this exists pre 5.6 though)
Read https://docs.unity3d.com/Manual/GPUInstancing.html for more info.

2 Likes

thx a lot,

My team next meeting is tuesday but if i have some spare time, i will try to test your advices!

In your tests, did you try the scene with unity terrain?

So here is a list of things i need to do :wink:

  • Set ILL2CPP
  • Set Application.targetFrameRate = 60; in one of our first loaded class. ( we did it in our project and it didn’t change anything, but will try with all the other things may be it will help!)
  • Reduce image to something near their size in the game ?
  • Move things out of Resources folder if they do not get loaded from scripts (shouldn’t hit perf but for clarity?)
  • Find a better shader (Does mobile->unlit (Supports Lightmap) could be use or it will hit perf a lot ?)
  • Baking Lighting (Is there any special setting to configure, as we dont know anything about this fonctionnality, except build!)
  • We did forget about Static Objects, we definitly have a lot of Static Object to set!
  • This option is not there but we will check about upgrading unity to 5.6.
    Using Standard shader + this option for dynamic object will not hit perf too much ?

Sorry if it took time to respond, i got many things to do!

No worries if it takes some time, I’ve got a lot of things to do myself.
The experience sharing is mostly what I’ve learned through reading and experimenting a lot.
Those are tips, and should be considered as such, it is not a must but is good to take in mind.

But starting off with IL2CPP, setting the objects static and reducing the texture size + not using resources may be a good place to start.

  • Reducing image sizes could be lighter for the shader if the shader is reading / applying calculations based on them.

  • Basically things about the Resources folder: https://unity3d.com/learn/tutorials/temas/best-practices/resources-folder
    Don’t use it x’D

  • mobile shaders are made for mobile hence the reason “Mobile Shaders”, they were supposed to be lighter than the normal legacy diffuse shader. Though you should pick a shader that does suit your needs but does not impact performance too much. Unity does it’s best to optimize the standard shader, though during my own experiments with the HoloLens the standard shader was still quite heavy vs an unlit or diffuse shader.
    You got to fiddle a lot with shaders, I’m no shader expert though but theres always the trade off between performance and visual quality. You want your game to look as good as possible but only if the FPS doesn’t drop below x amount.
    You might even just copy the standard shader and edit it to suit your needs and make it lighter for your specific needs.
    Like the trees use a cutout shader with a specular map. Specular map is baked lighting so it doesn’t require additional specular calculations.
    You might want to try out this setup with the standard shader:
    3068276--230669--Unity 5.6.0 Standard Shader.png

  • Baking the lighting correctly is quite a job, but that’s what the specular map is for probably?
    I’m a programmer, not an artist :stuck_out_tongue: I just know a little about shaders since I needed to program them in C++.
    Setting your objects static will allow them to get baked as well.
    There’s a lot on graphics at https://unity3d.com/learn/tutorials/s/graphics

  • The option for Enable Instancing is amazing though from what I’ve seen what you can do with it.
    I guessed it would be a 5.6 feature, 5.6.1 just came out by the way.
    Though I think in your case, setting it static may be enough.
    https://unity3d.com/unity/whats-new/unity-5.6.0
    https://unity3d.college/2017/04/25/unity-gpu-instancing/
    I was actually trying to find the fish+shark demo, its rendering a lot of animated fishes with a shark that scare the fish.

To me graphics vs performance is quite a trial and error
The profiler can give some indication though but not specifically what the problem is.
It doesn’t say X material with Shader Y on Object Z is taking a long time to process (even though that would be awesome)

But what you can do is write Unity Tests and by using the Test Runner you can deploy to the device let the test run.
Just create the FPS counter on the fly, instantiate the objects you want and observe the profiler.
Mostly what you want to do is keep the number of draw calls low.

My test device : Mali T720 MP2 (gpu power 13 compare to s7 was 261)

  1. Change terrain shader from Standard to Legacy diffuse in terrain settings

  2. You have used Realtime GI, turn it off. Also remove Default Skybox

Now 47 fps was 20 fps~

  1. Baked light

47 fps

  1. Changed rock and tree shaders to mobile diffuse

51 fps

1 Like

@MaskedMouse thx for your informations! It definitly help us to understand a little bit more on those fields! We are programmers too and we have someone who can use photoshop. So we didn’t have any person with 3D, Shader, Light background! So we are learning it the hard way! :slight_smile: When i check the tutorials i mostly go in scripts/ui !! I’ve forgotten about other tutorials… shame on us! I chekced other links too, i will have some reading to do!

@aliyeredon2 thx for your tests and your solutions!

We will definitly have some work to do.
We trully appreciate your time as a young team!

If you get more informations we appreciate it and we are always listenning to other’s experience!
I will post which things we did and the result we got in few days!

Sorry if it took that much time to respond!
I got a lot of thing to do in my pipeline!

I tried on a 5.6.1 Unity version.
IL2CPP
TargetFrame = 60 in our FPS CounterScript
Shader => Mobile → Unlight (Support LightMap)
Texture => Import with 256x256
Directionnal Light => Mode Bake
Lighting => Bake
Moved everything from Resources to Rsc
Everything is Static except our camera and ball

Lighting Settings

Camera

We didn’t get the scene with the terrain goes above 15fps.

@aliyeredon2 You talked about terrain shader, can you say where we can set it ? we didn’t find any shader on the terrain! If it’s possible, can you send the project modified by what you tested so we can compare what we didn’t change correctly? Because you have the same GPU from my teammate

How can i calculate the Power of my GPU as you guys mentionned? to compare my tablet and the phone of my teammate! => ok i found it http://kyokojap.myweb.hinet.net/gpu_gflops/

EDIT:

@aliyeredon2
I see in some of your screen shot a FPS Counter, can u show the script you use to see something higher than 60fps ? it never happenned to me even on High-End PC.

hi again

  1. terrain shader
    You need to create a new material and assign terrain splat shader to it and drag created material to Material slot in Terrain Settings tab (on terrain component)

2.fps
I think you cannot display more than 60 fps when Vsync is enabled. I don’t know more about this

Which version of unity do you use? because there is no Terrain Splat Shader, and my terrain accept only Terrain Material and in a Terrain Material there is no shadder.

i use unity 5.6.1

You can use unity internal Legacy Diffuse terrain shader or write your own more optimized terrain shader
i have 2 shaders in my free effects:
https://www.assetstore.unity3d.com/#!/content/72703

I had wrote that originally for unity 4 and then converted to unity 5. I don’t know it works fine or not in unity 5

Ok, i found in Terrain Settings, the Terrain Material.

If i use ur material for my terrains i got this message from unity:

Can’t use materials with shader which need tangent geometry on terrain, use shader in Nature/Terrain instead.

I will test it tomorrow

thx a lot :wink:

I will continue to work on it to find which thing can improve our FPS on low-mid device!

In your case, terrain shader is very important . Because terrain is covered most pixels of the screen

Our problem is fixed for now, we found the terrain material in the terrain settings and changed it for “Built in Legacy Diffuse” and now we et 54 FPS on our low-mid device!

thx your help guys! :slight_smile:
We are happy and understood some of the optimisation process to look at when doing mobile game!