[SOLVED] Problem with alpha blending when drawing sprites from RenderTarget2D

Hello, I’m new here and hopefully I’m not posting this in the wrong place.

I have been working on a ‘small’ pet project that started in the days of XNA 3. I put it on Ice when MS killed XNA and finally I was able to get it working again with MonoGame. It started out as a web application, a browser game if you like and slowly evolved into a client program, based on XNA, that connects to the server over web services. A homebrew 3D engine renders and animates scenes in the background and a (also homebrew) UI provides the actual gameplay. Sure beats motionless webpages. Here is a recent screenshot:

The UI inherited a problem from its XNA 3 origins: Rendering spritefonts was changed from nonpremultiplied to premultiplied. The settings remained the same when I ported everything to XNA 4, so rendering text still worked well without changes.

Now, with MonoGame, I can’t set the spritefonts to be prepared nonpremultiplied anymore. I had to set the BlendState to BlendState.AlphaBlend when drawing the UI, like this:

SpriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.Default, oState);

With this change the text looked fine again, but a new problem has appeared, which I could not yet fix. The controls of the UI are drawn in two stages. When property changes in a control demand it to be redrawn, the new appearance is rendered into a RenderTarget2D object. then, when a frame is rendered, the rendering thread simply walks through the control tree of the UI and draws the texture from each control, also with a SpriteBatch set to BlendState.AlphaBlend.

Now this is the problem: Controls can have transparent backgrounds. Now, with AlphaBlending, the alpha value of the background color has no effect anymore. It seems locked to a certain degree of transparency, no matter what value the alpha value of the background color actually has.

The background of the RenderTarget2D objects is set by the following line. When drawing nonpremultiplied, this worked perfectly.


As I see it, clearing the RenderTarget2D with the color does not work. I must use a value that makes the texture in the RenderTarget2D a premultiplied texture, but I’m not sure how to do that.

Can’t you just make a custom blend state, and look up what parameters were used in the XNA blendstates?

Edit: relevant? https://blogs.msdn.microsoft.com/shawnhar/2010/04/08/premultiplied-alpha-in-xna-game-studio-4-0/

Just coming home fom work. Thanks for yor reply. The link indeed is relevant. I have quickly tried the Color * Alpha formula described there and got plain white as a result.

I’m going to follow the link and look at the math behind that. Since I’m rendering into the bitmap that is supposed to have premultiplied colors, I will probably have to think in the reverse. Something like Color * (255 - Alpha).

Luckily there is little redundancy in my classes, so there is only one method that needs to be changed and everything should be well again.

It works now! My guess was very close. It turned out that the backround color had to be calculated this way:

Color * (Alpha / 255), assuming that Color.A = 255

The transparent backgrounds of the controls now are rendered as before without AlphaBlend. The problem may return in other drawing functions, but now I know what to do about it.

Thanks for pointing me in the right direction. Is there a way to mark this question as solved?