Shaders, Post-processing, and SpriteBatch handling questions

Hey there, I’m working on a project that requires having some shaders applied to individual sprites, and post-processing as well. As far as I have researched, I must call spriteBatch.Begin(effect); then draw the sprites and the end the batch, then all sprites rendered inside that batch, have the same shader applied.

My questions are:

  • Does it affect (and how much) to the game’s performance having many batches?
  • Is there a way of applying the shader to the sprite without starting new batches?
  • How can I implement post-processing?

At the time i made this post I only have two batches: the one for HUD Render and the one for content in scene.

Well, i’d be glad if someone guide me the right way. I’m still a bit new to Monogame and to C# in general, so sorry if these questions sound a bit dumb. :grinning:

What matters is how many times those batches have to flush. Single batch can end up in many drawcalls depending on how batchable is what you are rendering and if you are rendering it in deferred mode in the first place.

One drawcall (flush) = one shader.

Minor note, just to set on in right direction, question you asked has basically nothing to do with C# and relatively little to do with Monogame (beside understanding what spritebatch actually does). Info you are looking for is from area of general basic rendering, so if you want to know more search for things like: Drawcall, VertexShaderStage, PixelShaderStage and you will find what you need.

Spritebatch, in deferred mode simply takes all you provide it from .Draw and tries to (fairly inefficiently) combine what it can into single drawcall. Draw with different texture for example will cause forced flush (hence drawcall).

Depending on complexity of your project, if you do not plan something absolutely basic I advice against using spritebatch and rather developing own simple sprite rendering system that you can make as simple or complex as you see fit.

Best of luck!

Additional note: you will see people on this forum telling you how bad is to have hundreds of drawcalls. Unless you are aiming on mobiles or ancient HW, few THOUSANDS are fine, especially if they are not hit by overhead caused by inefficiency of spritebatch implementation.

Thanks for the advice.

Rendering stuff seems overwhelming to me. Two more things, can you explain me why is Draw method inefficient? And finally, Is there any good resource to learn about how graphics work under the hood?

Edit: I found https://learn-monogame.github.io/tutorial/first-batcher/ I think it answers my first question here. I will analyze the code there to try understand.

By Draw in this context I mean pretty much anything that causes drawcall, including custom geometry, rendering model, etc. MG has lot of safety and abstraction that takes a toll. Especially way it currently handles constant buffers has its performance issues. For relatively simple typical indie games it won’t matter.