I have problems alpha blending multiple RenderTarget2Ds. The following is the minimal reproductible example:
`protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.TransparentBlack);
// FIRST CIRCLE
var renderTarget = CreateRenderTarget();
GraphicsDevice.SetRenderTarget(renderTarget);
GraphicsDevice.Clear(Color.TransparentBlack);
_spriteBatch.Begin(blendState: BlendState.AlphaBlend);
_spriteBatch.Draw(_whiteCircleTexture, new Vector2(0,0), Color.White * 0.5f);
_spriteBatch.End();
GraphicsDevice.SetRenderTarget(null);
_spriteBatch.Begin();
_spriteBatch.Draw(renderTarget, new Vector2(0, 0), Color.White * 0.5f);
_spriteBatch.End();
renderTarget.Dispose();
// SECOND CIRCLE
var renderTarget2 = CreateRenderTarget();
GraphicsDevice.SetRenderTarget(renderTarget2);
GraphicsDevice.Clear(Color.TransparentBlack);
_spriteBatch.Begin(blendState: BlendState.AlphaBlend);
_spriteBatch.Draw(_whiteCircleTexture, new Vector2(0, 0), Color.White * 0.5f);
_spriteBatch.End();
GraphicsDevice.SetRenderTarget(null);
_spriteBatch.Begin();
_spriteBatch.Draw(renderTarget2, new Vector2(400, 0), Color.White * 0.5f);
_spriteBatch.End();
renderTarget2.Dispose();
base.Draw(gameTime);
}
private RenderTarget2D CreateRenderTarget()
{
var pp = GraphicsDevice.PresentationParameters;
return new RenderTarget2D(GraphicsDevice, pp.BackBufferWidth, pp.BackBufferHeight, false, pp.BackBufferFormat, DepthFormat.Depth24Stencil8, 0, RenderTargetUsage.PreserveContents);
} `
What I want to achieve is to create RenderTarget2D, draw a semitransparent white circle, blend this RenderTarget2D to the screen and repeat this with another (slightly shifted) circle. The result should be something like this:
But no matter what I do, always only the second circle is visible. Could you please help me with this?
I think you might need to use BlendState.NonPremultiplied instead of BlendState.AlphaBlend. You also aren’t using any blend state in your second begin call, so I think it will just go to the default of AlphaBlend? I can’t remember what it is… but maybe.
Hmm ok, was worth a shot. Whenever I’m having troubles, that’s almost always the culprit. I have to run out but I’ll try to remember to check this out. You’ve posted some code so it should be pretty easy to play around with. Nothing else obvious jumps out at me.
When you switch to a render target, and then switch back to the backbuffer, the backbuffer will loose it’s content. You have to render to both render targets first, and then draw them to the backbuffer in one go.
you can draw them in a chain under the default settings.
public float motiony = 0;
protected override void Draw(GameTime gameTime)
{
var elapsed = gameTime.ElapsedGameTime.TotalSeconds.ToFloat();
motiony += elapsed;
if (motiony > 1.0f)
motiony = 0f;
GraphicsDevice.Clear(Color.CornflowerBlue); // Clear backbuffer.
GraphicsDevice.SetRenderTarget(rTargetA); // Set the drawing target to be a off screen rendering buffer.
spriteBatch.Begin();
spriteBatch.Draw(dotTexture, new Rectangle(0, (int)(motiony * 100), 100, 100), Color.Yellow * .5f);
spriteBatch.End();
GraphicsDevice.SetRenderTarget(rTargetB); // Set the drawing target to be a different off screen rendering buffer.
spriteBatch.Begin();
spriteBatch.Draw((Texture2D)rTargetA, new Rectangle(0, 0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height), Color.White);
spriteBatch.End();
spriteBatch.Begin();
spriteBatch.Draw(dotTexture, new Rectangle(60, (int)(motiony * 100), 100, 100), Color.Red * .5f);
spriteBatch.End();
GraphicsDevice.SetRenderTarget(null); // Set the drawing target to be the back buffer.
spriteBatch.Begin();
spriteBatch.Draw((Texture2D)rTargetB, new Rectangle(0, 0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height), Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
Though i dunno how to auto clear the render targets to a clear color
I guess you could overwrite the whole thing with a draw seems like there should be a way to do it with clear.
I am working with Monogame for about a week and I must say I am really impressed. The framework is clean and well organized, it is a real joy to develop with it.
Since it’s around this topic, I also wanted to point out the use of RenderTargetUsage.PreserveContents in an overload of the RenderTarget2D constructor. This can be a helpful feature when you need to create various render targets between drawing to the backbuffer and such, but be mindful of its possible performance costs, pending on use.