- Home /
Very Low FPS rendering only meshes
I've been working on a game that generates/renders a fractal terrain at runtime using meshes. I was doing this on very small power of 2 sized maps and everything was fine. As soon as I increased the size to 128x128 the application became a slide show.
I culled my project down to a bare bones test case. I was trying to find why the performance is so low with only 32k triangles, but without luck. I'm hoping I've missed something simple.
Admittedly I have a pretty old machine. it's a dual core 3.1ghz with 4gb of ram and directx 9. It does have an nvidia gtx460 gpu however.
I created a new project with 3 objects and 1 script. The default camera, an empty game object with my script attached to it, and a third empty game object. The third one is a prefab with a mesh renderer, mesh collider, and mesh filter attached. I disabled vsync in the project settings.
Here's my lone script:
using UnityEngine;
using System.Collections;
public class gen : MonoBehaviour {
public Transform mt;
private Mesh mesh;
private MeshFilter mf;
private MeshCollider mc;
private MeshRenderer mr;
private int size = 129;
void Start ()
{
CreatePlaneMesh();
for (int x=0; x<size; x++)
{
for(int z=0; z<size; z++)
{
Transform tr = Instantiate (mt, new Vector3 (x*3f, 0f, z*3f), Quaternion.identity) as Transform;
}
}
}
public void CreatePlaneMesh()
{
mesh = new Mesh ();
mf = mt.GetComponent<MeshFilter> ();
mc = mt.GetComponent<MeshCollider> ();
mr = mt.GetComponent<MeshRenderer> ();
mf.mesh = mesh;
Vector3[] vertices = new Vector3[]
{
new Vector3( 1, 0, 1),
new Vector3( 1, 0, -1),
new Vector3(-1, 0, 1),
new Vector3(-1, 0, -1),
};
Vector2[] uv = new Vector2[]
{
new Vector2(1, 1),
new Vector2(1, 0),
new Vector2(0, 1),
new Vector2(0, 0),
};
int[] triangles = new int[]
{
0, 1, 2,
2, 1, 3,
};
Vector3[] normals = new Vector3[]
{
new Vector3( 0, 1, 0),
new Vector3( 0, 1, 0),
new Vector3( 0, 1, 0),
new Vector3( 0, 1, 0),
};
mesh.vertices = vertices;
mesh.uv = uv;
mesh.triangles = triangles;
mesh.normals = normals;
mesh.RecalculateNormals ();
mc.sharedMesh = mesh;
}
}
No update methods. Nothing else in the project. When I run it in the webplayer I get sub 20 frames per second. That seems very low when rendering <25k triangles on screen. The docs state you should keep your triangle count under 3m on a desktop, so I'm really confused. It pegs one of my cpu cores at 100% so I'm guessing this is CPU limited instead of GPU limited.
Is there some simple gotcha I've overlooked here? I plan to cull distant/hidden objects in the future, but I'm concerned about the low FPS.

On my old laptop, which was lower spec that your PC, changing a simple mesh a runtime using the method you are using caused a massive frame rate drop. Down to 1 - 2 fps. I had to take this out of Update and do it via an Invoke method that only ran 3 times per second, that got me back up to about 20 fps.
Answer by tanoshimi · Oct 28, 2014 at 02:07 PM
If you're trying to create a procedural terrain, you're going about it the wrong way. What your script does at the moment is create 16,641 (129x129) individual game objects, each consisting of a single quad plane.
Dynamic batching is kicking in which is saving your draw calls, but there will be signicant overhead in those 12,113 dynamically batched meshes. Then, I imagine the real killer is you're assigning a mesh collider (the most expensive type of collider) to all 16,000 objects in the scene.
If you want to create a procedural terrain mesh, you need to be calculating the vertices in a single shared mesh, not lots of tiny ones.
Thanks! This was the direction I needed to go. I changed the code to use a single mesh and the frame rate goes up to 2,500fps while rendering 10k quads on screen.
Unity cried when I tried to create a mesh with more than 65k vertices, but I can work around that. I understand the mesh collider is expensive, but I do want collision detection on my terrain.
Thanks again.
Your answer