I update a mesh created procedurally. What bothers me is that it seems to be slow (on iPad2 my performance drops from 26-27 FPS to 22 FPS). My mesh has around 3200 vertices and is updated like this:
I don’t even call any Clear or any other methods and don’t make any additional assignments. Just substitute vertices.
Is my performance drop expected in this case to be that big? In general, Unity’s dynamic batiching (for particles for instance) does not seem to slow down the game that much, so why would mine be so slow?
So there are several places where things can be slow here:
the “determine new vertices” part. How complex are the calculations there?
the actual changing of the underlying vertex buffer, sending that off to the graphics driver etc.
You can figure out which one is slow by either using a profiler (connect unity editor’s profiler to the game on the device; or use built-in iOS “console profiler”), or by process of elimination. For example make the code that “determines new vertices” much simpler and check what is the performance difference.
for (int i = 0; i < newVertices.Length; i++)
{
newVertices[i] = originalVertices[i];
newVertices[i].y += 1.0f;
}
if (updateVertices)
mesh.vertices = newVertices;
Graphics.DrawMesh(mesh, UnityEngine.Matrix4x4.identity, material, 0);
I’ve also just examined how the update behaves with much smaller number of vertices (16). Basically the same problem. 30-31 FPS when the mesh is not updated (possibly even more because of vsync) and drops to 24-25 FPS when updateVertices bool is set to true.
I also cannot profile as we don’t have Unity Pro for iOS yet.
Calling newVertices.Length for every vert you update is costly. It’s faster to store that before doing your loop. I’m guessing copying the array over in one lump before starting the loop (rather than doing the copying per entry during the loop) could be a bit faster, too.
newVertices = originalVertices;
for (int i = 0, int length = newVertices.Length; i < length; i++)
{
newVertices[i].y += 1.0F;
}
if (updateVertices)
mesh.vertices = newVertices;
Graphics.DrawMesh(mesh, UnityEngine.Matrix4x4.identity, material, 0);
I also found that, at least in Javascript, this was far faster at iterating through verts. Not sure if it holds true for C++. It ended up being a significant speed improvement in JS, though. It means that it goes backwards through the array, but it’s a much faster conditional evaluation.
newVertices = originalVertices;
int length = newVertices.Length - 1;
while (length)
{
newVertices[i].y += 1.0F;
length--;
}
its the mesh rebuild that takes some time, correct.
Creation of VBO and uploading it.
You might want to test out 3.5.2 if you didn’t do that yet to ensure its not related to the 3.5.0 / 3.5.1 VBO creation regression.
Yes 3.5.2 has the iPhone splash issue but thats meant to be worked out with 3.5.3 and I doubt your app is done before that so you are fine (and even if not ,returning to 3.5.1 is possible without problems)