Trying to use a multiplying blendstate to get results like image editors.

I am trying to draw a room that has a day and night mode.

Here is a stand.

This is the part of the layer that darkens the stand. There is a transparency spot for where an on lamp will go.

When I layer these on top of each other and set the mode of the darkness layer to multiply in an image editor, I get this:

which is correct.

I am trying to replicate this behavior in monogame but the best I am getting is this:

I don’t really know what is happening here and I don’t really understand BlendStates. I created a multiply blendstate based on what I’ve read online:

        multiplyBlend = new BlendState()
        {
            AlphaBlendFunction = BlendFunction.Add,
            AlphaDestinationBlend = Blend.Zero,
            AlphaSourceBlend = Blend.DestinationAlpha,
            ColorBlendFunction = BlendFunction.Add,
            ColorSourceBlend = Blend.DestinationColor,
            ColorDestinationBlend = Blend.Zero,
        };

And I pass this into Spritebatch.Draw() but the results are as above, with a dark orb where the transparency should be. As I said, I don’t really get how this works and I tried some brute forcing with various different settings to no avail.

Hi,

Try to disable transparency when you export your file .png
The neutral element of multiplicative blending is “white”, not “transparent”. Your blend state does not consider the alpha channel at all :wink:

And for multiply in your Draw() method you just need this :

BlendState multiplyBlend = new BlendState()
            {
                ColorBlendFunction = BlendFunction.Add,
                ColorSourceBlend = Blend.DestinationColor,
                ColorDestinationBlend = Blend.Zero,
            };

            spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);
            spriteBatch.Draw(room, Vector2.Zero, Color.White);
            spriteBatch.End();
            spriteBatch.Begin(SpriteSortMode.Immediate, multiplyBlend);
            spriteBatch.Draw(darkness, Vector2.Zero, Color.White);
            spriteBatch.End();

This may be helpful:

Your blend state does not consider the alpha channel at all

Could you elaborate on this? None of the Alpha properties stuff does anything or the way I was setting it wasn’t doing anything? In any case, replacing transparency with white did work.

Hi :wink:,

My english is really bad :sweat_smile:

:sweat_smile:, sorry, this :

AlphaBlendFunction = BlendFunction.Add,
AlphaDestinationBlend = Blend.Zero,
AlphaSourceBlend = Blend.DestinationAlpha,

That change nothing

I can explain without writing too much in English the solution if you want.
You want to create a Multiply BlendState like Photoshop :

First you need to understand how works ColorBlendFunction :

ColorBlendFunction = BlendFunction.Add // already setting

That means : (Source * SourceBlend ) + (Destination * DestinationBlend)

If we want only multiply Source and Destination
We have : Source * Destination + Destination * Zero

So :
SourceBlend = Destination : ColorSourceBlend = Blend.DestinationColor
DestinationBlend = Zero : ColorDestinationBlend = Blend.Zero

1 Like