Shaders with HLSL #01 : Shaders with HLSL for WPF Developers

Complete Tutorial Series

In this first part of our tutorial, we will briefly enlighten ourselves on key concepts involving shaders and why it is required. We will also write our first shader application, introducing ourself to the HLSL semantics.

What is a Shader ?

Shaders are small programs written to run on the GPU (Graphical Processing Unit) and describes how to render each pixel. Since running parallely on the GPU hardware, they typically produces faster output,compared to having it run on the CPU.
There are mainly two types of Shaders

  • Vertex Shader – Vertex Shader gets the first chance to work on Model, prior to even Rasterizer and is responsible for transforming vertex.
  • Pixel Shader – Pixel Shader comes into pipeline a little later, after Rasterizer and is responsible for determining the final color of a pixel

WPF and Shaders

The huge computing power of modern GPUs ensures complex and graphically rich applications have little impact on performance. Begining with .Net 3.5 SP1, Microsoft introduced hardware accelerated affects for WPF (Effects in WPF, for example Blur Effect and DropShadowEffect) utilizing the power of shaders. We could write our own custom shaders and use them in our WPF applications.

Evolution of HLSL/C

One of the earliest approaches for writing Shaders used assembly language, but soon it was evident that the inherient complexity of Assembly Language was not making it any easier. This lead to development of Cg (C for Graphics) by NVida and HLSL (High Level Shader Language) by Microsoft. Both languages follows a similiar syntax and is closely associated to C Language in syntax and compile shaders for DirectX.

Getting Started with HLSL

Let’s write some code first and then we will go in detail examining the code as well as how to use it in your WPF Application.

sampler2D input: register(s0);

float4 main(float2 uv:TEXCOORD) : COLOR
{
return float4(1.0f, 0.0f, 0.0f, 1.0f);
}

The first line of code represent our input parameters, stored in GPU registers.

sampler2D input: register(s0);

Pixel Shaders rely on GPU registers input, which are high speed storage areas. There are different types of registers, but most of our applications written in C# depends on S and C register1 types. The S registers, also known as Sampler Registers are mainly used for storing input images data2. If we need to pass another Image Source, we could pass it via the register s1. We could pass other arguements to our shaders using the C registers (floating point registers), but for the sake of our first example, we will keep it simple with just a single input parameter, which is our Image data.

The first line of code specifies an input variable input and the register to use for the purpose. It also specifies the input type, which in this case is sampler2D and refers to the image it is being applied to.

The main as one can easily guess, represent the entry point of the shader code. The incoming parameter uv represents the incoming texture cordinates, while the return type float4 represents an RGBA color.

float4 main(float2 uv:TEXCOORD) : COLOR

The body of our first Shader application is pretty simple, it returns a color representing Red.

return float4(1.0f, 0.0f, 0.0f, 1.0f);

Let’s save the above code with extension “hlsl”. In the next part of tutorial we will examine how to compile our HLSL code to ps format, which would be later consumed by our WPF application.


  1. More on Registers : Source : Microsoft 
  2. Image, in this context refers to visual representation of the target control. 
Advertisements