Hey everyone,
I’ve been struggling with drawing an abundance of sprites. To be precise, my game needs to draw a lot of grass. Basically, I use a mesh with a texture that consists of a few blades of grass, which is animated using a wind-shader. To have a nicer effect, I draw a couple of different versions of it with different wind strenghts and use setContext(...)
to create images to use on the spot. This way, I don’t have to create hundreds of meshes that all calculate their shader on their own, but draw the mentioned images using sprite(...)
.
Before the game even starts to draw anything, I use a custom algorithm to distribute the grass across a 2d-plane. At the end, I have a 2d-array with probably thousands of entries, which contains the positions where a grass-sprite should be drawn.
In the actual draw-method, the grass-sprites are drawn. I loop through the 2d-array and draw one of the few variations of the sprite. This amounts to sometimes hundreds of grass-sprites being drawn at the same time, which (obviously) brings down the performance considerably. Only a fraction of all possible grass-positions is drawn at the same time as the 2d-array contains all positions across the entire 2d-plane, of which only a part can be visible since there is a camera that follows the player.
As a result, I thought using a mesh would be beneficial. I created an image grassAtlas = image(...)
, used setContext(grassAtlas)
and then drew all different grass versions next to each other. This way, I thought, I would have one sprite, the grassAtlas, that could be used as the texture and using mesh:setTexRect(...)
, I could set the version for a specific rect that I would be adding by mesh:addRect(...)
. As a result, I would have one single mesh, but could use the same variations of the grass-sprite as before.
As long as I don’t draw the mesh, everything’s fine. I was worried that adding thousands of rects to the mesh could be an issue, but it doesn’t seem to be. However, drawing the mesh instead of the sprites brings down the performance considerably more, even to a point where the game’s basically unplayable. This seems odd to me as drawing the same amount of sprites was heavy on performance, but the game was still running at a decent and stable framerate.
Now I have two questions:
- Should my approach theoretically work? By that I mean: Is my assumption correct that multiple rects of one mesh, which uses a single texture atlas but attributes a different part of said texture using
mesh:setTexRect(...)
to different rects, only require one draw call instead of one per rect? - Is there any efficient way to draw that many rects of a mesh/add that many rects to a mesh? I’m fully aware that both of my approaches are terrible as far as memory consumption and performance are concerned, but I also don’t know of a better one.
Thanks in advance and sorry for the long text!