Rendering a large amount of sprites and maintaining good performance is a difficult task but thankfully there are some good ways to manage it. I’m going to talk about one of the methods I use to render large amounts of sprites in WebGL.
Given that at the time of writing there is no native support for instancing in WebGL I have had to come up with a way to do this myself. I’m not going to claim that this is the most efficient way to do things and there may be better methods out there so I encourage you to go look and find one that works for you. This way fits my use-case perfectly, although I’m sure I’ll continue to refine it as I go along.
When rendering a good rule of thumb is to reduce the number of calls to
gl.drawElements. So instead of creating multiple vertex buffers that contain each individual sprites vertex data I create one huge buffer that contains all the vertex data for all the sprites. I try to group these into related sprites just to make things easier to manage but that is optional. This means we can just call one draw method and draw all the sprites in one go, however if we want to add another sprite to the list we have to upload all the data again to the GPU. So we need to be able to set these sprites up in advance so not to incur a performance hit, and we need to avoid adding more sprites if necessary while in the main rendering loop.
I created a class to handle this called SpriteBatch. Feel free to read through the commented code and get a feel for how the class works. I’ve talked in an abstract way about the main way the class handles the drawing of large amounts of sprites but I always find it’s helpful to see some actual code. I won’t go through the code here as I think it’s pretty simple, feel free to comment and ask questions if necessary and I’ll answer anything as best I can.