I started experimenting with OpenGL ES 2.0, and I'm trying to figure out a way to optimize/batch sprite drawing, where sprites only have the texture in common, but differ in the following properties:
- Position
- Size
- Rotation
- Texture coordinates
- Color
- Hue
I tried two different approaches, which are "good enough" for most games, but I'm still curious on how I could optimize drawing sprites further. All the code is available here on GitHub, but I'll explain my approaches below.
(Both approaches use 4 vertices + 6 indices to draw a quad.)
One drawcall per sprite.
Position and texture coordinates are passed as a
vec4
vertex attribute. The MVP matrix (that handles size and rotation) is passed as amat4
uniform. Color is passed as avec4
uniform and hue is passed as afloat
uniform.Since pretty much everything is being passed as an uniform, I have to set all uniforms and call
glDrawElements
once per sprite.I can draw 50000 sprites at 60FPS on my desktop (i7 2400k, GTX 970).
One drawcall per
N
sprites.The second idea I had and tried was dividing sprites in batches of
N
. In this approach, everything is passed as a vertex attribute.attribute mat4 a_projection_view_model; attribute vec4 a_pos_tex_coords; attribute vec4 a_color; attribute float a_hue;
From my tests it seems slightly faster than the previous approach, but it isn't a big improvement. Also, passing the same
mat4
and the samevec4
(a_color
) four times seems weird and unnecessarily expensive.I couldn't figure out a different solution since every sprite has its own MVP matrix, color an hue.
How is sprite batching (when the texture is the same) usually done? Are my approaches "correct" in theory, or am I doing something which is considered bad practice?
How can I optimize my sprite drawing?