Microsoft Communities

Welcome to WindowsClient.net | Sign in | Join

Using Effects in WPF, Part 2

In a previous post on Effects gave a simple example of instantiating a parameter-less Effect. It just took the complement of a color through XAML. Now let's discuss more about the use of Effects.

First, lest you think that Effects are somehow a XAML-only feature, let’s write some code to use Effects. Recall that the invocation of the Effect through XAML looked like this:

<Grid>
  <Grid.Effect>
    <eff:ColorComplementEffect />
  </Grid.Effect>
  <Image ...="" />
  <Button ...="" />
  <TextBox ...="" />
</Grid>

In code, presuming I already have the Grid and it's called "myGrid", we’d just do the following:

                    myGrid.Effect = new MyEffects.ColorComplementEffect();

Like everything in WPF, Effects can be created and manipulated in code, so most of the below will focus on usage through XAML.

The ColorComplementEffect is very limited in what it can do, as it takes no parameters. Let's look at using an Effect that does take parameters. This is an intensity-thresholding effect. For each pixel, it determines if the pixel is above a certain intensity and, if so, outputs that pixel; otherwise, it outputs a constant color (transparent by default). The XAML below applies the ThresholdEffect with a threshold value of 0.2, and yellow as the color to fill in those pixels that are below an average 0.2 intensity.

<Grid>
  <Grid.Effect>
    <eff:ThresholdEffect Threshold="0.25" BlankColor="Orange" />
  </Grid.Effect>
  <Image ...="" />
  <Button ...="" />
  <TextBox ...="" />
</Grid>

The result looks like this:

The ThresholdEffect class exposes Threshold and BlankColor as DependencyProperties, so we can use our standard WPF techniques to databind and animate these properties. For instance, the XAML below introduces a slider and wires the Threshold value of the ThresholdEffect to the value of the slider. As you move the slider, the grid content "thresholds" in and out:

<Grid>
  <Grid.Effect>
    <eff:ThresholdEffect Threshold="{BindingElementName=thresholdSlider, Path=Value}"
        BlankColor="Orange" />
  </Grid.Effect>
  <Image ...="" />
  <Button ...="" />
  <TextBox ...="" />
</Grid>
<Slider Name="thresholdSlider" Minimum="0" Maximum="1"...=""/>

Chaining Effects

In the world of GPU programming, there’s a concept known as "multi-pass", where the programmer sets up multiple pixel shaders and cycles through them, with the output of one becoming the input of the next. In this release of WPF, we do not have explicit support for building multi-pass effects. However, WPF provides a very natural way to express what is typically desired, namely "containment". If I want to apply my ThresholdEffect as above; but, after that, I want to apply the ColorComplementEffect, a very simple way to do this is to take the Grid shown above and wrap a Border around it. On this Border, add the ColorComplementEffect. Here's the XAML:

<Border>
  <Border.Effect>
    <eff:ColorComplementEffect />
  </Border.Effect>
  <Grid >
    <Grid.Effect>
      <eff:ThresholdEffect Threshold="0.25" BlankColor="Orange" />
    </Grid.Effect>
    <Image ...="" />
    <Button ...="" />
    <TextBox ...=""/>
  </Grid>
</Border>

Here's what this looks like:

Multi-input Effects

These Effects receive a single input bitmap from the UIElement they are attached to and can have an arbitrary number of "scalar" properties through DependencyProperties that the Effect author provides for his users, and that they can be chained via element containment. These "scalar" properties are things like double, Color, Point, Point3D, Vector, Vector3D, Size, etc.

One thing that all the Effects have in common is they have exactly one bitmap input: the rasterization of the UIElement they're being applied to. WPF also supports "multi-input" effects where multiple UIElements (or other sources of bitmap data) can be provided to and manipulated by an Effect. (We don't consider effects like ThresholdEffect to be multi-input even though they have multiple properties/parameters. We consider "multi-input" to mean receiving more than one bitmap input.)

Multi-input effects will be part of the .NET 3.5 SP1 release, but they're not in the Beta, so we won't discuss them further here.

Comments: 1

You must Login to comment.
 

Si: On September 19, 2008 10:28 AM said:

no comments

 

Featured Item

Page view counter