- Home /
Optimizing and generating terrain on mobile
So I've got my mobile game in which a player is controlling a flying plane over a 1000x1000 terrain. Since I'm flying over a terrain I need it to be huge, so the skybox won't be as visible. I don't really care that much about the quality, it is really simple as of now, there is a trigger when player hits it, but still - drawing the terrain gets my draw calls to over a 100 easily.
While my SGS 6 keeps a steady 60 fps, Motorola G from 2014, which is on Android 6.0, gets down to 14-18 fps, which is unplayable. I tinkered with lighting, quality of images, removing unnecessary assets and other stuff, but it looks to me like terrain is the thing that consumes the most processing power.
How do you guys deal with massive terrains in such situations on mobile? Using meshes somehow? Or do you stick with Unity's terrain?
Terrain is necessarily complex to render, and Unity's inbuilt terrain system is generally not recommend for use on mobiles. That said, you really haven't explained what your particular bottleneck is - there's no point tinkering with random stuff just because it looks like terrain is consu$$anonymous$$g CPU time - use the profiler to see exactly what is taking processing time each frame.
Camera.render drawing seems to be taking the most % after WaitForTargetFPS In editor if I disable terrain I get 29 draw calls, with it on I get 250. What other way would you recommend for making a terrain?
So it sounds you either need to reduce the complexity of your terrain (by decreasing the pixel error value), or use less passes (by using a simpler shader/reducing the number of textures sampled in your splatmap)
I can recommend an asset, Terrain To $$anonymous$$esh. And yes, generally speaking, meshes on mobile. probably working with chunks making use of LODs
It looks like a really great tool. I see many positive opinions. I will think about it if I don't achieve what I want with tinkering and Pixel error
Answer by omerselman · Jul 17, 2017 at 05:48 PM
I have been on the same path for 3-4 months and finally find out how to deal with massive terrains. My terrain suppose to be at least 4k X 4k but i got low fps when i use unity terrain. I have planes, tanks, choppers and tps character in the sceene and i needed an huge open map. My aproach was totally wrong. I tried to make one single terrain holding the whole area with lots of heights. Even 500x500 flat terrain cause low fps. When i increased the tailing and decreased the resolution, got rid of shadows, real time lightining and updates from scripts i couldnt make it more than 40fps. Occ culling didnt help much. The main problem was the terrain itself. Texture quality doesnt matter. The terrain is so dense for mobiles. I used same scene with mesh which has 3 lods and fps jumped to 60. Mesh was 5000x5000 and very mountanious. So what i figured out is; you can combine small terrains with meshes and disable them asap when you are done or use chunked meshes with lods. Either way your fps goes up. I suggest you to draw your terrain with unity terrain, add trees and plans, convert it to mesh,when you sre done use mega splat or a atlas asset and bake the meshes and textures. Slice them as many as possible and use lod. This is the most efficent solution. Disable and enable when the mesh is in view. Hope it helps.
Im using Unity Terrain on my pretty average ASUS Z007 and i have like 45-60fps with moving objects, and real time terrain modification(smoothing, flattening etc) if u use correct resolution Terrain works like charm on mobiles
As i mentioned above i tested with lowest resolutions and highest error rate. I am not quite sure which version of unity you use and what size terrain. I could manage to get 40 with less height (almost flat) and none of my gameobjects were enabled. The size of the terrain and texturing it decrease the fps. Lets check what you do different than me so we can find out a solution; Using 5.6
Camera settings: occoluision culling solid color 500 camera distance 50 view angle Terrain settings: 500x500 Pixel error 200 cast shadow off No tree No grass One texture set for android and 256. Tailing is 100 Lighting : Baked with no real time Fog Shadows off Quality settings Lowest and fastest quality Phone is samsung j10
Hey omerselman, did your terrain have a lot of trees before you converted to a mesh based system? If so, how did you handle that?
you can add trees on your mesh later by writing your own script or you can use speed tree and convert it with trees.T2$$anonymous$$ converts terrain with trees. or you can use this simple script. It is not completed but it works fine. If you use tree meshes use LOD. http://www.gdcvault.com/play/1023191/$$anonymous$$aking-the-World-of she explains very well how to handle. The main objective is not to create something actualy there, create something pretending as it is actualy there.. https://www.assetstore.unity3d.com/en/#!/content/10507 this guy used 3 lod chunked meshes on 10x10 and fps works damn fine. there are 180+ mesh chunks for each LOD and when you get closed to each of them, they switch between LOD gameobjects.
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class TreeSpawner : $$anonymous$$onoBehaviour {
public GameObject[] tree;
public int numberOfTreesWanttoPlace;
public int distanceBetweenTrees;
public int $$anonymous$$inXaxis;
public int $$anonymous$$inZaxis;
public int $$anonymous$$axXaxis;
public int $$anonymous$$axZaxis;
int usedX, UsedZ;
int x, z;
float y = 10000;
float usedY;
Vector3 GeneratedPosition;
Vector3 CheckPosition;
public List<Vector3> usedPositions;
void Start()
{
PlaceTree();
}
public void PlaceTree()
{
for (int i = 0; i < tree.Length; i++)
{
x = UnityEngine.Random.Range($$anonymous$$inXaxis, $$anonymous$$axXaxis);
z = UnityEngine.Random.Range($$anonymous$$inZaxis, $$anonymous$$axZaxis);
usedX = x;
UsedZ = z;
if (x == usedX && z == UsedZ)
{
x = UnityEngine.Random.Range($$anonymous$$inXaxis, $$anonymous$$axXaxis);
z = UnityEngine.Random.Range($$anonymous$$inZaxis, $$anonymous$$axZaxis);
}
GeneratedPosition = new Vector3(x,y, z);
CheckPosition = GeneratedPosition;
if (usedPositions.Contains(CheckPosition))
{
return;
}
else
{
usedPositions.Add(GeneratedPosition);
Vector3 position = GeneratedPosition;
RaycastHit hit = new RaycastHit();
if (Physics.Raycast(position, Vector3.down, out hit))
{
Instantiate(tree[i], hit.point, Quaternion.Euler(-90, 0, 0));
}
}
}
}
}
Very cool, thanks for the script and I watched that entire talk.
With the asset you linked to, how many trees are in the players view at one time? The reason I asked is because I need at least 6000 billboards to show up at a time.
Sorry for late reply, probably you are looking for real imposters asset. Check it, you may like that. If you wanna use mesh ins$$anonymous$$d of terrain, import the mesh, use 3th party design tools, not unity assets. Thats the best way
I've seen that asset but the reviews say that it doesn't work at all on trees. Have you tried it? I have already moved from unity terrain to mesh-based, but I still have to get these trees optimized which are killing my FPS.
Did you say that the trees in that desert pack were well optimized? How many do they render at a time?
If so, what method do they use?
I went with converting Terrain to mesh, huge performance improvements, while of course losing some of the quality, but I'm okay with that. Now I can have huge mesh without worrying too much about fps drops.
Does anyone knows what asset or how did desert starter kit guy used in this project?
Never$$anonymous$$d found it. I been running the sample scene on mobile for more than 3 hours and the FPS is 45-47. In the first hour it was 60 .. That is what i wanted. 10km x 10km and fps is 60.
Your answer
Follow this Question
Related Questions
Is there a way to make unity stop discarding self intersecting geometry? 0 Answers
Why do Unity 5 is glitched as hell? Please, I need help... 0 Answers
Third Person Controller Movement on Elevated Terrain 1 Answer
[Solved]Lighting Job Process using 100% CPU? (Unity 5.1) 1 Answer
Edit Terrain at runtime 1 Answer