Simply RenderTargets

May 26, 2009 at 6:39 pm (Other Stuff, XNA) (, , )

Somebody in the #xna IRC channel just asked how to use RenderTargets to only draw a portion of the screen. Here’s my answer.

I guessed from his brief description he might have a game scene which didn’t look like this



And the result he wanted, was something almost like … this ?


What you see here is the game scene drawn, with a triangle portion visible and the rest not so much. My favourite way to achieve this is to use 2 RenderTargets, A VERY simple Effect(shader) and good old SpriteBatch. So what do we use all this for?

First we need to draw the game scene. There is a way around this but to make things easier to understand we will draw this to a RenderTarget. Simply put, a RenderTarget is an imaginary “screen” to draw to which you can specify the size of. Then once done, you can use the texture like any normal Texture2D you might load from the Content Pipeline.

To draw the scene we first want to set the correct RenderTarget, then use spritebatch just like you would to draw any other sprite. Like this.

            GraphicsDevice.SetRenderTarget(0, _gameRT);
            //Clear the RT screen
            //Draw the game


Simple uh?

Now we need to create another RenderTarget, and Draw a triangle to it. This will never be displayed in the final scene. Although with the RenderTarget it allows you to if you so desire, maybe for debugging purposes?

            GraphicsDevice.SetRenderTarget(0, _lightRT);
            //Clears the screen transparent.


This code is almost identical to the last except we draw the _triangle Texture which looks like this.


And we use the color transparent black.

The final thing we need to do now is draw it to the scene.

If we just draw the triangle on top of the game scene you will see the game scene with a white triangle on top. This isnt what we want. So we use a shader to take the game scene, and change the alpha channel corresponding to the white triangle. Wherever there is a solid non transparent color pixel, this will be set to a fully non transparent pixel in the game result, however, a transparent pixel in the triangle image will result in a completely transparent pixel in the final result. Resulting in you not being able to see that pixel. The final result is like this.



The shader code is very simple. It is a pixel shader which takes a AlphaTexture parameter which is the texture taken from the triangle RT. It takes the alpha from that texture, and sets the coresponding pixel on the final image to be the same.

float4 PixelShader(float2 texCoord: TEXCOORD0) : COLOR
	float4 Color = tex2D(ScreenS, texCoord);
    float alphaLayerAlpha = tex2D(AlphaSampler, texCoord).a;
    return Color;  


To use this we just create a new Effect variable and load it in LoadContent. Call Begin/End in the appropriate places, set the parametar and hey presto. A RESULT!!!

spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.None);


To get a better grasp of the code you can download the sample project here.


As I said, Someone in IRC literally just asked. So I knocked this up. Apologies for the rushed post 🙂 BACK TO SBARG!!!



  1. raigan said,

    This might be a stupid question but.. wouldn’t just using the stencil buffer be a lot simpler?

  2. raigan said,

    Another simpler solution is to render the scene to an offscreen buffer (as you suggest), and then draw a triangle textured with that buffer (rather than draw a triangle to another buffer, and then combine the buffers).

    I’m not really sure what you gain from drawing the triangle to a texture and then combining the two.. although I’m still learning graphics stuff so I might be missing something!

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: