May

Text Effects in Silverlight - It's So Simple

Author: Steve
Posted on: 28 May 2009
In this blog post I'm going to concentrate on how text animation control can be used and customized to create lot's of different text animations.

Download: TextEffectsSample Source

Text animation is powerful tool to present information and catch visitors attention. There are several libraries out there to create text animations in Flex. If you need to create text effects in Silverlight apps - please try SvLite Effects.

See it in action below:

SvLite Effects library providers text effect control to create text animations in Silverlight. The control is easy to use and can be configured in multiple ways to create different text animations.

TextEffectControl can be defined in Xaml as follows:

 <SvUx:TextEffectControl 
x:Name="textEffect"
Text="Text Effects"
FontSize="40"
HorizontalAlignment="Center"
VerticalAlignment="Center" />

You need to set it's Text property, FontSize and it's also possible to use custom Style for the control. In the above code we use TextEffectControlStyle defined inside application resources dictionary.

To start text animation you can use two methods: Show - to show text, and Hide - to hide text. However you also need to define animation parameters for the control. This can be done by setting text effect control Pattern property.

Text effect control Pattern property has TextAnimationPattern type and it defines type of show and hide animations for all text characters.

The following xaml code shows simple text animation pattern, which defines relatively complex animation:

 <SvFx:TextAnimationPattern >
<SvFx:TextAnimationPattern.AnimationSelectors >
<SvFx:AllAnimationGroupSelector >
<SvFx:AllAnimationGroupSelector.AnimationPattern >
<SvFx:ShiftItemPattern
ShowInterval="0.1"
HideInterval="0.1"
SpeedRatio="4"
Shuffle="True"
MoveTween="BackTweenOut"
ShiftMode="FromRandomPoint"
StartVerticalOffset="60"
StartHorizontalOffset="60" />
</SvFx:AllAnimationGroupSelector.AnimationPattern>
</SvFx:AllAnimationGroupSelector>
</SvFx:TextAnimationPattern.AnimationSelectors>
</SvFx:TextAnimationPattern>

AnimationSelectors property defines animation groups and in the above code we use AllAnimationGroupSelector to apply animation to the whole text. In the above code we also use ShiftItemPattern for the selector. ShiftItemPattern is really powerful tool to customize your animations. Shift item pattern contains lot's of properties to customize animation.

Just open App.xaml file from the post's sample code and take a look into all animation patterns defined. It's so simpe!

Posted in: Silverlight

Create Reflection Shader in Silverlight

Author: Steve
Posted on: 25 May 2009
In this post I'm going to post some sample code on how to create reflection shader using new pixel shader feature of Silverlight 3.

Reflection Shader Source

It is easy to create pixel shaders in Silverlight. It's basically C# like code. Language for creating shaders is called HLSL - High Level Shader Language. HLSL is heavily used inside video games to create cool graphics :) At the moment Silverlight doesn't allow you to define vertex shaders, you can do only pixel.

See how it works:

Steps to Create New Pixel Shader:

  1. Create new text file with "fx" extension and place your HLSL code there.
  2. Then compile (not with Visual Studio, but with special effect compiler tool available from DirectX SDK - you can download this from Microsoft web site) your "fx" file to get compiled pixel shader. Compiled pixel shader is placed inside binary file with "ps" extension.
  3. Make sure to include this "ps" file into your project and set it's compile type to "Resource".
  4. And finally create new ".cs" file and place C# shader code there.

Fx File

Effect file should contains HLSL instructions in order to compile. If you are new to HLSL then read HLSL reference here: HLSL Reference it should give you information on language syntax, available data types, operators and functions.

Here is how simplest "fx" file looks like:

sampler2D input : register(s0);

float4 main(float2 uv : TEXCOORD) : COLOR
{
  return tex2D(input, uv);
}

This line: "sampler2D input : register(s0);" defines "input" variable of sampler2D type. This instruction "register(s0)" defines that data for input variable comes from "s0" register. Next main function is defined - it's C like syntax, except for "TEXTCOORD" and "COLOR" - these are HLSL semantics used by effect compiler and GPU. TEXTCOORD means that "uv" parameter contains texture coordinates, which can get values from 0 to 1. Since "uv" variable has float2 data type, it's possible to access it's "u" and "v" components, e.g. "uv.u", "uv.v", or you can use "uv.x", "uv.y". COLOR semantic means that main function returns color data. "text2D" used inside main function's body is HLSL function which returns color data from the given sampler and texture coordinates.

We are going to define Reflect function for our reflection shader. See below:

float4 Reflect(float2 uv : TEXCOORD) : COLOR
{
  float edge = 0.5;
  if (uv.y > edge)
  {
    uv.y = edge - (uv.y - edge);
    return tex2D(input, uv) * uv.y;
  }
  return tex2D(input, uv);
}

 

The code is really simple, if uv.y > 0.5 we reflect uv coordinate and return color data, otherwise we use original texture coordinate to return color data. So now we just call Reflect function from our main:

float4 main(float2 uv : TEXCOORD) : COLOR
{
  return Reflect(uv);
}

To compile fx code you need to run the following command line:
fxc /T ps_2_0 /E main /Fo "Reflection.ps" "Reflection.fx"

For more info see this:
Fxc Tool

You can define pre build action for your project:
"fxc" /T ps_2_0 /E main /Fo "$(ProjectDir)Reflection.ps" "$(ProjectDir)Reflection.fx"

fxc tool will create "Reflection.ps" binary file - include it to your project and set compile type to resource.

 

C# Shader File

Create new C# file, and paste the following code:

 

using System;
using System.Windows.Media.Effects;
using System.Windows;

namespace ReflectionShader
{
  public class ReflectionShader : ShaderEffect
  {
    public ReflectionShader()
    {
      Uri u = new Uri(@"ReflectionShader;component/Reflection.ps", UriKind.Relative);
      PixelShader = new PixelShader() { UriSource = u };
    }

    public static readonly DependencyProperty ElementHeightProperty =
            DependencyProperty.Register("ElementHeight",
            typeof(double), typeof(ReflectionShader),
            new PropertyMetadata(100.0, OnElementHeightChanged));

    static void OnElementHeightChanged(DependencyObject d, 
      DependencyPropertyChangedEventArgs e)
    {
      (d as ReflectionShader).OnElementHeightChanged((double)e.OldValue, (double)e.NewValue);
    }

    protected virtual void OnElementHeightChanged(double oldValue, double newValue)
    {
      PaddingBottom = newValue;
    }

    public double ElementHeight
    {
      get { return (double)base.GetValue(ElementHeightProperty); }
      set { base.SetValue(ElementHeightProperty, value); }
    }
  }
}

Take a look at the code inside ReflectionShader constructor - it sets PixelShader property inherited from ShaderEffect class. "ReflectionShader;component/Reflection.ps" - this string sets relative url to our "ps" file. Since reflection shader needs some space below ui element we use PaddingBottom property inside OnElementHeightChanged method.

 

Hot to Use Pixel Shader

It's really simple. Here is Xaml code:

 <Button 
x:Name="btnReflected"
Width="200"
Height="70" >
<TextBlock
FontWeight="Bold"
FontSize="25"
Text="Reflection" />
<Button.Effect >
<local:ReflectionShader
ElementHeight="70" />
</Button.Effect>
</Button>


That's all.

Posted in: Silverlight