Dynamic Update of Mesh

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:

// determine newVertices

mesh.vertices = newVertices;

if (mesh)
	Graphics.DrawMesh(mesh, UnityEngine.Matrix4x4.identity, material, 0);

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?

You shouldn’t have to call drawmesh on it.

You can simply substitute your modified vert position array back into the mesh and the engine will draw it as per normal.

But I want to render the mesh with DrawMesh. The mesh is controlled entirely via the script and I want to find the most optimal way of updating it

just update the vertex array. thats the most optimal you have (the only thing you have to update a mesh unless you do it through a vertex shader)

Just keep in mind that drawmesh will disable dynamic batching if you hoped for that.

Is it not what I am doing right now? I mean, is the code I posted in the first point doing this or is there a better way to update the vertex array?

I don’t. I am doing sort of “manual” batching; that’s why I am asking about the most optimal way of updating a mesh :slight_smile:

The code you posted is ok.

So there are several places where things can be slow here:

  1. the “determine new vertices” part. How complex are the calculations there?
  2. 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.

I already did the code simplification. Now it just shifts vertices in one axis by some constants. Performance stays the same.

Saw a thread on iPad2 slowdowns with dynamic meshes the other day which was saying Unity might have an issue http://forum.unity3d.com/threads/118723-Huge-performance-loss-in-Mesh.CreateVBO-for-dynamic-meshes-IOS

That should not be relevant here. I do not recreate the VBO every time I update the mesh (I guess)

How do you “shift vertices up”? Paste the code :wink:

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.

Try something like this?

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--;
}

It’s not the update process that is slow, but the final assignment of newVertices to mesh.vertices

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)

I tried benchmarking that out of curiosity (assuming you meant newVertices[length].y += 1), and there’s definitely no difference in speed at all.

–Eric

Aw, perhaps it’s a JS thing? This was probably 3.1 or 3.2 I was testing it with, blending between 2 morph targets.

I found it made an appreciable difference to my frame rate at the time (as opposed to a for loop with a cached length variable).

I’m not big on C#, but I do recall that it was specific to javascript, I just thought that it might apply to C# too :slight_smile:

No, that’s what I used for the test.

I tested 3.4 and 3.5. Just tested 3.2 now, same thing, sorry.

–Eric

Huh… very strange. My project literally jumped from 5-6FPS to 30 when I optimised my loop and to about 35 when I tested that version.

Oh well, I lost the project data in a disk death a while ago so I can’t even go fiddle with it. Perhaps something else changed at the same time.