2
\$\begingroup\$

This my main draw call:

       Matrix Camera_transformation = player_camera_.GetTransformation();

        // Background - AlphaBlend
        spritebatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, null, null, null, null, Camera_transformation);
        background_.Draw(spritebatch);
        spritebatch.End();

        // Particles (of a player power, I want them behind him!) - Additive
        spritebatch.Begin(SpriteSortMode.Deferred, BlendState.Additive, null, null, null, null, Camera_transformation);
        player_.DrawParticles(spritebatch);
        spritebatch.End();

        // Player - Alpha Blend
        spritebatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, null, null, null, null, Camera_transformation);
        player_.Draw(spritebatch);
        spritebatch.End();

        // Hub/Ui - Not to be influenced by the camera, but always on top
        spriteBatch.Begin(); 
        UI.Draw(spritebatch)
        spriteBatch.End();

Is there a way to reduce the number of calls here? If my particle system didn't need an additive drawing, I would have merged the first three calls, but I can't. Is there something I am missing about spritebatch ordering?

\$\endgroup\$
4
  • 1
    \$\begingroup\$ What are you trying to achieve here? A performance improvement? Or do you literally want to reduce the number of C# method calls? Because the code you have there is basically optimal for performance, as far as SpriteBatch internals go. \$\endgroup\$ May 22, 2014 at 2:56
  • \$\begingroup\$ I would like to achieve better performances. I tried the suggestion below, but after profiling several times, I found it gets worse performances. \$\endgroup\$
    – user31021
    May 22, 2014 at 6:33
  • 1
    \$\begingroup\$ Note that profiling this kind of thing can be tricky - for example: is it the CPU or GPU slowing you down? As I said, at this stage you've basically maxed-out the performance for SpriteBatch (providing every particle you draw uses a single texture - see here). To improve performance, you have to go beyond SpriteBatch. If the CPU is slowing you down (and it probably is), perhaps you need to offload onto the GPU (rough example here). \$\endgroup\$ May 22, 2014 at 6:48
  • \$\begingroup\$ Does SpriteBatch have support for premultiplied alpha blending? This lets us combine additive and standard alpha blending into a single formula, so they can be drawn together in a single batch or even mixed within a single sprite. \$\endgroup\$
    – DMGregory
    Jul 19, 2021 at 11:34

1 Answer 1

0
\$\begingroup\$

Changing the SpriteSortMode to Immediate is faster in the cases when the overhead of creating new batches is more signifigant than the time saved by batching. If this is the case in your situation the below will be faster. While the mode is immididate you can alter the GrahpicsDevice's state and it will impact subsiquent draw calls.

    Matrix Camera_transformation = player_camera_.GetTransformation();


    spritebatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, null, 
        null, null, null, Camera_transformation);

    // Background - AlphaBlend
    background_.Draw(spritebatch);

    // Particles (of a player power, I want them behind him!) - Additive
    GraphicsDevice.BlendState = BlendState.Additive;
    player_.DrawParticles(spritebatch);

    // Player - Alpha Blend
    GraphicsDevice.BlendState = BlendState.AlphaBlend;
    player_.Draw(spritebatch);
    spritebatch.End();

    // Hub/Ui - Not to be influenced by the camera, but always on top
    spriteBatch.Begin()
    UI.Draw(spritebatch)
    spriteBatch.End();
\$\endgroup\$
1
  • 2
    \$\begingroup\$ Uh... the only time Immediate mode is faster is when you've only got a couple of sprites per batch. So unless that particle system has, like, three particles in it, you're going to want to use Deferred. \$\endgroup\$ May 22, 2014 at 3:01

You must log in to answer this question.