In my game, I procedurally generate tile map mesh and modify it when travelling around the "world". Each tile is a quad. So they each, have their own UV points. (Obviously)
I am using Unity for this, and in Unity, i can't have more then 65k vertices in a single mesh.
So i made this "tile mesh", chunk based. It's still a single mesh. But while I am creating it, i first create the "chunks", (which are 16x16 quad meshes), then i "merge" the chunk meshes to create the tile map mesh.
I keep these "chunk meshes" in a list. So basicly i merge all the meshes in the list when i want to "update" the tilemap mesh.
While i am travelling in the world, i can remove farthest chunk from list, and add new chunkes when it's necessary. List capacity is fixed to 9, so i can never exceed the "65k vertices limit".
Now the problem is, when i zoom out in game, there becomes almost 40k vertices in the scene since whole mesh becomes rendered. (Actually since it's a single mesh, it always renedered as whole, but the animation doesn't occur out side of the camera view)
But when i zoom out, there are like atleast (6x6)x(16x16) = 9.216 tiles. Which makes 36.864 vertices (and UV points).
Now updating few tiles (so few uv points) is easy. But updating the whole 36k point takes like 1-2 seconds. Which is really bad for updating animation in that way.
The code snippet for single quad uv update is here
public void SetTile(Coord chunkCoord, Coord tileCoord, Sprite sprite)
{
Vector2[] uv = meshFilter.mesh.uv;
Rect spriteRect = sprite.textureRect;
int chunkIndex = SearchForChunk(chunkCoord);
if (chunkIndex == -1)
{
Debug.LogError("Chunk not found");
return;
}
int ui = chunkIndex * (16 * 16) + (tileCoord.Y * 16 + tileCoord.X);
ui *= 4;
uv[ui] = ToUV(new Vector2(spriteRect.xMin, spriteRect.yMax), sprite.texture);
uv[ui + 1] = ToUV(new Vector2(spriteRect.xMin, spriteRect.yMin), sprite.texture);
uv[ui + 2] = ToUV(new Vector2(spriteRect.xMax, spriteRect.yMin), sprite.texture);
uv[ui + 3] = ToUV(new Vector2(spriteRect.xMax, spriteRect.yMax), sprite.texture);
meshFilter.mesh.uv = uv;
}
It takes chunk coordinate, and finds that chunk in the chunk list, so i can get the index of that chunk mesh for UV array.
The sprite that i get as a parameter is in a "sprite atlas", so i call a helper function to convert it's rectangle to uv points.
That's how i update a single tile's UV points.
But It's too slow, how can i optimize it, make it faster?