<Image x:Name="image" Source="Images/Waterfall.jpg" Stretch="Uniform" CacheMode="BitmapCache" >
<Image.Effect>
<BlurEffect />
</Image.Effect>
</Image>
Pixel shaders are a compiled set of software instructions that calculate the color of the pixels and executed on the GPU. The instructions are written in HLSL (High Level Shader Language). Pixel Shaders allow for the development of custom effects. All elements, that derive from UIElement, have the Effect property that allows the element to render with the connected pixel shader.
In this tutorial, we will show you how to use the built-in shaders and develop custom effects for your applications.
You will need the latest version of DirectX SDK to compile .fx files. This tutorial uses the November 2008 DirectX SDK, which can be downloaded from Microsoft's Download Site. After installing the SDK, you will need to add the directory path (C:\Program Files (x86)\Microsoft DirectX SDK (November 2008)\Utilities\bin\x86) to the PATH environment variable.
To simplify the process of developing shaders, I have developed a project that runs a batch script to compile the shaders to use in the application. The project can be downloaded here.
Silverlight 3 has two built-in pixel shaders, Blur and Drop Shadow, that can be applied to XAML elements. Both effects can be found in the System.Windows.Media.Effects library.
The following code snippet shows the XAML approach to add an effect to an image.
<Image x:Name="image" Source="Images/Waterfall.jpg" Stretch="Uniform" CacheMode="BitmapCache" >
<Image.Effect>
<BlurEffect />
</Image.Effect>
</Image>
The following code snippet shows the code approach.
image.Effect = new BlurEffect();
The BlurEffect class uses the Radius property to render the blur strength. The default value of the radius is 5.
|
<BlurEffect Radius="10" /> |
The DropShadowEffect class contains more properties to customize the drop shadow's strength and color.
|
<DropShadowEffect BlurRadius="10" ShadowDepth="10" /> |
fxc /T ps_2_0 /E main /Fo Shaders\Constant.ps Shaders\Constant.fx
sampler2D input : register(s0);
float4 main(float2 uv : TEXCOORD) : COLOR
{
float4 color = tex2D(input, uv);
return color;
}
public class ConstantEffect : CustomEffect
{
private static PixelShader pixelShader;
static ConstantEffect()
{
pixelShader = new PixelShader();
pixelShader.UriSource = new Uri("Effects/Shaders/Constant.ps", UriKind.RelativeOrAbsolute);
}
public ConstantEffect()
{
this.PixelShader = pixelShader;
UpdateShaderValue(InputProperty);
}
}
image.Effect = new ConstantEffect();
The Inverse Shader calculates the inverse of the color pixels.
sampler2D input : register(s0);
float4 main(float2 uv : TEXCOORD) : COLOR
{
float4 color = tex2D(input, uv);
float4 complement;
complement.rgb = 1 - color.rgb;
complement.a = color.a;
return complement;
}
fxc /T ps_2_0 /E main /Fo Shaders\Inverse.ps Shaders\Inverse.fx
using System;
using System.Windows.Media.Effects;
namespace PixelShaderTest.Effects
{
public class InverseEffect : CustomEffect
{
private static PixelShader pixelShader;
static InverseEffect()
{
pixelShader = new PixelShader();
pixelShader.UriSource = new Uri("Effects/Shaders/Inverse.ps", UriKind.RelativeOrAbsolute);
}
public InverseEffect()
{
this.PixelShader = pixelShader;
UpdateShaderValue(InputProperty);
}
}
}
image.Effect = new InverseEffect();
The Inverse Shader can be applied to all items that derive from UIElement. To apply on multiple items, the shader can be added the parent layout's Effect property.
<Grid x:Name="parent" Background="White">
<Image Margin="20" x:Name="image" Source="Images/Waterfall.jpg" Stretch="Uniform" CacheMode="BitmapCache" />
<Button Content="Pixel Shaders" Width="100" Height="25" HorizontalAlignment="Center" VerticalAlignment="Bottom" />
</Grid>
parent.Effect = new InverseEffect();
|
|
Pixel Shaders are used to create custom bitmap effects that are executed on the GPU. The shaders can be applied to all XAML elements. The DirectX SDK is needed to create custom pixel shaders.