XNA for C#
DirectX 9 for C#
DirectX 9 for C++
DirectX 9 for VB
Forum
   
My XNA Book
      
       Go to section on this site

Additional info


Latest Forum posts

 Account settings
  Posted by: Anonymous
  When: 07/05/2014 at 09:48:39

 forced subtitle
  Posted by: Applefly
  When: 07/05/2014 at 06:00:48

 convert DVD into PMS
  Posted by: Applefly
  When: 07/05/2014 at 05:55:25

 DVD to Digital Copy easily
  Posted by: VIKIVannessa
  When: 05/05/2014 at 06:52:29

 DVD on Xbox 360/Xbox One Console
  Posted by: VIKIVannessa
  When: 05/05/2014 at 06:51:47

 Extract .Srt Subtitles
  Posted by: Applefly
  When: 04/05/2014 at 03:54:38

 Encode Movie collection
  Posted by: Applefly
  When: 04/05/2014 at 03:52:41

 Convert DVD to WMV
  Posted by: Applefly
  When: 29/04/2014 at 05:53:50

 rip DVDs into digital files
  Posted by: Applefly
  When: 29/04/2014 at 05:51:20

 iTunes movies/music to Kindle Fire
  Posted by: ciciyu80
  When: 29/04/2014 at 05:10:20


Ads

The first Vertex Shader

Last chapter we’ve seen how to create our own vertex format. This chapter you will write your first HLSL code, together with your first vertex shader.

This would be a nice moment to have another look at our flowchart below. You notice the big arrow from our XNA app toward the vertex shader. At this point, we have the vertex stream (the position and color of our 3 vertices), as well as the metadata, which describes what’s in this vertex stream together with the memory size of each vertex.

When looking at the image, you’ll see it’s time to begin coding on our vertex shader!



Although one of the main goals of my tutorials is to keep all code in 1 file, we cannot get around this one. You’ll have to create a new empty effect file and give it a name (I named mine OurHLSLfile.fx). To do this, right-click on the Content entry of your XNA Solution Explorer and select Add -> New Item. In the dialog, select Effect file, give it the OurHLSLfile.fx name and click Add.

You should note the file has been added to the Content entry of your XNA Project. You will be presented with a screen containing a lot of code that seems pretty unknown, so delete it all

Although HLSL is not 100% the same as C# code, you will have absolutely no problem reading and writing the code. I could give you an extremely dry summary of the HLSL grammar, but I prefer to introduce you the syntax by showing some examples. At the end of this Series, you’ll be able to read and write almost any HLSL code you want.

As you have experienced throughout the previous series, an .fx file can describe one or more techniques. One technique can have multiple passes as you’ll see in the next chapters, but let’s start by defining a simple technique with only one pass. You can already put this as your first HLSL code in your .fx file:

technique Simplest
{
    pass Pass0
    {
        VertexShader = compile vs_2_0 SimplestVertexShader();
        PixelShader = NULL;
    }
}

This defines a technique, Simplest, which has one pass. This pass has a vertex shader (SimplestVertexShader), but no pixelshader. This indicates our vertex shader will pass its output data to the default pixel shader.

The main task of a 3D vertex shader is to accept a vertex with a 3D position, and to processor this into a 2D screen coordinate. Optionally, the vertex shader can also produce extra data, such as the color or texture coordinate.

Before we start coding our vertex shader, we would better define a structure to hold the data our vertex shader will send to the default pixel shader. The vertex shader method we will create, SimplestVertexShader, will simply transform the 3D positions in the vertices it receives from our XNA app to 2D screen pixel coordinates, and send them together with the color to the pixel shader, so put this code at the top of your .fx file:


struct VertexToPixel
{
    float4 Position     : POSITION;
    float4 Color        : COLOR0;
};

This again looks very much like C#, only for the :POSITION and :COLOR0. These are called semantics and indicate how our GPU should use the data. More on this in the next paragraph. Let’s start our SimplestVertexShader method, so you’ll better understand this. Place this method between the structure definition and our technique definition:

VertexToPixel SimplestVertexShader(float4 inPos : POSITION)
{
    VertexToPixel Output = (VertexToPixel)0;

    Output.Position = mul(inPos, xViewProjection);
    Output.Color = 1.0f;
    
    return Output;
}

This again looks a lot like C#. The first line indicates our method (our vertex shader) will generate a filled VertexToPixel structure. It also indicates the vertices that XNA sends to your vertex shader should contain positional data, as indicates by the POSITION semantic. This is very important: it links the data inside your vertex stream (as indicated in your VertexDeclaration) to your HLSL code.

Keep in mind that this method is called for every vertex in your vertex stream. The first line in the method creates an empty output structure. The second line takes the 3D coordinates of the vertex, and transforms them to 2D screen coordinates by multiplying them by the combination of the View and Projection matrix. For more information on this, you can always have a look at the Matrix sessions in my ‘Extra Reading’ section, which you can find at the right of every page.

Then we fill the Color member of the output structure. When you look at the definition of our output structure, you’ll see this has to be a float4: one float for each of the 3 color components, and an extra float for the alpha (transparency) value. You could fill this color by using the following code:

Output.Color.r = 1.0f;
Output.Color.g = 0.0f;
Output.Color.b = 1.0f;
Output.Color.a = 1.0f;

This would indicate purple, as you combine red and blue. The following code specifies exactly the same:

Output.Color.rba = 1.0f;
Output.Color.g = 0.0f;


This is called a swizzle, and helps you to code faster. Instead of rgba, you can also use xyzw. The rgba swizzle is usually used when working with colors, while the xyzw swizzle is used in combination with coordinates, but they do exactly the same. You can also use indices, which is useful for use in an algorithm:

Output.Color[0] = 1.0f;
Output.Color[1] = 0.0f;
Output.Color[2] = 1.0f;
Output.Color[3] = 1.0f;

In our example vertex shader above, we simply set Output.Color = 1.0f, which means the 4 components of the color are all set to 1.0f, corresponding to white. So our vertex shader will transform our 3D vertices to 2D screen coordinates, and pass them together with the color white to the default pixel shader. This means in our case of 1 triangle, our pixel shader will draw a solid white triangle to the window.

There’s still something missing. We still need to define xViewProjection, the matrix we’re using in our vertex shader to transform the 3D coordinate to the 2D screen coordinate. This matrix depends on the View and Projection matrices of the camera, so they stay the same for all vertices rendered in one frame. This matrix need to be specified by your XNA code, so put this at the very top of your HLSL code:

float4x4 xViewProjection;

This indicates xViewProjection is a matrix with 4 rows and 4 columns, so it can hold a standard XNA matrix. Our XNA app will fill this matrix in the next chapter.

That’s it for our first HLSL code! Of course, we still need to call the technique from our XNA app, as well as set the xViewProjection matrix. Because this chapter would otherwise become too lengthy, we’ll discuss the XNA part in the next chapter.




DirectX Tutorial 4 - Vertex shader

If you appreciate the amount of time I spend creating and updating
these pages, feel free to donate -- any amount is welcome !



Click here to go to the forum on this chapter!

Or click on one of the topics on this chapter to go there:
  • Vertex/pixel shader
          For my pixel shader I have this to counter for amb...
  • What does mul mean
          Hi riemers, I read the word mul in your HLSL cod...
  • W?
          I think I've had this explained to me before, but...
  • A typo in the code
          There's a small but confusing typo in the code fo...
  • Can't get FX Composer
          Hi, I tried to download the FX Composer, but th...



    Here you can find already what you should have as HLSL code:

    float4x4 xViewProjection;

    struct VertexToPixel
    {
        float4 Position     : POSITION;
        float4 Color        : COLOR0;
    };

    VertexToPixel SimplestVertexShader(float4 inPos : POSITION)
    {
        VertexToPixel Output = (VertexToPixel)0;

        Output.Position = mul(inPos, xViewProjection);
        Output.Color = 1.0f;
        
        return Output;
    }

    technique Simplest
    {
        pass Pass0
        {
            VertexShader = compile vs_2_0 SimplestVertexShader();
            PixelShader = NULL;
        }
    }



    Google
     
    Webwww.riemers.net


    If you appreciate the amount of time I spend creating and updating
    these pages, feel free to donate -- any amount is welcome !



    - Website design & XNA + DirectX code : Riemer Grootjans -
    ©2003 - 2011 Riemer Grootjans
  • Translations

    This site in English
    This site in Korean
    This site in Czech

    Microsoft MVP Award



    2007 - 2011 MVP Award
    DirectX - XNA

    Contents

    News
    Home
    Forum
    XNA 2.0 Recipes Book (8)
    XNA 3.0 Recipes Book (8)
    Downloads
    Extra Reading (3)
    Matrices: geometrical
    Matrix Mathematics
    Homogenous matrices
    Community Projects (1)
    Tutorials (160)
    XNA 4.0 using C# (89)
    2D Series: Shooters (22)
    3D Series 1: Terrain (13)
    3D Series 2: Flightsim (14)
    3D Series 3: HLSL (18)
    Starting point
    HLSL introduction
    Vertex format
    Vertex shader
    Pixel shader
    Per-pixel colors
    Textured triangle
    Triangle strip
    World transform
    World normals
    Per-pixel lighting
    Shadow map
    Render to texture
    Projective texturing
    Real shadow
    Shaping the light
    Preshaders
    3D Series 4: Adv. terrain (19)
    Short Tuts (3)
    DirectX using C# (54)
    DirectX using C++ (15)
    DirectX using VB (2)
    -- Expand all --


    Thank you!

    Support this site --
    any amount is welcome !

    Stay up-to-date

    I don't have the time to keep a News section, so stay informed about the updates by clicking on this RSS file!