Can I apply an opacity setting to an entire SpriteBatch?


I would like to apply an opacity setting to a group of sprites at once.

Currently I apply opacity by changing the alpha of the ‘tint’ value the is supplied to spriteBatch.Draw().

This works fine, but say I have a sprite over a background image and I want this all drawn at 50% opacity I can’t draw both at 50% opacity separately as you’d see the background image through the sprite.

Can I somehow draw both as normal and then render the result at 50% opacity without rendering to an offscreen image first?


SpriteBatch does not support that operation, but it’s easy to hack it in. You can copy SpriteBatch completely and add this functionality, though it uses some internal classes, so you’d have to copy those too. It’d be easier to extend SpriteBatch and add a Begin overload that takes a Color to multiply all tints by and DrawTint variants of the Draw functions that apply the multiplication.


Thanks for the reply - surely this wouldn’t work though as if I multiply all tints by the same amount I’ll just get what I’m getting already, ie two sprites rendered individually at 50% opacity rather than both sprites rendered at 100% and the result of this rendered at 50%?


Oh, sorry I didn’t read that right. I don’t think you can do that without an intermediate rendertarget.

I’m not sure I understand exactly what you’re asking for.

But I gather you want to draw selected elements using a specified color and opacity, and you don’t want to use render targets.

That will give you sprites on top of sprites on top of sprites, so the best you can
do with that is to draw the background using a solid color, and transparent sprites on top.
Maybe use lists of items, and a foreach loop to draw them all using a specific color.


this is not possible without use of additional rendertargets.

I understand you don’t want them, but in case you maybe change your mind, here is how it works.

RenderTarget2D opacityRenderTarget;

In my Initialize()

opacityRenderTarget = new RenderTarget2D(_graphicsDevice, targetWidth,
targetHeight, false, SurfaceFormat.Color, DepthFormat.None, 0, RenderTargetUsage.DiscardContents);

In my Draw()

//Draw background

SpriteBatch.Draw( … my background stuff … )


//Ideally you want to render with 100% opacity
SpriteBatch.Draw( … my foreground stuff … )

//Render to backbuffer again

//Now we want to change our blendmode to something with opacity, like additive or other custom blends
SpriteBatch.Draw(opacityRenderTarget, … );