Custom Bitmap Effects - HLSL
Written by Mike James   
Monday, 14 June 2010
Article Index
Custom Bitmap Effects - HLSL
Constants and samplers
The default sampler
Embossed effect



Now we need to implement the dependency property so that we can pass the WPF bitmap into the shader as register S1. To do this we define a new property of type Brush:

public Brush Bitmap1
get { return
(Brush)GetValue(Bitmap1Property); }

set { SetValue(Bitmap1Property, value); }

and associate it with a dependency property:

public static readonly 
DependencyProperty Bitmap1Property =

"Bitmap1", typeof(BlankEffect),1);

The only difference is that we use the special Register method RegisterPixelShaderSamplerProperty, which specifies as its final parameter the register number to be used, i.e. in this case s1. Now we can write some code to make it work.

Assuming that we have bitmap stored in a BitmapSource object then we can create an ImageBrush quite easily:

BitmapImage bmi = new BitmapImage(uri);
ImageBrush pic=new ImageBrush(bmi);

and use this to set the new dependency property:

BlankEffect BE = new BlankEffect();
button1.Effect = BE;

If you now run the program, remembering to save and recompile the shader, what you will see is the bitmap displayed in the area that would normally be used to render the button.


The button before the effect


The button with the effect applied

The default sampler

At this point you might be begining to see how it all fits together but we have one last element to put into place.

The default value for any sampler dependency property that you might define is supplied by the static ImplicitInput property of the Effects class. This is set to a brush that is obtained by rendering the UIElement that the effect is applied to. To make sure that a dependency property adopts this default you have to add an UpdateShaderValue method call to set the default value - usually in constructor. So, if we add:


to the end of the constructor, Bitmap1Property is initialised to a brush that is the result of rendering the control that it is assigned to. If you assign another brush to the property then this is overwritten by the new brush.

Any sampler dependency property that has an UpdateShaderValue call and isn't explicitly assigned to a brush has the default value of the rendered control.

Hence if you now remove the setting of the Bitmap1 property, i.e. remove the instruction:


the same shader will simply draw the button as it is usually displayed.

In most cases it is usual to set register s0 to be the default brush, and hence the rendered control, and it is also common to define a dependency property just to represent the brush that results from rendering the control. All of this should become clear in the following example.






Last Updated ( Tuesday, 27 July 2010 )