Help with normal map effect

Hi and thanks for all your work.

I’m trying to add normal mapping to my 2D game. I made it work with one sprite with a shader (if you need it I’ll attach it), but I don’t understand how should I draw the whole scene. Basically the question is: “what’s the correct order to draw a lot of sprites with different normal maps?

Consider I have to draw a ground tile map and on top of it I have some other objects like a jar.

I did this:

protected override void Draw(GameTime gameTime)
{
    GraphicsDevice.Clear(Color.Black);

    _normalMapShader.Parameters["LightDirection"].SetValue(_lightDirection);

    // Tile map ground draw
    _normalMapShader.Parameters["NormalTexture"].SetValue(_cellNormalMap);
    _normalMapShader.CurrentTechnique.Passes[0].Apply();
    _spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, _normalMapShader);
    for (int col = 0; col < GraphicsDevice.Viewport.Width; col += _cell.Width)
        for (int row = 0; row < GraphicsDevice.Viewport.Height; row += _cell.Height)
        {
            _spriteBatch.Draw(_cell, new Vector2(col, row), Color.White);
        }
    _spriteBatch.End();

    // Jar draw
    _normalMapShader.Parameters["NormalTexture"].SetValue(_jarNormalMap);
    _normalMapShader.CurrentTechnique.Passes[0].Apply();
    _spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, _normalMapShader);
    _spriteBatch.Draw(_jar, new Vector2(200, 200), Color.White);
    _spriteBatch.End();
   
    // Other different objects the same way
    // ...
    // ...

    base.Draw(gameTime);
}

It works, but I wonder if it is bad to call SpriteBatch.Begin for each kind of object, in this case for each different normal map I would have different begin call.

Are there other possibilities? Am I doing it wrong?

Thanks!

Behind the scene, this is what SpriteBatch actually does - you fill it with Draw Calls and SpriteBatch will internally group them by similarities (mainly texture). Once you call “End” the Batcher will do the statechanges and do all the draws related to that state.

It doesn’t make that much difference if you add 10 draws with different textures to a single batch or call begin/end 10x

So the way you do it isn’t that bad. The one thing you could improve is having all textures in an Atlas and having another Atlas for the normalmaps - so you can do it all in one batch, but if it’s ust the jar as a single call, you’re not losing much by doing like you did anyway

All right, thanks reiti!