Drawing FullScreen Quads with XNA 4.0

Quads are very important for numerous effects like all Image processing techniques (Bloom, Blur,Fog ….), Deferred Shading, Some particles system technics and others …..

In this short tutorial we will show how to draw a simple quad (and the theory behind it =P) using xna 4.0

If you dont want to know about the theory behind the quads, no problems =P, go to the code section directly.

Instead of showing how to create a Quad, i will talk about a specific case called FullScreenQuad, cause it is simpler and more easy to follow than the general case. (The concepts are the same in both case).

In simple words FullScreenQuad is just two triangles that fills the entire screen (imagine a rectangle in 2D that cover all the screen =P).

The importance of drawing FullScreen Quads is that we can run the pixel shader exactly once for each pixel of the render target (can be the back buffer or a texture). One example of this usefull property is the PostProcessing phase (or Image Process phase) where we recieve one quad and one texture as inputs, in GPU we change each texel of this texture and save the changes to the render target.

The magic is that the constructed quad will be perfect aligned to the screen borders (a rectangle covering all of it), when it is rasterized, the pixel shader will be called exactely once for each pixel of the screen, then you can access each corresponding texel of the associated texture, change it (process) and output  it in the render target in the same position it has in the original texture. (Remember that Render targets can be used as textures in another shader pass)

There are LOTS of ways of drawing fullscreen quads. We will use one that is simple and flexible enough =P (and can be used to draw arbitrary size quads, not only fullscreen).

Our choice is to create the vertices in CPU already in Projection Space and send them to a by-pass Vertex Shader.
In Projection space (after applying the world, view and projection matrix) , the borders of the screen (using the DirectX/XNA Projection matrix convention) are:  X: [-1,1], Y:[-1,1] and Z[0,1] (primitives which vertices is out of this range are clipped).  For example, a point with (-1,-1,0) will be in the down, left of you screen (The Z being 0 mean that it is VERY close to the camera). A point in (0,0,0) will appear in the midle of the screen. The following image shows the projection coordinates domain: (imagine the screen being the front square). Remember that we are in the normalized space, the rasterizator unit will convert it to the real screen coordinates (resolution dependent one)

DirectX Projection Coordinates space

So we will just create two triangles (to fill the quad) already in projection space, pass them to vertex shader, dont apply transformation (cause they are already in projection space) and send the vertices to the rasterization unit.

The vertice will contain the positions in Projection Space  and the Texture Coordinates. The up, left point of the quad will have the (0,0) texture coordinate and the lower, right will be (1,1).

The following code shows an easy way to do this in XNA 4.0:

internal sealed class QuadRender
        private VertexPositionTexture[] verts;
        private GraphicsDevice myDevice;
        private short[] ib = null;

        /// Loads the quad.
The engine.
        public QuadRender(GraphicsDevice device)

            myDevice = device;         

            verts = new VertexPositionTexture[]
                            new VertexPositionTexture(
                                new Vector3(0,0,0),
                                new Vector2(1,1)),
                            new VertexPositionTexture(
                                new Vector3(0,0,0),
                                new Vector2(0,1)),
                            new VertexPositionTexture(
                                new Vector3(0,0,0),
                                new Vector2(0,0)),
                            new VertexPositionTexture(
                                new Vector3(0,0,0),
                                new Vector2(1,0))

             ib = new short[] { 0, 1, 2, 2, 3, 0 };


        /// Draws the fullscreen quad.
The effect.
        public void RenderFullScreenQuad(Effect effect)
            RenderQuad(Vector2.One * -1, Vector2.One);

        public void RenderQuad(Vector2 v1, Vector2 v2)

            verts[0].Position.X = v2.X;
            verts[0].Position.Y = v1.Y;

            verts[1].Position.X = v1.X;
            verts[1].Position.Y = v1.Y;

            verts[2].Position.X = v1.X;
            verts[2].Position.Y = v2.Y;

            verts[3].Position.X = v2.X;
            verts[3].Position.Y = v2.Y;

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

If you dont want to draw a full screen quad, you can change the border values passed as function parameter

The Vertex Shader to process the FullScreen quad is:

texture colorMap;
sampler colorSampler = sampler_state
    Texture = (colorMap);
    AddressU = CLAMP;
    AddressV = CLAMP;
    MagFilter = LINEAR;
    MinFilter = LINEAR;
    Mipfilter = LINEAR;

struct VertexShaderInput
    float3 Position : POSITION0;
    float2 TexCoord : TEXCOORD0;

struct VertexShaderOutput
    float4 Position : POSITION0;
    float2 TexCoord : TEXCOORD0_centroid;

float2 halfPixel;
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
    VertexShaderOutput output;
    input.Position.x =  input.Position.x - 2*halfPixel.x;
    input.Position.y =  input.Position.y + 2*halfPixel.y;
    output.Position = float4(input.Position,1);
    output.TexCoord = input.TexCoord ;
    return output;


XNA 4.0 works under DirectX9.0. In this environment, we have to make a “somehow strange correction” to the position of our vertices in the Vertex Shader (subtract the halfPixel size) when processing quads. The reason for this is the algorithm used in the rasterization unit (More info about this is Here).

The Pixel Shader is where you process the image. For this sample i just multiply each texel by 0.7f. (make them darker):

float4 PixelShaderFunctionNormal(VertexShaderOutput input) : COLOR0
	float4 process = tex2D(colorSampler,input.TexCoord);
        return process * 0.7f;

Its done =P quite simple. The PostProcess samples (the simple ones) are just “diferent” pixel shaders that process the recovered color in diferent ways.


, , ,

  1. #1 by auto HOME insurance quotes on 15 de janeiro de 2017 - 5:05 pm

    you are really a good webmaster. The site loading speed is incredible. It seems that you’re doing any unique trick. In addition, The contents are masterwork. you have done a fantastic job on this topic!

  2. #2 by home insurance by zip code map on 15 de janeiro de 2017 - 7:48 pm

    Thanks for sharing superb informations. Your web site is very cool. I am impressed by the details that you have on this web site. It reveals how nicely you understand this subject. Bookmarked this web page, will come back for extra articles. You, my friend, ROCK! I found just the information I already searched everywhere and just could not come across. What a great web-site.

  3. #3 by cialisNM on 15 de janeiro de 2017 - 9:22 pm

    I enjoy the data on your website. Thanks a ton!

  4. #4 by buycialisNM on 15 de janeiro de 2017 - 9:23 pm

    Much thanks! This is definitely an astounding internet site!

  5. #5 by Urban Decay Mascara on 15 de janeiro de 2017 - 9:27 pm

  6. #6 by cheap insurance for motorbike on 15 de janeiro de 2017 - 10:19 pm

    I’m not that much of a internet reader to be honest but your sites really nice, keep it up! I’ll go ahead and bookmark your website to come back in the future. Many thanks

  7. #7 by healthcare family plans on 16 de janeiro de 2017 - 1:00 am

    Hey very nice web site!! Man .. Excellent .. Superb .. I’ll bookmark your site and take the feeds additionally…I’m satisfied to find a lot of helpful info right here in the submit, we need develop extra strategies in this regard, thank you for sharing.

  8. #8 by adidas yeezy boost 350 on 16 de janeiro de 2017 - 2:31 am

  9. #9 by Gambling on 16 de janeiro de 2017 - 2:40 am

    Thanks for finally talking about > blog_title < Loved it!|

  10. #10 by Gambling on 16 de janeiro de 2017 - 3:21 am

    I’m gone to tell my little brother, that he should also go to see this weblog on regular basis to get updated from latest news.|

  11. #11 by Retire Early on 16 de janeiro de 2017 - 3:47 am

    Hmm it appears like your site ate my first comment (it was super long) so I guess I’ll just sum it up what I had written and say, I’m thoroughly enjoying your blog. I as well am an aspiring blog blogger but I’m still new to everything. Do you have any suggestions for first-time blog writers? I’d certainly appreciate it.

  12. #12 by Living Our Dreams on 16 de janeiro de 2017 - 4:11 am

    Heya i am for the primary time here. I came across this board and I find It truly useful & it helped me out a lot. I’m hoping to offer something again and help others such as you helped me.

  13. #13 by buy web hosting on 16 de janeiro de 2017 - 4:31 am

    After examine a few of the weblog posts in your web site now, and I really like your method of blogging. I bookmarked it to my bookmark website listing and shall be checking back soon. Pls check out my website as well and let me know what you think.

  14. #14 by jordan 12 low for sale on 16 de janeiro de 2017 - 8:37 am

  15. #15 by esurance company on 16 de janeiro de 2017 - 11:26 am

    Outstanding post, I conceive people should learn a lot from this weblog its rattling user friendly.

  16. #16 by beton imprime on 16 de janeiro de 2017 - 11:37 am

    Hello would you mind letting me know which webhost you’re using? I’ve loaded your blog in 3 different browsers and I must say this blog loads a lot faster then most. Can you suggest a good web hosting provider at a fair price? Thanks a lot, I appreciate it!

  17. #17 by viagra_online on 16 de janeiro de 2017 - 1:34 pm

    Hello! Someone in my Facebook group shared this website with us so I came to check it out. I’m definitely enjoying the information. I’m bookmarking and will be tweeting this to my followers! Outstanding blog and superb design and style.

  18. #18 by my Direct auto insurance on 16 de janeiro de 2017 - 1:53 pm

    Thanks for some other great post. Where else may just anyone get that type of information in such a perfect means of writing? I’ve a presentation subsequent week, and I am at the search for such info.

  19. #19 by geico insurance york pa on 16 de janeiro de 2017 - 3:46 pm

    whoah this weblog is fantastic i like studying your articles. Stay up the good paintings! You already know, a lot of individuals are hunting around for this info, you could help them greatly.

  20. #20 by Top Colleges Online on 16 de janeiro de 2017 - 4:41 pm

    Thank you for sharing with us, I believe this website really stands out : D.

  21. #21 by Car Insurance Quotes Online on 16 de janeiro de 2017 - 6:13 pm

    Hello there! I could have sworn I’ve been to this site before but after reading through some of the post I realized it’s new to me. Anyways, I’m definitely delighted I found it and I’ll be bookmarking and checking back often!

  22. #22 by wild rabbit vibrator on 16 de janeiro de 2017 - 7:31 pm

    although web sites we backlink to beneath are considerably not associated to ours, we really feel they may be essentially worth a go by means of, so have a look

  23. #23 by самолетни билети от лондон до пловдив on 16 de janeiro de 2017 - 7:38 pm

    Spot on with this write-up, I truly think this website needs much more consideration. I’ll probably be again to read much more, thanks for that info.

  24. #24 by vintage photography on 16 de janeiro de 2017 - 7:42 pm

    831218 313688hey there, your website is great. I do thank you for work 45306

  25. #25 by Chandra on 16 de janeiro de 2017 - 11:24 pm

    that will be the end of this post. Right here you will uncover some sites that we believe you will value, just click the hyperlinks over

  26. #26 by car insurance quotes online compare on 16 de janeiro de 2017 - 11:37 pm

    Very good post. I absolutely appreciate this site. Keep it up!

  27. #28 by free download for windows pc on 17 de janeiro de 2017 - 12:27 am

    Some truly nice and utilitarian info on this web site, besides I think the style and design has good features.

  28. #29 by Building Cost Estimator on 17 de janeiro de 2017 - 12:38 am

    I simply wanted to thank you very much once again. I am not sure the things that I would’ve taken care of in the absence of those creative concepts documented by you directly on that concern. It seemed to be a very fearsome circumstance in my view, nevertheless witnessing this specialized style you solved the issue made me to jump over happiness. Extremely thankful for this help and as well , believe you recognize what a great job you happen to be accomplishing teaching most people all through your website. More than likely you haven’t met any of us.

  29. #30 by Homeopathy on 17 de janeiro de 2017 - 2:43 am

    Great write-up, I am regular visitor of one¡¦s website, maintain up the nice operate, and It is going to be a regular visitor for a long time.

  30. #31 by Individual Health Insurance on 17 de janeiro de 2017 - 3:57 am

    Hey There. I found your blog using msn. This is a really well written article. I’ll make sure to bookmark it and come back to read more of your useful information. Thanks for the post. I will definitely comeback.

  31. #32 by Ekans Pokemon on 17 de janeiro de 2017 - 4:18 am

    I keep listening to the newscast talk about getting free online grant applications so I have been looking around for the most excellent site to get one. Could you advise me please, where could i find some?

1 593 594 595
(não será publicado)