Basic Bandwidth Load Optimization Best Practices
Before any advanced optimizations are considered, there are a few high-level best practices that should be followed to minimize the initial bandwidth load.
Mesh triangle density
The simplest optimization that you can make is reducing the total vertex count in the 3D models. This gives a proportional reduction in vertex bandwidth. Therefore, you need to simplify all 3D models used. For mobile content, we recommend an upper limit of 250,000 input triangles per frame, which equals ~125K visible triangles after clipping and culling.
Mesh attribute precision
Adjust the data types used to store data in memory. While you can consider treating everything as 32-bit
GL_FLOAT data types, for many use cases - such as storage of color data - this level of precision is too high.
Instead, use 16-bit
GL_HALF_FLOAT, or packed formats such as
GL_INT_2_10_10_10_REV, to minimize storage footprint and data fetch bandwidth. Then, order fields in memory and be ensure that you minimize any buffer space lost to padding.
Intermediate data storage that is required to store vertex shader outputs can be minimized by ensuring that outputs are stored at
mediump precision rather than
Mesh spatial locality
Modern GPU s are reliant on data caches to keep recently accessed data close to the processor, rather than constantly fetching data from main memory. The vertices for triangles that are close together on screen must be stored close together in the attribute buffer.
Dynamic mesh level-of-detail
For 3D games with highly variable scene depth, consider using a dynamic mesh level-of-detail, that selects simpler meshes as the distance between the camera and the object increases. An example of a mesh with a dynamic level-of-detail can be seen below:
When an object is only 50 pixels high, it is not necessary to use a model that uses 5000 triangles. This is because very few sample points are hit and they are therefore made completely redundant.
When reviewing meshes, check the obvious render state settings that impact mesh processing. For example, whether face culling is correctly enabled for opaque meshes.