Mesh vertices manipulation performance / understanding Mesh.GetNativeVertexBufferPtr

Hello!

I’m trying to figure out the best way to do fast runtime mesh manipulation, on meshes with high vertex counts (~50000).
On my machine (gtx970) a multi-threaded approach and setting mesh.SetVertices a few times every frame runs like butter.
But on a friends machine (gtx770) the games fps drops from 200 to sub 100!

I’ve noticed that the mesh.SetVertices call is the main problem.
After searching the forums i found a new approach: “Mesh.GetNativeVertexBufferPtr”.
And also a good example: https://bitbucket.org/Unity-Technologies/graphicsdemos/src/43011994ae74ebf5e39bfe0055990cb349a4ae09/NativeRenderingPlugin/

In the example project, it seems to cycle through all the vertices to apply the manipulations. But isn’t this slow again?
Would it not be better to do the manipulations on a separate thread and just pass the result?

Some insight and explanation from someone who knows this stuff would be great!
Thanks!

For our current game we needed a custom trail renderer and had a similar problem. We tried setVertices which probably does a lot more that just setting the vertex array (the docs are very sparse about what actually happens) and it was not fast enough for us.

Additionally we only wanted to add/update a handful of vertices in the array not all of them at once. I briefly looked into Native plugins, but did not investigate it much farther, fearing that I would have to write plugins for each platform we gonna support.

What we ended up using are compute shaders and compute buffers. Depending on your target hardware level this can be a fairly good way to work around that. If the hardware supports it, then it is very likely that you can run the same setup on all supported platforms.

Depending on your workload, offloading it to a compute shader could really be the right thing to do. If it is something simple, like updating particles, then the GPU is probably much better suited to the task anyway.

In another instance, we have a simple CPU particle system, that outputs the particle positions into a point computeBuffer, where we then expand every point to tetraeder in the geometry shader.

tldr; Take a look at ComputeBuffers and shaders, and see if your workload is better suited for the GPU or CPU.

3 Likes