Page 2 of 4

Re: Any way to get canvases to be more efficient?

Posted: Sat Feb 22, 2020 2:32 pm
by pgimeno
If you use sprite batches but omit the draw calls, is it still slow? (you'll obviously not see anything, but this is about FPS)

Re: Any way to get canvases to be more efficient?

Posted: Sat Feb 22, 2020 4:17 pm
by Sky_Render
The canvases are 4096x4096; it actually gets slower if I make them any smaller or larger, for some reason that seems to be a "sweet spot". The maps thus far range in size from 256x256 to 1024x1024 pixels, but I see the exact same lag no matter which map is being rendered. It's a "top-down Zelda-style" game where the screen scrolls to keep the player centered on screen when not at the edge of the map, with rendering handled based on player position and screen coordinates. The tiles are 16x16, meaning the maps range from 16x16 to 32x32 tiles right now (not very big, in other words). The tileset size is nearly irrelevant in the canvas method since I've extracted each tile image to its own spot in memory, but they are mostly about 16X16 arrays.

The slowdown with the SpriteBatch method only happens when drawing. I get 60FPS with nothing rendered with either method, and it takes effectively the same amount of time to load the game either way.

Re: Any way to get canvases to be more efficient?

Posted: Sat Feb 22, 2020 4:20 pm
by raidho36
So you're doing up to 20k sprites per frame, well that's pretty much nothing, my old GPU could do 100k sprites per frame without slowing down. You're clearly doing something very silly with your graphics related code.

Re: Any way to get canvases to be more efficient?

Posted: Sat Feb 22, 2020 5:28 pm
by Sky_Render
raidho36 wrote: Sat Feb 22, 2020 4:20 pm So you're doing up to 20k sprites per frame, well that's pretty much nothing, my old GPU could do 100k sprites per frame without slowing down. You're clearly doing something very silly with your graphics related code.
I don't think I'm doing anything that strange. Unless you're not supposed to issue draw commands in love.draw, which seems like it would be counterintuitive. It is running on an Acer E5-575, but even at that the graphics card on that system is an Intel HD Graphics 520, which should certainly be able to handle a load like that without too much issue. I wonder, though... Are non-draw instructions parsed slower in love.draw than elsewhere? If so, I think I may well have an answer to at least part of the issue.

Re: Any way to get canvases to be more efficient?

Posted: Sat Feb 22, 2020 5:35 pm
by slime
It's hard for me to be sure without seeing your code/assets (or a .love), but it really sounds like you're bottlenecked by the number of pixels being processed on the GPU. Each sprite you draw will run code on the GPU for each pixel its geometry touches, even if something else overlaps it and even when the sprite has transparent pixels. That can add up quickly if you have a lot of overlapping sprites.

That being said, providing an example that demonstrates the problem which we can run might reveal something else going on.

Re: Any way to get canvases to be more efficient?

Posted: Sat Feb 22, 2020 5:44 pm
by Sky_Render
If that's the case then don't quite get how you're supposed to render large numbers of layered objects properly. I mean I'm only drawing to the screen once technically since what's outputted is assembled to a master Canvas that's exactly the screen resolution, but that doesn't seem to affect the efficiency one iota. Is it because the final assembly of said Canvas from other Canvases happens in the love.draw function? I am very confused, to say the least.

Re: Any way to get canvases to be more efficient?

Posted: Sat Feb 22, 2020 5:50 pm
by slime
Sky_Render wrote: Sat Feb 22, 2020 5:44 pm Is it because the final assembly of said Canvas from other Canvases happens in the love.draw function? I am very confused, to say the least.
If I'm understanding what you're doing correctly, then yes - drawing to the main screen or to a canvas is effectively identical in terms of performance, if you're drawing to them every frame (although if you draw to a canvas typically you'll also want to draw the canvas to the screen in the same frame, which costs additional performance because it's more pixel shaders run by the GPU than otherwise).

If you can provide a .love or something, we might be able to suggest alternate ways to achieve the same visual effect that you want, without impacting performance as much.

Re: Any way to get canvases to be more efficient?

Posted: Sat Feb 22, 2020 5:56 pm
by Sky_Render
I would settle for a simple explanation of how you can "touch every pixel only once" when you have many, many layers that need to be rendered over one another. Because from what I can tell from this conversation, that is patently impossible by any method. How do you render layers efficiently? SpriteBatches aren't cutting it, Canvases are showing limitations, and I can't find anything in the Wiki suggesting an alternative to either or anything in there explaining a proper layer-rendering methodology that cuts down on operations. I've already pared down how much is drawn per layer as low as I can get it at this point, but I still keep running into the same limitation of 15 to 20 layers before slowdown sets in.

Re: Any way to get canvases to be more efficient?

Posted: Sat Feb 22, 2020 5:59 pm
by slime
What's an example of a game that accomplishes the same visual effect you want to do? Maybe we can work backwards from there.

Re: Any way to get canvases to be more efficient?

Posted: Sat Feb 22, 2020 6:01 pm
by raidho36
It crossed my mind that overdraw could be problematic, but with simple 2d pixel shaders and not particularly huge overdraw factor, I don't believe that's an issue.

Can you post your project file? Cut the music though.