I have a static class that I use to build a 3d character and render the results to a RenderTarget2D which I then return.

I'd like to store the results for later use so I need to make a copy of the returned RenderTarget. To do this I`ve tried both a Quad VertexPrimitive Effect with a tiny copy PixelShaderFunction and a SpriteBatch.Draw.

I think that the Quad render is quicker but no matter how I fiddle, the Quad never seems to get it quite right.

For example, I do use SpriteBatch to pick up a 256*256 area of a large Texture2D backdrop and Draw that to a RenderTarget2D. But if I then send that directly to the Quad render and put that result back in the same place it almost - but VERY annoyingly not quite - fits back perfectly. Using another SpriteBatch.Draw does give a perfect result but I've convinced myself that it is slower.

So my questions are twofold.

1) Is the Quad UserIndexedPrimitive quicker than the SpriteBatch.Draw for multiple iterations?


2) Why can`t I get the Quad render to give me back the same image when setting it as the Effect sampler via Effect.Parameter..SetValue(RenderTarget)?

As ever, Thanks :) Stoort.

Source and Destination 512*512 RenderTargets side by side

Here is the problem in png form.

The left half is the RenderTarget2D before I use a short user Effect that just does a straight copy using

    return tex2D(texture, coord);

as the only PixelShaderFunction instruction via a quad with

                (PrimitiveType.TriangleList, verts, 0, 4, ib, 0, 2);

The source and destination width and height are identical as are all the RenderTarget2D settings for both.

As you can see the output on the right is blurred and the top and right lines are wrapped from the opposite sides.

  • \$\begingroup\$ An image explaining "it almost - but VERY annoyingly not quite - fits back perfectly" would be helpful. The first thing that comes to mind is that you may need to implement a half pixel offset: msdn.microsoft.com/en-us/library/windows/desktop/… \$\endgroup\$
    – JonBee
    Commented Dec 21, 2015 at 16:45
  • \$\begingroup\$ Which part do I add the offset from? VertexShader or PixelShader and how? \$\endgroup\$
    – Stoort
    Commented Dec 26, 2015 at 5:22

1 Answer 1


Thanks JonBee your halfpixel offset was just what I was looking for :)

What I did to fix it was this...

When building my quad I add the following Vector3 to each Vertex Position in the VertexPositionTexture[] array :-

    Vector3 HalfPixelOffset = new Vector3(-0.5f, 0.5f, 0);

This worked a charm and I tested it with several different sizes of RenderTarget2D. No changes were needed in the HLSL Effect code. Lovely :)

  • \$\begingroup\$ If you are creating your own view matrix, you can implement the half-pixel offset with it, so that you don't have to offset every vertex coord. \$\endgroup\$
    – JonBee
    Commented Dec 28, 2015 at 16:30

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .