Procedural Mesh - Lag

Hi again,

I’ve now implemented my procedural code into a landscape but everytime I click to destroy a block it really lags.

My mesh is 25x10x25. It gets worse when I increase the mesh to 50x10x50 though.

Everytime I click a block it gets removed then my GenerateMesh script is run to recalculate the mesh.

This is my code:

function GenerateMesh()
{
	var mesh = voxelMesh.GetComponent(MeshFilter).mesh;
	mesh.Clear();
	
	var newVertices = new Vector3[0];
	var newTriangles = new int[0];
	var newUVs = new Vector2[0];
	var newColors = new Color[0];
	var newNormals = new Vector3[0];
	
	_triangles = [ 0, 1, 2, 2, 1, 3 ];
	var _topNormals = 		[Vector3( 0, 1, 0), Vector3( 0, 1, 0), Vector3( 0, 1, 0), Vector3( 0, 1, 0)];
	var _bottomNormals = 	[Vector3( 0,-1, 0), Vector3( 0,-1, 0), Vector3( 0,-1, 0), Vector3( 0,-1, 0)];
	var _frontNormals = 	[Vector3( 0, 0,-1), Vector3( 0, 0,-1), Vector3( 0, 0,-1), Vector3( 0, 0,-1)];
	var _backNormals = 		[Vector3( 0, 0, 1), Vector3( 0, 0, 1), Vector3( 0, 0, 1), Vector3( 0, 0, 1)];
	var _leftNormals = 		[Vector3(-1, 0, 0), Vector3(-1, 0, 0), Vector3(-1, 0, 0), Vector3(-1, 0, 0)];
	var _rightNormals = 	[Vector3( 1, 0, 0), Vector3( 1, 0, 0), Vector3( 1, 0, 0), Vector3( 1, 0, 0)];
	
	for(x=0; x<dim.x; x++)
	{
    	for(y=0; y<dim.y; y++)
    	{
    		for(z=0; z<dim.z; z++)
    		{
    			if(gridArray[x,y,z] != 0)
    			{
    				//////////////
    				// Vertices //
    				//////////////
    				
    				var y1 = y * -1;
    				
    				frontVertices = 	[Vector3(x,y1,z), Vector3(x,y1+1,z), Vector3(x+1,y1,z), Vector3(x+1,y1+1,z)];
			    	topVertices = 		[Vector3(x,y1+1,z), Vector3(x,y1+1,z+1), Vector3(x+1,y1+1,z), Vector3(x+1,y1+1,z+1)];
			    	leftVertices = 		[Vector3(x,y1,z+1), Vector3(x,y1+1,z+1), Vector3(x,y1,z), Vector3(x,y1+1,z)];
			    	rightVertices = 	[Vector3(x+1,y1,z), Vector3(x+1,y1+1,z), Vector3(x+1,y1,z+1), Vector3(x+1,y1+1,z+1)];
			    	backVertices = 		[Vector3(x+1,y1,z+1), Vector3(x+1,y1+1,z+1), Vector3(x,y1,z+1), Vector3(x,y1+1,z+1)];
			    	bottomVertices = 	[Vector3(x,y1,z+1), Vector3(x,y1,z), Vector3(x+1,y1,z+1),Vector3(x+1,y1,z)];
			    	
					
					////////////
					// Coding //
					////////////
					
					if(CheckGrid(Vector3(x,y-1,z)) == 0)
					{
						// Draw Top Face
						newVertices += topVertices;
						newTriangles += _triangles;
						newColors += [colorArray[x,y,z],colorArray[x,y,z],colorArray[x,y,z],colorArray[x,y,z]];
						_triangles = IncreaseIntArray(_triangles, 4);
						newNormals += _topNormals;
					}
					if(CheckGrid(Vector3(x,y+1,z)) == 0)
					{
						// Draw Bottom Face
						newVertices += bottomVertices;
						newTriangles += _triangles;
						newColors += [colorArray[x,y,z],colorArray[x,y,z],colorArray[x,y,z],colorArray[x,y,z]];
						_triangles = IncreaseIntArray(_triangles, 4);
						newNormals += _bottomNormals;
					}
					if(CheckGrid(Vector3(x-1,y,z)) == 0)
					{
						// Draw Left Face
						newVertices += leftVertices;
						newTriangles += _triangles;
						newColors += [colorArray[x,y,z],colorArray[x,y,z],colorArray[x,y,z],colorArray[x,y,z]];
						_triangles = IncreaseIntArray(_triangles, 4);
						newNormals += _leftNormals;
					}
					if(CheckGrid(Vector3(x+1,y,z)) == 0)
					{
						// Draw Right Face
						newVertices += rightVertices;
						newTriangles += _triangles;
						newColors += [colorArray[x,y,z],colorArray[x,y,z],colorArray[x,y,z],colorArray[x,y,z]];
						_triangles = IncreaseIntArray(_triangles, 4);
						newNormals += _rightNormals;
					}
					if(CheckGrid(Vector3(x,y,z-1)) == 0)
					{
						// Draw Front Face
						newVertices += frontVertices;
						newTriangles += _triangles;
						newColors += [colorArray[x,y,z],colorArray[x,y,z],colorArray[x,y,z],colorArray[x,y,z]];
						_triangles = IncreaseIntArray(_triangles, 4);
						newNormals += _frontNormals;
					}
					if(CheckGrid(Vector3(x,y,z+1)) == 0)
					{
						// Draw Back Face
						newVertices += backVertices;
						newTriangles += _triangles;
						newColors += [colorArray[x,y,z],colorArray[x,y,z],colorArray[x,y,z],colorArray[x,y,z]];
						_triangles = IncreaseIntArray(_triangles, 4);
						newNormals += _backNormals;
					}
    			}
    		}
    	}
    }
    
    mesh.Clear();
    mesh.vertices = newVertices;
    mesh.triangles = newTriangles;
    mesh.colors = newColors;
    mesh.normals = newNormals; 
    mesh.Optimize();
    
    voxelMesh.GetComponent(MeshCollider).sharedMesh = null;
    voxelMesh.GetComponent(MeshCollider).sharedMesh = mesh;
	voxelMesh.renderer.material = voxelMaterial;
}

It also lags just as much when I remove mesh.Optimise();

Can anyone spot the problem causing the lag?

I presume you are regenerating the entire mesh every time you add or remove a block. This is why it’s laggy, I think.

To resolve this you can try the following, or both together:

  • Split the mesh up into chunks of say 8x8x8. When you remove or add a block, only perform any mesh operations on the chunk that it resided within, and on any neighboring chunks if edge blocks were modified.
  • Figure out a way to retain as much of the original information as possible when updating the mesh, instead of starting over from scratch, if this can be done so efficiently. Perhaps by marking only the changed areas as “dirty” and only reconstructing them.