Dispatching individual draw calls (gl.drawElements) for every sprite on screen creates severe CPU-to-GPU bottlenecking. High-performance 2D engines (like PixiJS and custom WebGL renderers) achieve 60 FPS across tens of thousands of sprites by buffering vertex coordinates, texture coordinates, tint colors, and texture indices into a single interleaved Float32Array.
1. Interleaved Vertex Structure Layout
| Attribute Name | Data Type | Bytes per Vertex | Shader Location & Purpose |
|---|---|---|---|
aPosition | 2 x Float32 (x, y) | 8 bytes | Screen space quad vertex coordinates. |
aTexCoord | 2 x Float32 (u, v) | 8 bytes | Normalized UV coordinates inside the texture atlas. |
aColor | 4 x Uint8 (r, g, b, a) | 4 bytes | Vertex tint and alpha transparency. |
aTextureId | 1 x Float32 (id) | 4 bytes | Index of the bound sampler2D texture slot in shader. |
