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)
        {
            effect.CurrentTechnique.Passes[0].Apply();
            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;

            myDevice.DrawUserIndexedPrimitives
                (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 Corporate Computer Disposal bracknell on 28 de julho de 2016 - 2:05 am

    I’ve learned some new things as a result of your web site. One other thing I’d prefer to say is the fact newer laptop or computer operating systems often allow far more memory to be utilized, but they furthermore demand more storage simply to function. If a person’s computer can not handle more memory as well as newest software requires that memory increase, it may be the time to buy a new Laptop or computer. Thanks

  2. #2 by Miquel on 28 de julho de 2016 - 2:47 am

    Recorded Delivery generic vermox Neil Rennison, creative director of Tin Man Games, describes the books as “my first portable gaming experience – I remember family holidays where I would take along a stack of Fighting Fantasy books”

  3. #3 by PC Recycling newbury on 28 de julho de 2016 - 3:11 am

    Things i have seen in terms of laptop or computer memory is that there are specific features such as SDRAM, DDR and so forth, that must match up the features of the motherboard. If the computer’s motherboard is pretty current while there are no os issues, replacing the memory space literally normally takes under one hour. It’s among the easiest computer system upgrade processes one can visualize. Thanks for sharing your ideas.

  4. #4 by Temecula Auto Glass on 28 de julho de 2016 - 3:33 am

    Great, thanks for sharing this blog.Thanks Again. Cool.

  5. #5 by katana swords on 28 de julho de 2016 - 3:50 am

    Product received just as described. very satisfied

  6. #6 by Living Room Decorating Ideas on 28 de julho de 2016 - 4:00 am

    Thanks a lot for providing individuals with a very superb chance to read articles and blog posts from this blog. It’s usually so awesome and as well , packed with a good time for me and my office friends to visit your website particularly 3 times every week to find out the latest secrets you have. Not to mention, I am usually fulfilled considering the tremendous information you serve. Some 3 points in this article are undoubtedly the most effective we have all had.

  7. #7 by betterscooter.com on 28 de julho de 2016 - 4:06 am

    the betterscooter.com http://www.scamadviser.com/is-betterscooter.com-a-fake-site.html are certainly cool.we’ve all the african american vintage bombers.this specific are generally our 3 rd couple partners and then 1st around extra tall.as a result thrilled i didnt receive the baily bottom level high.

  8. #8 by Bennett on 28 de julho de 2016 - 4:06 am

    Insert your card where to buy diclofenac Rebels patrolled casually and were in a boisterous mood, using positions in the town to fire artillery on Debaltseve.

  9. #9 by rio brazil olympics on 28 de julho de 2016 - 4:07 am

    I truly enjoy looking through on this web site, it has got superb posts. аЂа‹One should die proudly when it is no longer possible to live proudly.аЂа› by Friedrich Wilhelm Nietzsche.

  10. #10 by where is 2016 olympics on 28 de julho de 2016 - 4:07 am

    Thanks to my father who told me concerning this weblog,

  11. #11 by handmade sword on 28 de julho de 2016 - 4:22 am

    transaction fantastique! souper expédition rapide! article comme décrit !

  12. #12 by Benjamin on 28 de julho de 2016 - 4:54 am

    Could I make an appointment to see ? order clobetasol If they are desirable places to live, demand for living space will be high, and so, too, will be the purchase and rental price of land

  13. #13 by viagra pharmacy on 28 de julho de 2016 - 5:19 am

    Thanks-a-mundo for the blog.Thanks Again. Much obliged.

  14. #14 by Tracey on 28 de julho de 2016 - 5:25 am

    The manager aricept uk patent The Roxy Women's 2/2MM Syncro S/S Back Zip Spring suit, is the perfect choice when out in the ocean

  15. #15 by продажба имоти без посредник в софия on 28 de julho de 2016 - 5:27 am

    There are certainly a lot of details like that to take into consideration. That is a great point to bring up. I offer the thoughts above as general inspiration but clearly there are questions like the one you bring up where the most important thing will be working in honest good faith. I don?t know if best practices have emerged around things like that, but I am sure that your job is clearly identified as a fair game. Both boys and girls feel the impact of just a moment’s pleasure, for the rest of their lives.

1 438 439 440
(não será publicado)