Parametric Shader Effect in Silverlight 3 Beta1
Cristian Merighi ()

Sample Trackball Behavior gets enriched by a PixelShader (new in Silverlight 3) that modifies the aspect of the rotating UIElement based on incidence and intensity of a virtual directional light.
This article is obsolete. Some functionalities might not work anymore. Comments are disabled.
This is a pretextuous prosecution of my last article about Silverlight 3 and its new features:
I'd like to introduce and contextualize a serious enhancement to the rendering process, I'm talking about
shader effects.
We've seen how to use Blend 3 libraries in order to attach a simple Trackball behavior to an
UIElement, now I want that - goal - as soon as the element rotates an hypothetical light modifies
the look of the element itself (try the demo by clicking on the following image)...

What I'm gonna (step-by-step)?
- Write an .fx file using HLSL(anguage) which contains the logic of
- accepting a map of pixels as input;
- accepting a couple of numeric parameters which carry informations about light incidence;
- returning the algorithm used for the per-pixel handling.
- Compile the .fx file into a .ps (pixel shader) one
I need a tool that comes with the DirectX SDK, the fxc(ompiler), stored into the
«C:\Program Files\Microsoft DirectX SDK (_edition_)\Utilities\bin\x86» folder.
- Include the .ps file into my Silverlight project as a resource.
- Wrap the shader in a class that inherits from ShaderEffect and that properly
exposes the members that bridge to the pixel shader (.ps) parameters.
So first: the .fx file:
sampler2D input : register(s0);
float dotProduct : register(c0);
float lightIntensity : register(c1);
float4 main(float2 uv : TEXCOORD) : COLOR
{
float goal = dotProduct <= 0.0 ? 0.0 : 1.0;
float adjust = -lightIntensity * abs(dotProduct);
float4 clr = tex2D( input , uv.xy);
clr.r = clr.r + (goal - clr.r) * adjust;
clr.g = clr.g + (goal - clr.g) * adjust;
clr.b = clr.b + (goal - clr.b) * adjust;
return clr;
}
Now compile it into a .ps file using the following cmd line instruction:
fxc /T ps_2_0 /E main /Fo"specular.ps" "specular.fx"
Where /T is the target profile parameter (must target pixel shader 2.0),
/E identifies the entry point function, while /Fo provides the file output.
Next: encapsulate the generated .ps file into the Silverlight project as a resource.
Now the shader wrapper, I'll just emphasize some line of code (the entire project can be downloaded
at the bottom of the page).
public SpecularShader()
{
this.PixelShader = SpecularShader.pixelShader;
}
static SpecularShader()
{
pixelShader = new PixelShader();
pixelShader.UriSource = new Uri("RyoushinSamples;component/shaders/specular.ps", UriKind.Relative);
}
public static readonly DependencyProperty InputProperty =
ShaderEffect.RegisterPixelShaderSamplerProperty(
"Input",
typeof(SpecularShader),
0);
internal static readonly DependencyProperty LightIntensityProperty =
DependencyProperty.Register("LightIntensity", typeof(double), typeof(SpecularShader),
// !do not put default value in the metadata (it will make the whole thing not work!)
new PropertyMetadata(PixelShaderConstantCallback(1 )));
private static readonly DependencyProperty DotProductProperty =
DependencyProperty.Register("DotProduct", typeof(double), typeof(SpecularShader),
// !do not put default value in the metadata (it will make the whole thing not work!)
new PropertyMetadata(PixelShaderConstantCallback(0 )));
The updated Xaml markup provides declarative information about scene's directional light:
<Image Source="images/sample.jpg" x:Name="img" Width="420" Height="235"
HorizontalAlignment="Center" VerticalAlignment="Center">
<Image.Projection>
<PlaneProjection CenterOfRotationX="0.5"
CenterOfRotationY="0.5"
CenterOfRotationZ="0.5"
RotationY="30"/>
</Image.Projection>
<i:Interaction.Behaviors>
<ryoushin:TrackballBehavior x:Name="trackball"
LightIntensity="1"
LightVectorX=".25"
LightVectorY="-1"/>
</i:Interaction.Behaviors>
</Image>
Nota bene: demo and code have been implemented on top of Silverlight 3 Beta1, I
do not tend
nor intend to
modify the content of this article to match the future releases of the Silverlight plugin.
«
Silverlight TrackballBehavior+Shader
Take care. Bye.