Wednesday, September 4, 2019

unity - Performance of manipulating a mesh in realtime



Does Unity allow streaming mesh data that can be continuously changed?


I have a level that is dynamically changing based on some parameters. The number of triangles stays the same, they just change positions.


I'm speaking of around 2000 triangles that need their position updated each frame (they follow a spline that is computed on CPU), running on mobile phones.


I can't use a TrailRenderer because the object is a whole level. I can't use bones, because I need to know the final position for each vertex for my custom collision code.


The mesh should be marked Mesh.MarkDynamic.



Answer



Yes, you can change a mesh at runtime.



  1. get the current mesh from your object using Mesh mesh = GetComponent().mesh. Alternatively, if you want to replace the mesh with a completely new one, create one with Mesh mesh = new Mesh(); and assign it to your object with GetComponent().mesh = mesh;

  2. When you intend to modify the same mesh every frame, you should call the MarkDynamic() method on it. This might improve performance in that situation (thanks, Kroltan).


  3. Modify the Mesh object. It is a reference-type, so any changes you make will be reflected by the object which owns the mesh. For a minimum functional mesh you need to set at least its .vertices and .triangles component, if you want it to be textured also the uv component. If you are really just going to change the positions of vertices of an existing mesh, then the .vertices property is likely the only one you need. But keep in mind that you have little control over the order in which your 3d modeling program saves the vertices of a 3d model, so a slight change to the model can mean that the indexes of all vertices change in a completely unpredictable way.

  4. When you are finished, call mesh.RecalculateNormals which is required by almost every shader to calculate brightness levels correctly.

  5. The .tangents component is also important for some shaders, especially those which use bump mapping. The documentation warns that it needs to be set after you updated the normals.

  6. If you use that mesh for a MeshCollider, you should also call mesh.RecalculateBounds. You mentioned you are doing collision detection all by yourself, so this might not be necessary in your case, but it might be necessary for other people.


Unity also made an example of procedural mesh generation as a complete project on the asset store available for free.


Will it be fast enough for mobile phones? That depends on countless factors, like what kind of mobile phone you are talking about, how often you are going to change the mesh, how effective your mesh changing algorithm is, what shaders you are using and much more. You need to test it for yourself. By the way, if your changes will usually be localized, it might help to break down your terrain into multiple sub-objects and only update the meshes of those which were affected.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...