What I have
- Terrain chunks of size 64x64 meters in a custom format
- PVR textures
- OpenGLES2 renderer
- GLSL shader
None of the above can be changed in any way, i.e. I can't modify the existing code of shader or change the renderer.
Terrain
Each terrain chunk consists of 64 tiles of size 8x8 meters and are placed in a grid. Each tile has 3 layers of textures so theoretically there can be 192 different textures per chunk.
The way I currently load terrain is via script. I create a mesh for every tile in a chunk, so that's 64 meshes per chunk.
Shader
The shader input consist of:
- 3 textures and their texture mask
- 3 matrices
- minor stuff
The matrices needed are calculated in every frame in the following way:
var M = _object.transform.localToWorldMatrix;
var V = Camera.main.worldToCameraMatrix;
var P = Camera.main.projectionMatrix;
_material.SetMatrix("WorldViewProjectionMatrix", P * V * M);
_material.SetMatrix("WorldViewT", (V * M).transpose);
_material.SetMatrix("World", M);
What I need
Loading the entire terrain would take a lot of time and resources, so I only load the nearest chunks depending on player position and its a 5x5 chunks area. And still on average I have:
- 25 chunks
- 25 * 64 = 1600 tile meshes
- 25 * 64 = 1600 materials
- up to 25 * 192 = 4800 different textures (only theoretically! Currently there is no more than 20-30 per chunk and the average across loaded chunk is about 300 textures)
- about 6400 matrix operations
The amount of materials does not seem to have a huge impact on performance, but the matrix calculates make the fps drop from ~80FPS to ~12. I could've reduced the matrix operations down to 100 if I could render single chunk as a single mesh instead of 64 submeshes, but I don't see a way to properly pass the textures to shader.
So basically what I need is an approach that would allow me to render terrain chunk as a single mesh and a way to pass different textures for different tile parts of a mesh. Do I even look in the right direction?