Sprite batching performance

Started by
39 comments, last by Totologic 9 years, 1 month ago

OK thank you for you benchmark, it gives me a good start.

I start to implement a layer managing sprites sharing UV and with fixed scale and rotation. A kind of tile based renderer.

I hope this layer will reach several thousand of sprites.

My blog about games, AI...

http://totologic.blogspot.com/

Advertisement

While almost finished my tile renderer, I took time to build a new benchmark for my sprite renderer:

window 1200x800px

9600 sprites, sharing 25 textures 200x200px, with opacity (alpha 1 or 0)

each sprite is scaled 1/10 and rotated continuously

so the screen contains 80 lines of 120 sprite of size 20x20px

the offset between each sprite is 10px, so each sprite is completely overlaped by his 8 neighbours

I reached average of 16ms per frame, so around 60fps wub.png

(edit: my laptop was under battery... with energy plugged I reach 10ms per frame)

A capture of my screen:

[sharedmedia=gallery:images:6161]

My loop code:


glm::mat3 matTransf;
int i;
float t = 0.0f;
float t2x, t2y, rot, sx, sy, t1x, t1y;
while (!glfwWindowShouldClose(window))
{
	toto2d.clear();
	toto2d.setCameraLookAt(600.0f, 400.0f, 0.0f, 1.0f);
		
	for (i=0 ; i<9600 ; i++)
	{
		t1x = -100.0f;
		t1y = -100.0f;
		rot = t;
		sx = 0.1f;
		sy = 0.1f;
		t2x = (i%120)*10.0f;
		t2y = (i/120)*10.0f;
		Utils::mat3TRST(t2x, t2y, rot, sx, sy, t1x, t1y, matTransf);
		toto2d.getSpriteMatrixLayer().addSpriteMatrix(200*(i%5), 200*((i/5)%5), 200, 200, matTransf);

		if ((i > 0) && ((i % 799) == 0)) // the sprite layer can render 800 sprites max
			toto2d.getSpriteMatrixLayer().render();
	}

	if ((i % 799) > 0)
			toto2d.getSpriteMatrixLayer().render(); // render the last sprites on the list
	toto2d.swap();

	t += 0.01f;

	/* Poll for and process events */
	glfwPollEvents();
}

My blog about games, AI...

http://totologic.blogspot.com/

Are you filling in vertex buffers for each render?
Are you double-buffering them or even triple-buffering them?


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

About double buffering, I must admit I trusted GLFW:

http://www.glfw.org/docs/latest/quick.html#quick_swap_buffers

So I setted glfwSwapInterval(1) and then called glfwSwapBuffers(window) every frame when my rendering is finished.

Is it correct ?

About vertex buffers, I would say no, even if it is more complicated than that...

My blog about games, AI...

http://totologic.blogspot.com/

Actually I think I don't undertand your question about double buffering because you seem to speak about the vertex buffers.

My blog about games, AI...

http://totologic.blogspot.com/

He is asking if you double buffer your vertex buffer, not the framebuffer.

Updating the same buffer each frame between draw calls makes it so your render thread has to wait until the driver gives the heads up that the buffer wont be used anymore and the copy (update) can be made.

If you double or triple buffer your vertex buffers you'll be giving more time for the GPU to use each buffer when drawing.

"I AM ZE EMPRAH OPENGL 3.3 THE CORE, I DEMAND FROM THEE ZE SHADERZ AND MATRIXEZ"

My journals: dustArtemis ECS framework and Making a Terrain Generator

Mmmh OK.

But in fact I dont have any vertex buffer.

My blog about games, AI...

http://totologic.blogspot.com/

Then how are you drawing anything?


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

Ummm.... Correct me if I'm wrong but isn't the point of a sprite batcher to render as many sprites as possible with as few drawcalls as possible. Why are you only rendering 800 sprites at a time when you could just render them all at once. The only reason that I can think of are memory constraints but a batchsize of 800 is kinda low even for that.

Ummm.... Correct me if I'm wrong but isn't the point of a sprite batcher to render as many sprites as possible with as few drawcalls as possible. Why are you only rendering 800 sprites at a time when you could just render them all at once. The only reason that I can think of are memory constraints but a batchsize of 800 is kinda low even for that.

Aren't you limited to one combination of shaders and textures per draw-call? So if you need to switch what (multiple) textures and shaders are bound, you have to split that up into separate drawcalls, right? (I'm rather ignorant in this area, so this is an actual question)

This topic is closed to new replies.

Advertisement