Day #19: Silverlight Pixel Shader Effects

Today’s post was written by Matt Casto, a former colleague of mine, and my partner in crime for the Stir Trek event we held last May. You can read more from Matt at http://programwith.net.

Pixel shaders, also known as shader effects, are a cool new feature the became available with Silverlight 3. The two most common effects – drop shadow and blur – are included with Silverlight. Its easy to add these effects to any UIElement.

Lets build upon the simple form that was introduced in Jeff’s post Day #10: Styling Silverlight Controls. We can add a drop shadow effect to the email address textbox by changing the Page.xaml to look like this.

<TextBox x:Name="Email" Text="" Grid.Row="4" Style="{StaticResource TextBox}">
    <TextBox.Effect>
        <DropShadowEffect ShadowDepth="2" BlurRadius="3" Direction="300" />
    </TextBox.Effect>
</TextBox>

 

Running the application will show the drop shadow effect has been applied to the textbox.

PixelShaders_1

You can adjust the ShadowDepth, BlurRadius and Direction dependency properties to change the way the effect is rendered. For instance, if we change all of these values to be 10 we end up with this.

PixelShaders_2

Let’s also change the Page.xaml.cs code behind to set a Blur effect on the submit button while the Mailer service is being called.

void Clicky_Click(object sender, RoutedEventArgs e)
{
    if (Email.Text == ""){
        Email.Focus();
    }
    else
    {
        MailerReference.MailerSoapClient mailerClient = new MailerReference.MailerSoapClient();
        mailerClient.SendMailCompleted += new EventHandler<SilverlightStyling.MailerReference.SendMailCompletedEventArgs>(mailerClient_SendMailCompleted);
        string name = FirstName.Text.ToString() + " " + LastName.Text.ToString();
        string body = FirstName.Text.ToString() + "n" + LastName.Text.ToString() + "n" + Address.Text.ToString() + "n" + CityStateZip.Text.ToString();
        mailerClient.SendMailAsync("jeff@jeffblankenburg.com", Email.Text.ToString(), name, body);
 
        Clicky.Effect = new System.Windows.Media.Effects.BlurEffect { Radius = 3 };
    }
}
 
void mailerClient_SendMailCompleted(object sender, SilverlightStyling.MailerReference.SendMailCompletedEventArgs e)
{
    Clicky.Content = "Sent!";
    Clicky.IsEnabled = false;
    Clicky.Effect = null;
}

Run the application now and click Submit after filling in an email address and you’ll see the button get blurry until the service call has completed.

Pixel shaders modify the pixels before they’re rendered to display. This takes place at runtime and doesn’t use hardware acceleration at this point, so don’t expect these effects to be the most performant.

Adding Your Own Shader

You can create your own pixel shaders using High-Level Shading Language (HLSL) compiled with the DirectX SDK. Or you can download the Shazzam application to create, test and debug your pixel shader. Shazzam was created for WPF but all of these effects should work in Silverlight as well. Note that you’ll need the DirectX SDK installed first.

I pulled the Invert Color sample from Shazzam’s Shader Loader samples into the project by selecting Tools->View Compiled Shaders, copying the file (InvertColor.ps) and pasting it into the SilverlightStyling project. Also, I made sure the build action for the file is set to Resource. I then created a class to load the InvertColor.ps file.

using System;
using System.Windows.Media.Effects;
 
namespace SilverlightStyling
{
    public class InvertColor : ShaderEffect
    {
        public InvertColor()
        {
            var uri = new Uri(@"/SilverlightStyling;component/InvertColor.ps", UriKind.Relative);
            PixelShader = new PixelShader { UriSource = uri };
        }
    }
}

Then I applied the shader to the entire form by adding the effect to the LayoutRoot grid element.

<UserControl x:Class="SilverlightStyling.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:SilverlightStyling="clr-namespace:SilverlightStyling" 
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.Effect>
            <SilverlightStyling:InvertColor />
        </Grid.Effect>

Now our entire form has a beautiful effect.

PixelShaders_3

There are a lot more pixel shaders available from the Windows Presentation Foundation Pixel Shader Effects Library CodePlex project which was updated recently to work with Silverlight 3.

2 thoughts on “Day #19: Silverlight Pixel Shader Effects

  1. Jeff, I've got to give you (and your guest bloggers) props on this series. It's simple, useful and informative. Keep it up!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s