XNA Tutorials, Samples and Thoughts
Crash Course in HLSL
The XNA Effect Template Explained
Now that the main theoretical aspects are in place, you should look at the default template for effect files provided by XNA Game Studio 3.1. To see this template, create a new XNA project, and add a new Effect File to your Content project. You should see something similar to the code below.
float4x4 World;
float4x4 View;
float4x4 Projection;
// TODO: add effect parameters here.
struct VertexShaderInput
{
float4 Position : POSITION0;
// TODO: add input channels such as texture
// coordinates and vertex colors here.
};
struct VertexShaderOutput
{
float4 Position : POSITION0;
// TODO: add vertex shader outputs such as colors and texture
// coordinates here. These values will automatically be interpolated
// over the triangle, and provided as input to your pixel shader.
};
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
VertexShaderOutput output;
float4 worldPosition = mul(input.Position, World);
float4 viewPosition = mul(worldPosition, View);
output.Position = mul(viewPosition, Projection);
// TODO: add your vertex shader code here.
return output;
}
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
// TODO: add your pixel shader code here.
return float4(1, 0, 0, 1);
}
technique Technique1
{
pass Pass1
{
// TODO: set renderstates here.
VertexShader = compile vs_1_1 VertexShaderFunction();
PixelShader = compile ps_1_1 PixelShaderFunction();
}
}
At the very beginning, the effect contains definitions for three parameters. These parameters are matrices (float4x4) and represent the world, view and projection matrices. Under them, two structure data types are definded: one that defines the input to a vertex shader, VertexShaderInput, and one that defined the output of the vertex shader, VertexShaderOutput. Each of these structures contain a channel named Position, linked to the semantic POSITION0, which lets the GPU know the meaning of this data.
Next, a function is defined, which will fill the place of a vertex shader. As expected, its input is a VertexShaderInput structure, and it returns a VertexShaderOutput structure. The position given as an input is multiplied by the three matrices specified earlier, and the resulting position is written as the output. This sequence of multiplications is the most common one that happens in almost all vertex shaders.
The function destined to become a pixel shader returns a float4 as a result, and binds it to the COLOR0 semantic. The function uses a VertexShaderInput structure as input. This can be written in lots of different ways, but organizing the data like this yields in shader code which is cleaner and easier to maintain. The default XNA code simply returns the color red as the result.
And lastly, there is a technique defined. This technique only contains one pass, which uses the two functions defined above as a vertex shader and a pixel shader.
You can use this template as a starting point for your effect files.
Ending Words
I hope this short introduction was helpful for those of you looking to learn HLSL and shader programming. If you have any questions, feel free to post them in the comments below.

about 2 years ago
On page 4:
float4 PixelShaderFunction(float2 TexCoords : TEXCOORD0) : COLOR0
{
return tex2D(TextureSampler, input.TexCoord);
}
may be it should be:
return tex2D(TextureSampler, TexCoord);
about 2 years ago
I fixed it now. Thanks!
about 2 years ago
Thanks alot for this HLSL Crash Course =)
Now I can start writing my own Custom Shaders in XNA !
about 1 year ago
Thanks for your helpful explanations. Which book would be more suitable for a beginner who needs to learn everything from scratch (shaders, algebra, algorithms, and physical)? Thanks!
about 1 year ago
Why not develop the second part of the course with several practical examples (Blur, DOF, Sepia, etc.)?
about 1 year ago
You’re the best.
about 1 year ago
I’ve seen both () and used when doing Texture = (something) in declaring samplers. Is there an actual difference between the two?
about 1 year ago
Uh, that was supposed to two braces, that some reason didn’t show up.
about 1 year ago
Sorry, again that didn’t work, I think they’re treating them as html delimiters and I’m not quite sure how to escape them. Basically the less than and greater than symbols wrapping something.
about 1 year ago
Hey Zwabbit, they don’t defer in meaning
.
Btw CatalinZima, great tutorial. Been reading this and the deferred rendering tuts. Really freshens up my shader knowledge, I forgot almost everything that I learned when following riemers’ tuts.
about 9 months ago
very nice introduction,
cleared the stuff up. thanks!
about 8 months ago
Thanks a lot.
Great introduction.