Blending mode issue

Hi there,

Having a bit of problem understanding how blending works in a specific situation.

My game is drawing things on separate RenderTarget2D’s. Then, I draw all the RenderTarget2D’s onto the final game window.

As such, I draw scenery and characters on one RenderTarget2D, let’s call it CAMERA.
Then, I draw the UI on another RenderTarget2D, let’s call this one UI.

CAMERA:

Begin(
        SpriteSortMode.FrontToBack, // (because I have characters that I want to preserve Y sorting to)
        BlendState.NonPremultiplied,
        SamplerState.PointClamp);

	// draw to CAMERA here

End()

UI:

Begin(
        SpriteSortMode.Deferred,
        BlendState.NonPremultiplied,
        SamplerState.PointClamp);

	// draw ui elements here

End()

DRAW TO GAME WINDOW:

Begin(
                SpriteSortMode.Deferred,
                BlendState.NonPremultiplied,
                SamplerState.PointClamp
            );

// draw CAMERA to game window
// draw UI to game window

End();

My problem is when drawing to UI. I am creating some buttons and I want them to have a hover effect. As such, for a button:

  • I draw a background of a solid color;
  • I draw an overlay with a solid color AND alpha starting from 0 going to max depending on hover state;
  • Hover state increments from zero when entering the button and decrements as soon as mouse leaves button;

What I expected to obtain is a nice transition from color A → color B, so any increased transparency on B reveals more of solid color A;
What I get is a sort of color mix where the alpha is somehow translated to the result for the whole layer, because I can see through it in the middle of the hovering, see here:

I tried several combinations of blend states for drawing the UI and GAME WINDOW, but no change.

What am I missing here?

I found the problem. The default available blend states were not sufficient for my requirement. After quite a bit of trial and error, I found that this below custom blend state has the desired effect, even if you have another layer rendered beneath it:

static BlendState blendCustom = new BlendState() {
    ColorSourceBlend = Blend.SourceAlpha,
    ColorDestinationBlend = Blend.InverseSourceAlpha,

    AlphaSourceBlend = Blend.BlendFactor,
    AlphaDestinationBlend = Blend.InverseSourceAlpha
};

In my example, the UI needs to be drawn using this custom blendstate instead of what was there before.

Result: