<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US"><title type="html">Greg Schechter's Blog</title><subtitle type="html">Bing Maps, Windows Presentation Foundation and Silverlight -- Graphics, Media, Animation, Programming Model and other goodies.</subtitle><id>http://blogs.msdn.com/b/greg_schechter/atom.aspx</id><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/greg_schechter/" /><link rel="self" type="application/atom+xml" href="http://blogs.msdn.com/b/greg_schechter/atom.aspx" /><generator uri="http://telligent.com" version="5.6.50428.7875">Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><updated>2008-05-12T10:08:00Z</updated><entry><title>Introducing the new Bing Maps beta</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/greg_schechter/archive/2009/12/06/introducing-the-new-bing-maps-beta.aspx" /><id>http://blogs.msdn.com/b/greg_schechter/archive/2009/12/06/introducing-the-new-bing-maps-beta.aspx</id><published>2009-12-07T05:19:51Z</published><updated>2009-12-07T05:19:51Z</updated><content type="html">&lt;p&gt;Well, I’ve been off the air for quite some time, and now have the opportunity to pop up and talk about what I’ve been working on lately.&amp;#160; I made the switch from focusing on building platforms like Silverlight, WPF and the Desktop Window Manager to building an app built on such platforms – namely the Bing Maps site.&amp;#160; It’s great way to be able to see what you’ve been working on from a different perspective, and exercise a different set of muscles.&lt;/p&gt;  &lt;p&gt;Last week was an exciting one: we launched the beta of the &lt;a href="http://www.bing.com/maps/explore"&gt;new Bing Maps site&lt;/a&gt;, the first to use Silverlight.&amp;#160; We don’t use Silverlight just for the sake of using it, but because it enables fantastic user-experiences and superior performance and fluidity.&amp;#160; &lt;a href="http://www.bing.com/community/blogs/maps/archive/2009/12/02/bing-maps-adds-streetside-enhanced-bird-s-eye-photosynth-and-more.aspx"&gt;Chris Pendleton’s blog entry&lt;/a&gt; give a lot more detail on what we’ve released.&amp;#160; Rather than repeating it here, I recommend just giving his entry a read.&amp;#160; Meanwhile, I will provide some links to some cool examples here – check ‘em out:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://www.bing.com/maps/explore/#/6q8tktt8ds6ck7p7"&gt;Bird’s Eye view in Manhattan looking over Central Park West&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.bing.com/maps/explore/#/4ym5h3xcvnrmysb5"&gt;Seattle’s Fremont neighborhood highlighting establishments via “What’s nearby”&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;A &lt;a href="http://www.bing.com/maps/explore/#/3z34clb69ghzd304"&gt;Photosynth, displayed in Bing Maps&lt;/a&gt;, of a famous sculpture of socialist workers in Tiananmen Square that I took back in May &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.bing.com/maps/explore/#/c5t2w9j028p1933o"&gt;Today’s Front Pages – from around the world&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.bing.com/maps/explore/#/6o9kkmjfvdtvl8k0"&gt;Current Tweets from downtown Chicago&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.bing.com/maps/explore/#/or3cf1yw3jkv4yx2"&gt;Locally relevant blogging content from San Francisco&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;We’ve learned a lot in building the site, and we have lots of surprises and improvements up our sleeves for upcoming releases, functionality, and perf improvements.&amp;#160; So stay tuned, and enjoy using &lt;a href="http://www.bing.com/maps/explore"&gt;Bing Maps&lt;/a&gt;!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9933273" width="1" height="1"&gt;</content><author><name>Greg Schechter</name><uri>http://blogs.msdn.com/Greg-Schechter/ProfileUrlRedirect.ashx</uri></author><category term="Silverlight" scheme="http://blogs.msdn.com/b/greg_schechter/archive/tags/Silverlight/" /><category term="Bing Maps" scheme="http://blogs.msdn.com/b/greg_schechter/archive/tags/Bing+Maps/" /></entry><entry><title>Effect Library posted</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/greg_schechter/archive/2008/10/22/effect-library-posted.aspx" /><id>http://blogs.msdn.com/b/greg_schechter/archive/2008/10/22/effect-library-posted.aspx</id><published>2008-10-23T02:13:50Z</published><updated>2008-10-23T02:13:50Z</updated><content type="html">&lt;p&gt;Troy Jefferson interned this summer with the WPF team and gathered a bunch of Effects that had been written by members of the WPF team.&amp;#160; These are now available for downloading on &lt;a href="http://www.codeplex.com/wpffx"&gt;CodePlex&lt;/a&gt;.&amp;#160; At that same site, you can also browse to a video of these effects in action.&lt;/p&gt;  &lt;p&gt;The single input effects in this library include:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;BandedSwirl&lt;/li&gt;    &lt;li&gt;Bloom&lt;/li&gt;    &lt;li&gt;BrightExtract&lt;/li&gt;    &lt;li&gt;ColorKeyAlpha&lt;/li&gt;    &lt;li&gt;ColorTone&lt;/li&gt;    &lt;li&gt;ContrastAdjust&lt;/li&gt;    &lt;li&gt;DirectionalBlur&lt;/li&gt;    &lt;li&gt;Embossed&lt;/li&gt;    &lt;li&gt;Gloom&lt;/li&gt;    &lt;li&gt;GrowablePoissonDiskEffect&lt;/li&gt;    &lt;li&gt;InvertColor&lt;/li&gt;    &lt;li&gt;LightStreak&lt;/li&gt;    &lt;li&gt;Magnify&lt;/li&gt;    &lt;li&gt;Monochrome&lt;/li&gt;    &lt;li&gt;Pinch&lt;/li&gt;    &lt;li&gt;Pixelate&lt;/li&gt;    &lt;li&gt;Ripple SharpenSmoothMagnify&lt;/li&gt;    &lt;li&gt;Swirl&lt;/li&gt;    &lt;li&gt;Tone&lt;/li&gt;    &lt;li&gt;Toon&lt;/li&gt;    &lt;li&gt;ZoomBlur&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;There are also a set of two-input effects package up as &amp;quot;transitions&amp;quot; for doing interesting visual transitions between elements.&amp;#160; These include:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;BandedSwirl&lt;/li&gt;    &lt;li&gt;Blinds&lt;/li&gt;    &lt;li&gt;Blood&lt;/li&gt;    &lt;li&gt;CircleReveal&lt;/li&gt;    &lt;li&gt;CircleStretch&lt;/li&gt;    &lt;li&gt;CircularBlur&lt;/li&gt;    &lt;li&gt;CloudReveral&lt;/li&gt;    &lt;li&gt;Cloudy&lt;/li&gt;    &lt;li&gt;Crumble&lt;/li&gt;    &lt;li&gt;Dissolve&lt;/li&gt;    &lt;li&gt;DropFade&lt;/li&gt;    &lt;li&gt;Fade&lt;/li&gt;    &lt;li&gt;LeastBright&lt;/li&gt;    &lt;li&gt;LineReveal&lt;/li&gt;    &lt;li&gt;MostBright&lt;/li&gt;    &lt;li&gt;PixelateIn&lt;/li&gt;    &lt;li&gt;PixelateOut&lt;/li&gt;    &lt;li&gt;Pixelate&lt;/li&gt;    &lt;li&gt;RadialBlur&lt;/li&gt;    &lt;li&gt;RadialWiggle&lt;/li&gt;    &lt;li&gt;RandomCircleReveal&lt;/li&gt;    &lt;li&gt;Ripple&lt;/li&gt;    &lt;li&gt;Rotate&lt;/li&gt;    &lt;li&gt;Saturate&lt;/li&gt;    &lt;li&gt;Shrink&lt;/li&gt;    &lt;li&gt;SlideIn&lt;/li&gt;    &lt;li&gt;SmoothSwirl&lt;/li&gt;    &lt;li&gt;Swirl&lt;/li&gt;    &lt;li&gt;Water&lt;/li&gt;    &lt;li&gt;Wave. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Thanks, Troy!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9011892" width="1" height="1"&gt;</content><author><name>Greg Schechter</name><uri>http://blogs.msdn.com/Greg-Schechter/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>A More Useful Multi-Input Effect</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/greg_schechter/archive/2008/09/27/a-more-useful-multi-input-effect.aspx" /><link rel="enclosure" type="application/x-zip-compressed" length="249656" href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-08-96-78-13/LogoDisplacer.zip" /><id>http://blogs.msdn.com/b/greg_schechter/archive/2008/09/27/a-more-useful-multi-input-effect.aspx</id><published>2008-09-28T05:00:00Z</published><updated>2008-09-28T05:00:00Z</updated><content type="html">&lt;P&gt;In &lt;A href="http://blogs.msdn.com/greg_schechter/archive/2008/09/16/introducing-multi-input-shader-effects.aspx" mce_href="http://blogs.msdn.com/greg_schechter/archive/2008/09/16/introducing-multi-input-shader-effects.aspx"&gt;my last post&lt;/A&gt;, I introduced multi-input effects, where you can send in arbitrary WPF brushes that are interpreted as samplers in the shader.&amp;nbsp; The example I did just showed simple image combination via linear combination of pixel values -- illustrative, but not very useful.&lt;/P&gt;
&lt;P&gt;In this post, I'm going to demonstrate a more useful application of multi-input effects.&amp;nbsp; One of the things that TV networks and local stations do to identify themselves as programs are airing is display a little image that looks like a bit like a watermark in the lower portion of the screen.&amp;nbsp; This is subtle enough to not be distracting, but also clearly identifies the source.&amp;nbsp; This sort of subtle branding can be quite powerful.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Some do this watermarking just via a translucent icon (trivial to do in WPF without Effects).&amp;nbsp; Others use the icon in a more sophisticated way.&amp;nbsp; We're going to show a more sophisticated way here.&lt;/P&gt;
&lt;P&gt;Here is a screenshot of the sample app that's included in this post.&amp;nbsp; Note the rose logo in the lower right hand corner of the image.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/AMoreUsefulMultiInputEffect_155A/image_8.png" mce_href="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/AMoreUsefulMultiInputEffect_155A/image_8.png"&gt;&lt;IMG style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=484 alt=image src="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/AMoreUsefulMultiInputEffect_155A/image_thumb_3.png" width=584 border=0 mce_src="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/AMoreUsefulMultiInputEffect_155A/image_thumb_3.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;If you look closely at this close up, you may be able to see that the rose icon is really shifting the underlying pixels.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;A href="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/AMoreUsefulMultiInputEffect_155A/image_10.png" mce_href="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/AMoreUsefulMultiInputEffect_155A/image_10.png"&gt;&lt;IMG style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=107 alt=image src="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/AMoreUsefulMultiInputEffect_155A/image_thumb_4.png" width=107 border=0 mce_src="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/AMoreUsefulMultiInputEffect_155A/image_thumb_4.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;This is known as "displacement mapping", and makes for a subtle yet distinctive effect as opposed to simply alpha blending the icon on top.&amp;nbsp; Note that here we use it on top of a static image.&amp;nbsp; However, this can be used on live video, on UI, atop DirectX content, etc.&lt;/P&gt;
&lt;H3&gt;Using the LogoDisplacer effect&lt;/H3&gt;
&lt;P&gt;The attached project includes a "LogoDisplacer" Effect.&amp;nbsp; The above is modeled as so in XAML:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Image &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Source&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="desert.jpg" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Stretch&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="None" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Loaded&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="Image_Loaded"&amp;gt;
    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Image.Effect&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
        &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;lds&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;LogoDisplacer &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Logo&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="{&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;StaticResource &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;logoImage&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;}" 
               &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Displacement&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="20&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;AdditionalLogoOpacity&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="0.4"&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt; /&amp;gt;
    &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Image.Effect&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Image&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;(For simplicitly, I've elided the databinding syntax that hooks the Displacement and AdditionalLogoOpacity properties to sliders.)&amp;nbsp; The "Logo" property itself is the secondary sampler input, and comes in as a reference to an ImageBrush resource in this case, defined as:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Window.Resources&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;ImageBrush &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;x&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Key&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="logoImage" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;ImageSource&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="LogoImage.png" /&amp;gt;
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Window.Resources&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;Here, LogoImage.png looks like this, but yours could be anything:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/AMoreUsefulMultiInputEffect_155A/image_16.png" mce_href="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/AMoreUsefulMultiInputEffect_155A/image_16.png"&gt;&lt;IMG style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=101 alt=image src="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/AMoreUsefulMultiInputEffect_155A/image_thumb_7.png" width=102 border=0 mce_src="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/AMoreUsefulMultiInputEffect_155A/image_thumb_7.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;This is a snapshot from Photoshop where the checkerboard represents fully transparent background pixels.&amp;nbsp; (I created this in Photoshop just by using a character from the Zapf Dingbats font, and then having the Layer Blending options set to Bevel &amp;amp; Emboss with Contouring.)&lt;/P&gt;
&lt;P&gt;The LogoDisplacer shader effect uses this logo image to displace the content under it.&amp;nbsp; It does so by, for each pixel, seeing how far the red channel is from 0.5, and offsetting in &lt;EM&gt;x&lt;/EM&gt; the lookup of the pixel from the input image by that fraction of the "Displacement" property (in pixels).&amp;nbsp; It will do the same with the green channel and the &lt;EM&gt;y&lt;/EM&gt; offset.&amp;nbsp; Thus if the image is grayscale (as in this example), red and green are the same, and the &lt;EM&gt;x&lt;/EM&gt; and &lt;EM&gt;y&lt;/EM&gt; displacement will be the same.&amp;nbsp; This is all modulated by the alpha channel of the logo, so where there are transparent pixels in the logo, no displacement occurs.&lt;/P&gt;
&lt;P&gt;After this potentially displaced lookup into the original image happens, the corresponding pixel from the logo image itself is blended in with "AdditionalLogoOpacity" alpha, to make the logo more apparent.&amp;nbsp; AdditionalLogoOpacity should be small enough to not overshadow the displacement, but big enough to allow the overlay to be discernible.&lt;/P&gt;
&lt;P&gt;When I apply the LogoDisplacer effect as constructed above, my result looks like this:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/AMoreUsefulMultiInputEffect_155A/image_12.png" mce_href="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/AMoreUsefulMultiInputEffect_155A/image_12.png"&gt;&lt;IMG style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=484 alt=image src="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/AMoreUsefulMultiInputEffect_155A/image_thumb_5.png" width=584 border=0 mce_src="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/AMoreUsefulMultiInputEffect_155A/image_thumb_5.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Not quite the result we were hoping for, since we want the rose just in the lower right hand corner, and at it's original pixel size.&lt;/P&gt;
&lt;P&gt;The reason the rose takes up the whole image was discussed in the last post.&amp;nbsp; The sampler inputs are &lt;EM&gt;always&lt;/EM&gt; sized to match the render size of the UIElement that the effect is being applied to.&amp;nbsp; So even though our logo image is 100x100, it gets scaled up to the size of the desert image (1024x768), and that's why it's pixellated.&lt;/P&gt;
&lt;P&gt;We need to do something that prevents this resize/pixellation.&amp;nbsp; Since we know that whatever input we provide will be scaled to the size of the UIElement, we can't do a predetermined scaling -- that is, we can't create a 1024x768 image and just put the rose in the lower right hand corner, because if I apply to a UIElement of a different size, the scaling will be wrong again.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Using the Viewbox property&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;What we do instead is rely on the Viewbox property of ImageBrush.&amp;nbsp; By default, Viewbox is the unit-rect ([0,0,1,1]) that the image fills.&amp;nbsp; If we make the Viewbox larger, we can in effect position the unit-rectangle (and thus the logo) anywhere within that larger viewbox.&amp;nbsp; If I make the Viewbox be [0,0,2,2], then the logo will fill the upper left quadrant.&amp;nbsp; If I make it (-1,-1,2,2), then it will fill the lower right quadrant.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;A little math then lets us figure out how to size the Viewbox so that it fits in the lower right 100x100 pixels (or whatever the logo's pixel size is), based on the actual width and height of the UIElement.&amp;nbsp; The following is the event handler invoked when the desert image above completes loading:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;private void &lt;/SPAN&gt;Image_Loaded(&lt;SPAN style="COLOR: blue"&gt;object &lt;/SPAN&gt;sender, &lt;SPAN style="COLOR: #2b91af"&gt;RoutedEventArgs &lt;/SPAN&gt;e)
{
    &lt;SPAN style="COLOR: #2b91af"&gt;ImageBrush &lt;/SPAN&gt;logo = (&lt;SPAN style="COLOR: #2b91af"&gt;ImageBrush&lt;/SPAN&gt;)&lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;.Resources[&lt;SPAN style="COLOR: #a31515"&gt;"logoImage"&lt;/SPAN&gt;];

    &lt;SPAN style="COLOR: green"&gt;// Create a viewbox so that the original logo image is in the &lt;BR&gt;    // lower right hand corner at its original pixel size (relative &lt;BR&gt;    // to the image element).
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Image &lt;/SPAN&gt;thisImage = (&lt;SPAN style="COLOR: #2b91af"&gt;Image&lt;/SPAN&gt;)sender;
    &lt;SPAN style="COLOR: #2b91af"&gt;BitmapSource &lt;/SPAN&gt;bms = logo.ImageSource &lt;SPAN style="COLOR: blue"&gt;as &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;BitmapSource&lt;/SPAN&gt;;
    &lt;SPAN style="COLOR: blue"&gt;double &lt;/SPAN&gt;scaleX = (&lt;SPAN style="COLOR: blue"&gt;double&lt;/SPAN&gt;)thisImage.ActualWidth / bms.PixelWidth;
    &lt;SPAN style="COLOR: blue"&gt;double &lt;/SPAN&gt;scaleY = (&lt;SPAN style="COLOR: blue"&gt;double&lt;/SPAN&gt;)thisImage.ActualHeight / bms.PixelHeight;

    &lt;SPAN style="COLOR: green"&gt;// Choose viewbox to move it into the lower right.
    &lt;/SPAN&gt;logo.Viewbox = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Rect&lt;/SPAN&gt;(1.0 - scaleX, 1.0 - scaleY, scaleX, scaleY);
}&lt;/PRE&gt;
&lt;P&gt;Now, when we run the app, we get the first image shown in this post, with the logo at its correct pixel size in the lower right hand corner of the image.&lt;/P&gt;
&lt;P&gt;Note also that since the logo is just an ImageBrush, it can be made dynamic. The attached solution has the logo slowly rotating about its center.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;A note about performance&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;The performance impact of a sample like this can be deceiving, since we're only showing the lower right hand corner of the element being affected.&amp;nbsp; However, remember that all pixels in the element are being examined..., but only those within the logo are being modified.&amp;nbsp; Thus, any modifications to the element itself will cause the entire effect to be re-run over the element.&amp;nbsp; So, while the GPU &lt;EM&gt;is&lt;/EM&gt; incredibly fast, there are still limits, and one should be aware of the implications.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;Writing the LogoDisplacer effect&lt;/H3&gt;
&lt;P&gt;Let's move on to how the LogoDisplacer effect gets written.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;The C# file&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;The C# file, LogoDisplacer.cs, doesn't really have anything very interesting.&amp;nbsp; It just sets up the DependencyProperties that are bound to shader registers, as we've seen with other shaders.&amp;nbsp; In this case, there's Input (Sampler Register 0), Logo (Sampler Register 1), Displacement (Constant Register 0), and AdditionalLogoOpacity (Constant Register 1).&amp;nbsp; We also include this mellifluous property setting, which we discuss in the Appendix of this posting:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;.DdxUvDdyUvRegisterIndex = 6;&lt;/PRE&gt;&lt;PRE class=code&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;&lt;STRONG&gt;The FX file&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;This is where things get more interesting.&amp;nbsp; Here's the entire .fx file:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: green"&gt;//-----------------------------------------------------------------------------------------
// Shader constant register mappings (scalars - float, double, Point, Color, Point3D, etc.)
//-----------------------------------------------------------------------------------------

&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;float  &lt;/SPAN&gt;displacement : register(C0);
&lt;SPAN style="COLOR: blue"&gt;float  &lt;/SPAN&gt;additionalLogoOpacity : register(C1);
float4 ddxDdy : register(C6);

&lt;SPAN style="COLOR: green"&gt;//--------------------------------------------------------------------------------------
// Sampler Inputs (Brushes, including ImplicitInput)
//--------------------------------------------------------------------------------------

&lt;/SPAN&gt;sampler2D implicitInputSampler : register(S0);
sampler2D logoSampler : register(S1);


&lt;SPAN style="COLOR: green"&gt;//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------

&lt;/SPAN&gt;float4 main(float2 uv : TEXCOORD) : COLOR
{
   &lt;SPAN style="COLOR: green"&gt;// Pull the sample from the logo.
   &lt;/SPAN&gt;float4 logoSample = tex2D(logoSampler, uv);
   
   &lt;SPAN style="COLOR: green"&gt;// See how far away the the red and green channels are from "gray".  Use this
   // value to shift.
   &lt;/SPAN&gt;float2 fracShift = float2(0.5,0.5) - logoSample.rg;
   
   &lt;SPAN style="COLOR: green"&gt;// But first modulate the shift by the alpha in the logo.  Most of the logo is
   // transparent, so this will zero out fracShift anywhere other than the logo.
   &lt;/SPAN&gt;fracShift *= logoSample.a;
   
   &lt;SPAN style="COLOR: green"&gt;// Calculate coordinate to sample main image at, by displacing by the logo's
   // "distance from gray".  ddxDdy is used to ensure that "displacement" is treated
   // in pixel units (it maps from pixel units to [0,1] units).
   &lt;/SPAN&gt;float2 displacedCoord = uv + fracShift * displacement &lt;BR&gt;                              * float2(length(ddxDdy.xy), length(ddxDdy.zw));
    
   &lt;SPAN style="COLOR: green"&gt;// Now get the main image's color at that displaced coordinate.
   &lt;/SPAN&gt;float4 color = tex2D(implicitInputSampler, displacedCoord);
    
   &lt;SPAN style="COLOR: green"&gt;// And mix in that color with a portion of the logo, to make the logo more clearly
   // visible.  Modulate it with "additionalLogoOpacity".
   &lt;/SPAN&gt;float4 finalColor = color + logoSample * logoSample.a * additionalLogoOpacity;
   
   &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;finalColor;
}&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The first sections (up until "main") are just setting up the register associations that we showed in the C# file.&amp;nbsp; Then, the main() entry point:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Pulls out the color value from the logo and sees how far red and green are from 0.5 (modulating by the alpha value so it will be zero for transparent pixels).&lt;/LI&gt;
&lt;LI&gt;Figures out where to sample the main input image based upon the distances from 0.5, multiplied by the incoming "displacement" value that was in a DependencyProperty.&amp;nbsp; (The DdxDdy thing is mentioned here... we'll get there soon...)&lt;/LI&gt;
&lt;LI&gt;Now samples the main input sampler at this potentially displaced coordinate, arriving at a color.&lt;/LI&gt;
&lt;LI&gt;Finally adds in some portion of the logo pixel itself on the displaced color from the main input sampler, based upon the value of the AdditionalLogoOpacity DependencyProperty.&lt;/LI&gt;&lt;/UL&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;This results in the subtle but visible displacement effect we see in the above images.&amp;nbsp; A running solution is attached to this post (note that it requires the &lt;A href="http://blogs.msdn.com/greg_schechter/archive/2008/08/11/a-visualstudio-buildtask-and-project-and-item-templates-for-writing-shadereffects.aspx" mce_href="http://blogs.msdn.com/greg_schechter/archive/2008/08/11/a-visualstudio-buildtask-and-project-and-item-templates-for-writing-shadereffects.aspx"&gt;ShaderBuildTask from here&lt;/A&gt;.)&lt;/P&gt;
&lt;P&gt;That's all for now!&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Appendix: Advanced - a little about DdxUvDdyUvRegisterIndex&lt;/STRONG&gt; &lt;/P&gt;
&lt;P&gt;(Note that this is a fairly complicated topic that I'm not going to do full justice to in this post.)&lt;/P&gt;
&lt;P&gt;Recall that the PixelShader system samples textures within a unit square, [0,0,1,1].&amp;nbsp; However, our Displacement value is provided in pixels (which makes sense, since we typically want to display the logo at its original pixel size).&amp;nbsp; We need a way of converting from these pixel values into the unit square.&amp;nbsp; That's where DdxUvDdyUvRegisterIndex comes in.&amp;nbsp; You set it in the C# file to a constant register index, then in your shader, you access that register constant.&amp;nbsp; This constant is a float4, representing the increment in unit coordinates that the GPU needs to move when sampling to get to the next pixel to process.&amp;nbsp; The components are as follows:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;ddxDdy.x - the unit coord distance in x to move one horizontal pixel in the destination sampler.&lt;/LI&gt;
&lt;LI&gt;ddxDdy.y - the unit coord distance in y to move one horizontal pixel in the destination sampler.&lt;/LI&gt;
&lt;LI&gt;ddxDdy.z - the unit coord distance in x to move one vertical pixel in the destination sampler.&lt;/LI&gt;
&lt;LI&gt;ddxDdy.w - the unit coord distance in y to move one vertical pixel in the destination sampler.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Thus, in the above code, we multiply the Displacement by "float2(length(ddxDdy.xy), length(ddxDdy.zw))".&amp;nbsp; We take the length of x &amp;amp; y combined to tell us about the horizontal, the z &amp;amp; w combined to tell us about the vertical.&amp;nbsp; It's necessary to use all of these because if, for instance, I just used the primary components (x &amp;amp; w), but then rotated my source 90 degrees, these values would be 0, since horizontal movement no longer translated to x-coord movement in unit space.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8967813" width="1" height="1"&gt;</content><author><name>Greg Schechter</name><uri>http://blogs.msdn.com/Greg-Schechter/ProfileUrlRedirect.ashx</uri></author><category term="WPF" scheme="http://blogs.msdn.com/b/greg_schechter/archive/tags/WPF/" /><category term="Effects" scheme="http://blogs.msdn.com/b/greg_schechter/archive/tags/Effects/" /></entry><entry><title>Introducing Multi-Input Shader Effects</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/greg_schechter/archive/2008/09/16/introducing-multi-input-shader-effects.aspx" /><link rel="enclosure" type="application/x-zip-compressed" length="869827" href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-08-95-35-78/SimpleMultiInputEffect.zip" /><id>http://blogs.msdn.com/b/greg_schechter/archive/2008/09/16/introducing-multi-input-shader-effects.aspx</id><published>2008-09-16T10:16:00Z</published><updated>2008-09-16T10:16:00Z</updated><content type="html">&lt;P&gt;Thus far in &lt;A title="this series on Effects" href="http://blogs.msdn.com/greg_schechter/archive/2008/05/09/a-series-on-gpu-based-effects-for-wpf.aspx" mce_href="http://blogs.msdn.com/greg_schechter/archive/2008/05/09/a-series-on-gpu-based-effects-for-wpf.aspx"&gt;this series on Effects&lt;/A&gt;, we've discussed building and using Effects that have a single "texture" or "sampler" as input to them.&amp;nbsp; In the Beta of .NET 3.5 SP1, that's all that was available.&amp;nbsp; With the RTM release, we've added the ability to provide multiple samplers as input to the pixel shaders that drive Effects, thus substantially increasing the flexibility of what can be done with Effects.&lt;/P&gt;
&lt;P&gt;In this post, I'll show a very simple example of multi-input effects.&amp;nbsp; The result isn't anything particularly useful from a UI construction perspective, but it shows the general technique that can be used in more UI-relevant ways.&amp;nbsp; In fact, in the next post I do, I'll show something that's quite a bit more interesting from a UI perspective.&lt;/P&gt;
&lt;H2&gt;The result&lt;/H2&gt;
&lt;P&gt;I'll demonstrate a simple shader that just combines, via pixel addition, two images.&amp;nbsp; This lets me take these two images:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/IntroducingMultiInputShaderEffects_14F8C/Toco%20Toucan_2.jpg" mce_href="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/IntroducingMultiInputShaderEffects_14F8C/Toco%20Toucan_2.jpg"&gt;&lt;IMG style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=244 alt="A toucan perched on a branch in Brazil." src="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/IntroducingMultiInputShaderEffects_14F8C/Toco%20Toucan_thumb.jpg" width=324 border=0 mce_src="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/IntroducingMultiInputShaderEffects_14F8C/Toco%20Toucan_thumb.jpg"&gt;&lt;/A&gt;&amp;nbsp;&lt;A href="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/IntroducingMultiInputShaderEffects_14F8C/Tree_2.jpg" mce_href="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/IntroducingMultiInputShaderEffects_14F8C/Tree_2.jpg"&gt;&lt;IMG style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=244 alt="Sheep under a tree near Dorset, England." src="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/IntroducingMultiInputShaderEffects_14F8C/Tree_thumb.jpg" width=324 border=0 mce_src="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/IntroducingMultiInputShaderEffects_14F8C/Tree_thumb.jpg"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;and create a little app that can produce these sorts of combinations of the two:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/IntroducingMultiInputShaderEffects_14F8C/image_2.png" mce_href="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/IntroducingMultiInputShaderEffects_14F8C/image_2.png"&gt;&lt;IMG style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=265 alt=image src="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/IntroducingMultiInputShaderEffects_14F8C/image_thumb.png" width=324 border=0 mce_src="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/IntroducingMultiInputShaderEffects_14F8C/image_thumb.png"&gt;&lt;/A&gt; &lt;A href="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/IntroducingMultiInputShaderEffects_14F8C/image_4.png" mce_href="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/IntroducingMultiInputShaderEffects_14F8C/image_4.png"&gt;&lt;IMG style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=265 alt=image src="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/IntroducingMultiInputShaderEffects_14F8C/image_thumb_1.png" width=324 border=0 mce_src="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/IntroducingMultiInputShaderEffects_14F8C/image_thumb_1.png"&gt;&lt;/A&gt; &lt;A href="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/IntroducingMultiInputShaderEffects_14F8C/image_6.png" mce_href="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/IntroducingMultiInputShaderEffects_14F8C/image_6.png"&gt;&lt;IMG style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=265 alt=image src="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/IntroducingMultiInputShaderEffects_14F8C/image_thumb_2.png" width=324 border=0 mce_src="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/IntroducingMultiInputShaderEffects_14F8C/image_thumb_2.png"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;H2&gt;The code&lt;/H2&gt;
&lt;P&gt;Let's first look at the XAML needed to build this.&amp;nbsp; This example, in fact, has no code at all... it's all XAML.&amp;nbsp; (At least the program that consumes the Effect... the Effect definition itself requires code.)&lt;/P&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Window ... &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=code&gt;&lt;FONT size=4&gt;&lt;SPAN style="COLOR: blue"&gt;  &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Window.Resources&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=4&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
      &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;ImageBrush &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;x&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Key&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="treeKey" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;ImageSource&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=4&gt;&lt;SPAN style="COLOR: blue"&gt;="tree.jpg" /&amp;gt;
  &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Window.Resources&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;FONT size=4&gt;&amp;gt;
&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;StackPanel&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=code&gt;&lt;FONT size=4&gt;&lt;SPAN style="COLOR: blue"&gt;     &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Image &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Source&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="toucan.jpg" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Width&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="1024" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Height&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=4&gt;&lt;SPAN style="COLOR: blue"&gt;="768"&amp;gt;
         &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Image.Effect&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=4&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
             &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;eff&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;SimpleMultiInputEffect &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Input2&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="{&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;StaticResource &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;treeKey&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;}" &lt;BR&gt;                             &lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=4&gt;&lt;SPAN style="COLOR: red"&gt;MixInAmount&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="{&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Binding &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;ElementName&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=slider1, &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Path&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=4&gt;&lt;SPAN style="COLOR: blue"&gt;=Value}" /&amp;gt;
         &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Image.Effect&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=4&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
     &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Image&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;FONT size=4&gt;&amp;gt;
&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;        &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;StackPanel &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Margin&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="10" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Orientation&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="Horizontal"&amp;gt;
            &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Slider &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Minimum&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="-0.5" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Maximum&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="1" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;SmallChange&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="1" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;LargeChange&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="1" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Value&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="0.5" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="slider1" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Width&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="289" /&amp;gt;
            &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Label &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;HorizontalAlignment&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="Left"  &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="label1" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;VerticalAlignment&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="Bottom" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Width&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="120" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Content&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="{&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Binding &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;ElementName&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=slider1, &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Path&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=Value}" /&amp;gt;
        &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;StackPanel&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;    &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;StackPanel&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Window&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;FONT color=#000000&gt;The large text is the stuff that's more relevant here.&amp;nbsp; First note that we reference our tree.jpg image in an ImageBrush that's defined as a resource.&amp;nbsp; That's because all sampler inputs come in through WPF as Brushes.&amp;nbsp; In this case, it's an ImageBrush, but it could just as easily have been a VisualBrush, and thus anything that can be constructed in a WPF tree.&lt;/FONT&gt;&lt;/SPAN&gt; 
&lt;P&gt;Next, the &amp;lt;Image&amp;gt; displays the Toucan image, and we apply our custom "SimpleMultiInputEffect" to the &amp;lt;Image&amp;gt;.&amp;nbsp; Here, we set a property, Input2, as a reference to our ImageBrush holding the tree.&amp;nbsp; We also set a double-valued property MixInAmount, which is bound to the slider value.&amp;nbsp; The Effect itself lets MixInAmount control the amount of blending that Input2 will do against the primary input.&lt;/P&gt;
&lt;H2&gt;&amp;nbsp;&lt;/H2&gt;
&lt;P&gt;Moving to the Effect definition itself.&amp;nbsp; In the C# for the Effect, the only thing notable is that we define another Brush-valued DependencyProperty:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;public &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Brush &lt;/SPAN&gt;Input2
{
    &lt;SPAN style="COLOR: blue"&gt;get &lt;/SPAN&gt;{ &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;(&lt;SPAN style="COLOR: #2b91af"&gt;Brush&lt;/SPAN&gt;)GetValue(Input2Property); }
    &lt;SPAN style="COLOR: blue"&gt;set &lt;/SPAN&gt;{ SetValue(Input2Property, &lt;SPAN style="COLOR: blue"&gt;value&lt;/SPAN&gt;); }
}

&lt;SPAN style="COLOR: blue"&gt;public static readonly &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;DependencyProperty &lt;/SPAN&gt;Input2Property =
    &lt;SPAN style="COLOR: #2b91af"&gt;ShaderEffect&lt;/SPAN&gt;.RegisterPixelShaderSamplerProperty(&lt;SPAN style="COLOR: #a31515"&gt;"Input2"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #2b91af"&gt;SimpleMultiInputEffect&lt;/SPAN&gt;), 1);&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;The "1" provided as the last argument to RegisterPixelShaderSamplerProperty() indicates that this Brush's realization will be available in sampler register "1" in the pixel shader.&lt;/P&gt;
&lt;P&gt;The HLSL gets a little more interesting:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;//-----------------------------------------------------------------------------------------
// Shader constant register mappings (scalars - float, double, Point, Color, Point3D, etc.)
//-----------------------------------------------------------------------------------------

float mixInAmount : register(C0);

//--------------------------------------------------------------------------------------
// Sampler Inputs (Brushes, including ImplicitInput)
//--------------------------------------------------------------------------------------

sampler2D input1 : register(S0);
sampler2D input2 : register(S1);


//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------

float4 main(float2 uv : TEXCOORD) : COLOR
{
   float4 color1 = tex2D(input1, uv);
   float4 color2 = tex2D(input2, uv);
   return color1 + mixInAmount * color2;
}&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;This is also very simple.&amp;nbsp; All that's happening here is that color1 and color2 are being sampled from the two input samplers (the Toucan and the Tree images, in our application), and combined according to the value of mixInAmount.&amp;nbsp; When that value is 0, we end up with pure Toucan .&amp;nbsp; When it's positive, we're adding Tree in.&amp;nbsp; When negative, we're subtracting Tree out.&amp;nbsp; All on a per-pixel basis.&lt;/P&gt;
&lt;H2&gt;More explanation&lt;/H2&gt;
&lt;P&gt;There are a few more details worth expanding on here:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;The secondary inputs get sized to the rendered size of the UIElement that the effect is being applied to.&amp;nbsp; Thus, when they make it into the shader, all the sampler inputs are the same pixel size.&amp;nbsp; You can use transforms on the incoming brushes, or viewport/viewbox, to manipulate different portions of the brush into place for finer control.&amp;nbsp; (In the above example, both the toucan image and the tree image are the same size, so it didn't matter here.) &lt;BR&gt;&lt;/LI&gt;
&lt;LI&gt;You might be wondering how the initial sampler input gets its value, since we never assigned in Brush-valued resources through XAML or code in previous examples.&amp;nbsp; That's because the default for all samplers (registered via RegisterPixelShaderSamplerProperty) is a special Brush that you get from accessing Effect.ImplicitInput.&amp;nbsp; ImplicitInput just means "construct a brush from the image resulting from rendering the UIElement that this Effect is being applied to".&amp;nbsp; So, in the case above, this is the &amp;lt;Image&amp;gt; element that we have the Toucan in.&amp;nbsp; If we were applying the Effect to a Button, it'd be the rasterization of the Button. &lt;/LI&gt;&lt;/OL&gt;
&lt;H2&gt;That's it&lt;/H2&gt;
&lt;P&gt;That's it for now.&amp;nbsp; I've attached the solution that demonstrates this.&amp;nbsp; To build it, it requires the &lt;A href="http://blogs.msdn.com/greg_schechter/archive/2008/08/11/a-visualstudio-buildtask-and-project-and-item-templates-for-writing-shadereffects.aspx" mce_href="http://blogs.msdn.com/greg_schechter/archive/2008/08/11/a-visualstudio-buildtask-and-project-and-item-templates-for-writing-shadereffects.aspx"&gt;Shader Build Task that I had previously written about&lt;/A&gt;.&amp;nbsp; Next time I'll show a use of multiple effects that has a more practical use for UIs than the simple blending demonstrated above.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8953578" width="1" height="1"&gt;</content><author><name>Greg Schechter</name><uri>http://blogs.msdn.com/Greg-Schechter/ProfileUrlRedirect.ashx</uri></author><category term="WPF" scheme="http://blogs.msdn.com/b/greg_schechter/archive/tags/WPF/" /><category term="Effects" scheme="http://blogs.msdn.com/b/greg_schechter/archive/tags/Effects/" /></entry><entry><title>A VisualStudio BuildTask and project and item templates for writing ShaderEffects</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/greg_schechter/archive/2008/08/11/a-visualstudio-buildtask-and-project-and-item-templates-for-writing-shadereffects.aspx" /><id>http://blogs.msdn.com/b/greg_schechter/archive/2008/08/11/a-visualstudio-buildtask-and-project-and-item-templates-for-writing-shadereffects.aspx</id><published>2008-08-12T07:50:43Z</published><updated>2008-08-12T07:50:43Z</updated><content type="html">&lt;p&gt;In a number of places in &lt;a title="this series on Effects" href="http://blogs.msdn.com/greg_schechter/archive/2008/05/09/a-series-on-gpu-based-effects-for-wpf.aspx"&gt;this series on Effects&lt;/a&gt;, I've alluded to a VisualStudio BuildTask and project templates that ease the authoring of shader-based Effects.&amp;#160; We now have one up and available for you to download, install, and use.&amp;#160; This was written by Gerhard Schneider and me.&amp;#160; (Gerhard is the development lead who's team is responsible for implementing the new GPU-based Effects, among other things.)&amp;#160; We're distributing it as a CodePlex project under the Microsoft Public License.&amp;#160; You can find it at the &lt;a href="http://www.codeplex.com/wpf/Release/ProjectReleases.aspx?ReleaseId=14962"&gt;WPF Futures&lt;/a&gt; site, which is under the umbrella &lt;a href="http://www.codeplex.com/wpf"&gt;www.codeplex.com/wpf&lt;/a&gt;.&amp;#160; At that site, you'll find both a .zip file to install from, and the source code that you can peruse/modify yourself if you need to.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Once you have this installed, you can edit .fx files and the the corresponding C# ShaderEffect subclasses all in VisualStudio, and just hit F5 or rebuild from VS to compile the whole project, including compiling the .fx file and inserting the bytecode as a resource into the resultant assembly.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;The build task and project templates can be found in &amp;quot;Shader Effects BuildTask and Templates.zip&amp;quot;, and in there you'll find a README that documents what you need to do to install.&lt;/p&gt;  &lt;p&gt;Basically what the installer does is add a BuildTask assembly to the GAC.&amp;#160; This BuildTask gets run for &amp;quot;Effect&amp;quot; labeled project files, and basically runs the HLSL compiler on them, turning a .fx file into a .ps file containing the shader bytecode.&amp;#160; That .ps file is then included in the assembly as a resource, which will get loaded into a PixelShader object.&lt;/p&gt;  &lt;p&gt;Note that the machine that this is installed on &lt;u&gt;does not&lt;/u&gt; need to have the DirectX SDK installed.&amp;#160; In this case, it will use a statically linked shader compiler to compile the .fx file into bytecode.&amp;#160; If there is a DirectX SDK installed on the machine, it will try to use the latest one as the compiler.&lt;/p&gt;  &lt;p&gt;The VS project template lets you create a new Effect Library, with the right build directive in it's .csproj file, and an initial Effect subclass and .fx file.&amp;#160; The VS item template lets you add in new Effect subclasses and .fx files to the Effect Library assembly you're building.&lt;/p&gt;  &lt;p&gt;One thing to keep in mind:&amp;#160; the created C# project references a build task that runs trusted code.&amp;#160; This will cause a dialog like the following to pop up when you open a project.&amp;#160; You should expect this and click Yes (unless of course you think my code is going to reformat your hard drive :-) ):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/AVisualStudioBuildTaskandprojectanditemt_1331C/clip_image001_2.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="315" alt="clip_image001" src="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/AVisualStudioBuildTaskandprojectanditemt_1331C/clip_image001_thumb.png" width="433" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Important Note: the software referenced here is provided as-is, with no guarantees of updates/improvements/fixes/etc.&amp;#160; You're more than welcome, of course, to grab the code and modify it to suit your purposes.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8849921" width="1" height="1"&gt;</content><author><name>Greg Schechter</name><uri>http://blogs.msdn.com/Greg-Schechter/ProfileUrlRedirect.ashx</uri></author><category term="WPF" scheme="http://blogs.msdn.com/b/greg_schechter/archive/tags/WPF/" /><category term="Effects" scheme="http://blogs.msdn.com/b/greg_schechter/archive/tags/Effects/" /></entry><entry><title>.NET Framework 3.5SP1 and Visual Studio 2008 SP1 released!</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/greg_schechter/archive/2008/08/11/net-framework-3-5sp1-and-visual-studio-2008-sp1-released.aspx" /><id>http://blogs.msdn.com/b/greg_schechter/archive/2008/08/11/net-framework-3-5sp1-and-visual-studio-2008-sp1-released.aspx</id><published>2008-08-12T07:28:11Z</published><updated>2008-08-12T07:28:11Z</updated><content type="html">&lt;p&gt;Alright!&amp;#160; .NET 3.5 SP1 and VS 2008 SP1 are &lt;a href="http://go.microsoft.com/?linkid=9330986"&gt;live and available&lt;/a&gt; on the web today.&amp;#160; There are lots of places to read about all the great stuff there, but from the perspective of this blog, the two big additions over the Beta of .NET 3.5 SP1 are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Support for multiple texture inputs to shaders used in ShaderEffects.&amp;#160; The makes ShaderEffects quite a bit more expressive and powerful.&lt;/li&gt;    &lt;li&gt;The addition of D3DImage, allowing composition-level interop between DirectX surfaces and WPF.&amp;#160; This feature opens up many, many possibilities of meaningful integration between code that already uses DirectX, or code that is more appropriately written in DirectX than in WPF.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;That's just a teaser... I'll describe these in more detail (or link to other resources that do) in upcoming posts.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8849889" width="1" height="1"&gt;</content><author><name>Greg Schechter</name><uri>http://blogs.msdn.com/Greg-Schechter/ProfileUrlRedirect.ashx</uri></author><category term="WPF" scheme="http://blogs.msdn.com/b/greg_schechter/archive/tags/WPF/" /><category term="Effects" scheme="http://blogs.msdn.com/b/greg_schechter/archive/tags/Effects/" /></entry><entry><title>Interested in working on the WPF team?</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/greg_schechter/archive/2008/05/22/interested-in-working-on-the-wpf-team.aspx" /><id>http://blogs.msdn.com/b/greg_schechter/archive/2008/05/22/interested-in-working-on-the-wpf-team.aspx</id><published>2008-05-23T00:02:46Z</published><updated>2008-05-23T00:02:46Z</updated><content type="html">&lt;p&gt;As you can see from this and other blogs, there's lots of exciting stuff going on in WPF these days, and we're hiring!&amp;#160; Ivo Manolov, our Test Manager has &lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2008/05/20/8526007.aspx"&gt;a post about job openings&lt;/a&gt; in Quality Assurance for WPF, including a posting for a Test Architect.&amp;#160; Also, &lt;a href="http://windowsclient.net/jobs/#wpf"&gt;here's a site that contains job listings&lt;/a&gt; for both Software Development positions and Quality Assurance positions.&lt;/p&gt;  &lt;p&gt;Interested?&amp;#160; Check it out!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8534115" width="1" height="1"&gt;</content><author><name>Greg Schechter</name><uri>http://blogs.msdn.com/Greg-Schechter/ProfileUrlRedirect.ashx</uri></author><category term="WPF" scheme="http://blogs.msdn.com/b/greg_schechter/archive/tags/WPF/" /></entry><entry><title>Writing custom Effects - adding parameters to Effects</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/greg_schechter/archive/2008/05/15/writing-custom-effects-adding-parameters-to-effects.aspx" /><id>http://blogs.msdn.com/b/greg_schechter/archive/2008/05/15/writing-custom-effects-adding-parameters-to-effects.aspx</id><published>2008-05-16T02:15:11Z</published><updated>2008-05-16T02:15:11Z</updated><content type="html">&lt;p&gt;A &lt;a href="http://blogs.msdn.com/greg_schechter/archive/2008/05/12/introduction-to-writing-effects.aspx"&gt;couple of posts ago&lt;/a&gt;, I wrote about writing custom Effects.&amp;#160; The example that I dove into was ColorComplementEffect, an Effect that has no parameters other than the incoming &amp;quot;sampler&amp;quot; that it inverts the color on.&lt;/p&gt;  &lt;p&gt;This post is going to go into what it takes to add parameters to your Effects, which allows for much, much more powerful Effects. &lt;/p&gt;  &lt;h3&gt;Shader Constants and Dependency Properties&lt;/h3&gt;  &lt;p&gt;The first thing to understand is that HLSL shaders expose &amp;quot;shader constants&amp;quot; bound to &amp;quot;shader registers&amp;quot;.&amp;#160; We saw a shader constant in the form of a &amp;quot;sampler2D&amp;quot; called &amp;quot;implicitInput&amp;quot; in the previous post on writing Effects:&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre&gt;&lt;font color="#004080"&gt;sampler2D implicitInput : register(s0);&lt;/font&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;The parameters we discuss here will be shader constants of type float, float2, float3, or float4 in HLSL.&amp;#160; These shader constants maintain their value for an entire &amp;quot;frame&amp;quot; of the pixel shader executing across every pixel in the frame.&amp;#160; This is why they're called &amp;quot;shader constants&amp;quot;, since they're constant per-frame, though they can and often do change between frames.&lt;/p&gt;

&lt;p&gt;From an Effects point of view, they can be thought of as a property or parameter of the shader/effect.&amp;#160; And we already have a great way of dealing with properties in WPF -- we use DependencyProperties, which provides for change notification, databinding, animation, etc.&lt;/p&gt;

&lt;p&gt;So... the next step is kind of obvious...&amp;#160; we expose HLSL shader constants through custom Dependency Properties on the corresponding Effect.&lt;/p&gt;

&lt;h3&gt;An example - ThresholdEffect&lt;/h3&gt;

&lt;p&gt;Let's move to a simple example... the ThresholdEffect used &lt;a href="http://blogs.msdn.com/greg_schechter/archive/2008/05/12/using-effect-in-wpf-part-2.aspx"&gt;here&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;        &amp;lt;eff:ThresholdEffect Threshold=&amp;quot;0.25&amp;quot; BlankColor=&amp;quot;Orange&amp;quot; /&amp;gt;&lt;/pre&gt;

&lt;pre&gt;&lt;a href="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/UsingEffectinWPFPart2_D6D8/image_2.png"&gt;&lt;img height="273" alt="image" src="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/UsingEffectinWPFPart2_D6D8/image_thumb.png" width="364" border="0" /&gt;&lt;/a&gt;&lt;/pre&gt;

&lt;p&gt;This Effect just turns pixels that are below the specified Threshold intensity (0.25 in the case above) into the BlankColor (orange, in the case above).&lt;/p&gt;

&lt;p&gt;Here's the HLSL for the ThresholdEffect:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;font color="#004080"&gt;sampler2D implicitInput : register(s0);
float threshold : register(c0);
float4 blankColor : register(c1);

float4 main(float2 uv : TEXCOORD) : COLOR
{
    float4 color = tex2D(implicitInput, uv);
    float intensity = (color.r + color.g + color.b) / 3;
    
    float4 result;
    if (intensity &amp;gt; threshold)
    {
        result = color;
    }
    else
    {
        result = blankColor;
    }
    
    return result;
}&lt;/font&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;It's a very straightforward effect.&amp;#160; It samples the texture, figures out the intensity by averaging RGB, and if above the threshold returns the sampled color, otherwise the blankColor.&lt;/p&gt;

&lt;p&gt;I'll list the entire C# for the ThresholdEffect class below, but the most important part is to understand how these properties are defined.&amp;#160; Here's one of them, Threshold:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public double &lt;/span&gt;Threshold
{
    &lt;span style="color: blue"&gt;get &lt;/span&gt;{ &lt;span style="color: blue"&gt;return &lt;/span&gt;(&lt;span style="color: blue"&gt;double&lt;/span&gt;)GetValue(ThresholdProperty); }
    &lt;span style="color: blue"&gt;set &lt;/span&gt;{ SetValue(ThresholdProperty, &lt;span style="color: blue"&gt;value&lt;/span&gt;); }
}

&lt;span style="color: blue"&gt;public static readonly &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DependencyProperty &lt;/span&gt;ThresholdProperty = 
    &lt;span style="color: #2b91af"&gt;DependencyProperty&lt;/span&gt;.Register(&lt;span style="color: #a31515"&gt;&amp;quot;Threshold&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: blue"&gt;double&lt;/span&gt;), &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ThresholdEffect&lt;/span&gt;), 
            &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;UIPropertyMetadata&lt;/span&gt;(0.5, PixelShaderConstantCallback(0)));&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The CLR getter/setter Threshold is identical to all CLR getter/setters for DPs... it just does a GetValue/SetValue.&amp;#160; Then the definition for ThresholdProperty is also the same as all DPs...&amp;#160; the one difference is that the PropertyChangedCallback is created via &amp;quot;PixelShaderConstantCallback(registerNumber)&amp;quot;, which generates a callback to be invoked when the property changes.&amp;#160; In this case, we pass 0 as the parameter to PixelShaderConstantCallback, since that matches the &amp;quot;threshold&amp;quot; shader constant in the HLSL that's assigned register &amp;quot;c0&amp;quot;.&lt;/p&gt;

&lt;p&gt;Once we've set this up, ThresholdProperty is just like any other DP in the system.&amp;#160; Bind to it, bind from it, animate it, etc.&lt;/p&gt;

&lt;p&gt;The only other thing we need to do is call &amp;quot;UpdateShaderValue(ThresholdProperty)&amp;quot; in the constructor of the Effect.&amp;#160; This is necessary to inform the system about this value the first time, since the PropertyChangedCallback doesn't execute when the default value is set.&amp;#160; Don't forget to call UpdateShaderValue() on each of the properties you define, including InputProperty!!&lt;/p&gt;

&lt;h3&gt;What Types are supported?&lt;/h3&gt;

&lt;p&gt;The DependencyProperties that are bound to floating point shader constant registers can be any of the following types:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Double &lt;/li&gt;

  &lt;li&gt;Single ('float' in C#) &lt;/li&gt;

  &lt;li&gt;Color &lt;/li&gt;

  &lt;li&gt;Size &lt;/li&gt;

  &lt;li&gt;Point &lt;/li&gt;

  &lt;li&gt;Vector &lt;/li&gt;

  &lt;li&gt;Point3D &lt;/li&gt;

  &lt;li&gt;Vector3D &lt;/li&gt;

  &lt;li&gt;Point4D &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They each will go into their shader register filling up whatever number of components of that register are appropriate.&amp;#160; For instance, Double and Single go into one component, Color into 4, Size, Point and Vector into 2, etc.&amp;#160; Unfilled components are set to '1'.&lt;/p&gt;

&lt;h3&gt;Some minutiae&lt;/h3&gt;

&lt;p&gt;&lt;u&gt;Register Limit&lt;/u&gt;&lt;strong&gt;:&lt;/strong&gt; There is a limit of 32 floating point registers that can be used in PS 2.0.&amp;#160; In the unlikely event that you have more values than that that you want to pack in, you might consider tricks like packing, for instance, two Points into a single Point4D, etc.&lt;/p&gt;

&lt;p&gt;&lt;u&gt;What about int and bool registers?&lt;/u&gt;:&amp;#160; PS 2.0 doesn't deal particularly well with int and bool registers.&amp;#160; We decided to support only float registers.&amp;#160; If for some reason, you really need int or bool in your HLSL, you can cast a float register as appropriate.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;Complete ThresholdEffect listing&lt;/h3&gt;

&lt;p&gt;Finally, here's the entire listing for the ThresholdEffect class, which includes the Input sampler property, Threshold that we saw above, and the BlankColor property, that's managed in the exact same way that we did Threshold: &lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ThresholdEffect &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;ShaderEffect
&lt;/span&gt;{
    &lt;span style="color: blue"&gt;public &lt;/span&gt;ThresholdEffect()
    {
        PixelShader = _pixelShader;

        UpdateShaderValue(InputProperty);
        UpdateShaderValue(ThresholdProperty);
        UpdateShaderValue(BlankColorProperty);
    }

    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Brush &lt;/span&gt;Input
    {
        &lt;span style="color: blue"&gt;get &lt;/span&gt;{ &lt;span style="color: blue"&gt;return &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Brush&lt;/span&gt;)GetValue(InputProperty); }
        &lt;span style="color: blue"&gt;set &lt;/span&gt;{ SetValue(InputProperty, &lt;span style="color: blue"&gt;value&lt;/span&gt;); }
    }

    &lt;span style="color: blue"&gt;public static readonly &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DependencyProperty &lt;/span&gt;InputProperty =
        &lt;span style="color: #2b91af"&gt;ShaderEffect&lt;/span&gt;.RegisterPixelShaderSamplerProperty(&lt;span style="color: #a31515"&gt;&amp;quot;Input&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ThresholdEffect&lt;/span&gt;), 0);


    &lt;span style="color: blue"&gt;public double &lt;/span&gt;Threshold
    {
        &lt;span style="color: blue"&gt;get &lt;/span&gt;{ &lt;span style="color: blue"&gt;return &lt;/span&gt;(&lt;span style="color: blue"&gt;double&lt;/span&gt;)GetValue(ThresholdProperty); }
        &lt;span style="color: blue"&gt;set &lt;/span&gt;{ SetValue(ThresholdProperty, &lt;span style="color: blue"&gt;value&lt;/span&gt;); }
    }

    &lt;span style="color: blue"&gt;public static readonly &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DependencyProperty &lt;/span&gt;ThresholdProperty = 
        &lt;span style="color: #2b91af"&gt;DependencyProperty&lt;/span&gt;.Register(&lt;span style="color: #a31515"&gt;&amp;quot;Threshold&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: blue"&gt;double&lt;/span&gt;), &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ThresholdEffect&lt;/span&gt;), 
                &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;UIPropertyMetadata&lt;/span&gt;(0.5, PixelShaderConstantCallback(0)));


    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Color &lt;/span&gt;BlankColor
    {
        &lt;span style="color: blue"&gt;get &lt;/span&gt;{ &lt;span style="color: blue"&gt;return &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Color&lt;/span&gt;)GetValue(BlankColorProperty); }
        &lt;span style="color: blue"&gt;set &lt;/span&gt;{ SetValue(BlankColorProperty, &lt;span style="color: blue"&gt;value&lt;/span&gt;); }
    }

    &lt;span style="color: blue"&gt;public static readonly &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DependencyProperty &lt;/span&gt;BlankColorProperty =
        &lt;span style="color: #2b91af"&gt;DependencyProperty&lt;/span&gt;.Register(&lt;span style="color: #a31515"&gt;&amp;quot;BlankColor&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Color&lt;/span&gt;), &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ThresholdEffect&lt;/span&gt;), 
                &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;UIPropertyMetadata&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Colors&lt;/span&gt;.Transparent, PixelShaderConstantCallback(1)));


    &lt;span style="color: blue"&gt;private static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PixelShader &lt;/span&gt;_pixelShader =
        &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PixelShader&lt;/span&gt;() { UriSource = &lt;span style="color: #2b91af"&gt;Global&lt;/span&gt;.MakePackUri(&lt;span style="color: #a31515"&gt;&amp;quot;ThresholdEffect.ps&amp;quot;&lt;/span&gt;) };
}&lt;/pre&gt;&lt;/blockquote&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8509979" width="1" height="1"&gt;</content><author><name>Greg Schechter</name><uri>http://blogs.msdn.com/Greg-Schechter/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>A simple Effect sample project and ClickOnce application</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/greg_schechter/archive/2008/05/13/a-simple-effect-sample-project-and-clickonce-application.aspx" /><link rel="enclosure" type="application/x-zip-compressed" length="270538" href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-08-50-28-30/SimpleEffects_5F00_SP1Beta.zip" /><id>http://blogs.msdn.com/b/greg_schechter/archive/2008/05/13/a-simple-effect-sample-project-and-clickonce-application.aspx</id><published>2008-05-14T09:55:00Z</published><updated>2008-05-14T09:55:00Z</updated><content type="html">&lt;P&gt;The previous post in &lt;A href="http://blogs.msdn.com/greg_schechter/archive/2008/05/09/a-series-on-gpu-based-effects-for-wpf.aspx" mce_href="http://blogs.msdn.com/greg_schechter/archive/2008/05/09/a-series-on-gpu-based-effects-for-wpf.aspx"&gt;this series&lt;/A&gt; began to talk about writing custom Effects for WPF.&amp;nbsp; We looked specifically at ColorComplementEffect, an effect with no parameters.&amp;nbsp; In upcoming posts, we'll get into the details of multi-parameter effects and other specifics.&amp;nbsp; But in the meantime, I thought it would be useful to post a sample VS project and a ClickOnce application from that project for folks just itching to get going.&lt;/P&gt;
&lt;P&gt;The app looks like this:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/AsimpleEffectsampleprojectandClickOnceap_15045/image_2.png" mce_href="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/AsimpleEffectsampleprojectandClickOnceap_15045/image_2.png"&gt;&lt;IMG style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=413 alt=image src="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/AsimpleEffectsampleprojectandClickOnceap_15045/image_thumb.png" width=404 border=0 mce_src="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/AsimpleEffectsampleprojectandClickOnceap_15045/image_thumb.png"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;It's nothing fancy, mostly XAML and, in fact, the way the code and structure and UI are constructed are not conducive to hosting all effects now and forever (a more sophisticated hoster of effects would make a lot more use of metadata and reflection to allow arbitrary effects to be applied and parameters to be tweaked).&amp;nbsp; However, this definitely does the job in terms of showing how Effects are used and written.&amp;nbsp; There are two projects in the solution -- one is a MyEffects library, and the other just an EffectTest application that uses Effects from MyEffects.&lt;/P&gt;
&lt;P&gt;Note that this code and app are specific to the .NET 3.5 SP1 Beta release.&amp;nbsp; We already know of at least one breaking change in the RTM version that will require this code to be modified (just slightly).&lt;/P&gt;
&lt;P&gt;Without further ado:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://wpf.netfx3.com/direct/gregsc/SimpleEffectSample_SP1Beta/EffectTest.application" mce_href="http://wpf.netfx3.com/direct/gregsc/SimpleEffectSample_SP1Beta/EffectTest.application"&gt;Here's the ClickOnce application&lt;/A&gt; to run directly.&lt;/LI&gt;
&lt;LI&gt;&lt;A class="" href="http://blogs.msdn.com/greg_schechter/attachment/8502830.ashx" mce_href="http://blogs.msdn.com/greg_schechter/attachment/8502830.ashx"&gt;Here's the .zip file of the solution&lt;/A&gt; that's attached to this post.&amp;nbsp; All but about 15K of it is taken up by the JPEG image in the background.&amp;nbsp; (The other 15K is the good stuf :-) )&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;One thing to be aware of in the solution.&amp;nbsp; The compiled pixel shaders are included as resources in the MyEffects library.&amp;nbsp; I did the fxc.exe compilation outside of the project system.&amp;nbsp; As mentioned in the last post, we have a VS BuildTask in the works that will let this be part of the project system, but until then, I included the compiled bytecode directly.&lt;/P&gt;
&lt;P&gt;Have fun!&amp;nbsp; More to come...&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8502830" width="1" height="1"&gt;</content><author><name>Greg Schechter</name><uri>http://blogs.msdn.com/Greg-Schechter/ProfileUrlRedirect.ashx</uri></author><category term="WPF" scheme="http://blogs.msdn.com/b/greg_schechter/archive/tags/WPF/" /><category term="Effects" scheme="http://blogs.msdn.com/b/greg_schechter/archive/tags/Effects/" /></entry><entry><title>Writing custom GPU-based Effects for WPF</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/greg_schechter/archive/2008/05/12/introduction-to-writing-effects.aspx" /><id>http://blogs.msdn.com/b/greg_schechter/archive/2008/05/12/introduction-to-writing-effects.aspx</id><published>2008-05-12T20:08:00Z</published><updated>2008-05-12T20:08:00Z</updated><content type="html">&lt;P&gt;The last few posts in &lt;A href="http://blogs.msdn.com/greg_schechter/archive/2008/05/09/a-series-on-gpu-based-effects-for-wpf.aspx" mce_href="http://blogs.msdn.com/greg_schechter/archive/2008/05/09/a-series-on-gpu-based-effects-for-wpf.aspx"&gt;this series on Effects&lt;/A&gt; have focused on the perspective of those using Effects.&amp;nbsp; These Effects have to come into being somehow, and that's where we turn to now.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;In &lt;A href="http://blogs.msdn.com/greg_schechter/archive/2008/05/09/gpu-accelerated-custom-effects-for-wpf.aspx" mce_href="http://blogs.msdn.com/greg_schechter/archive/2008/05/09/gpu-accelerated-custom-effects-for-wpf.aspx"&gt;this post&lt;/A&gt; we showed how to apply a ColorComplementEffect to go from this to this:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/GPUacceleratedcustomeffectsforWPF_AD74/image_2.png" mce_href="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/GPUacceleratedcustomeffectsforWPF_AD74/image_2.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" border=0 alt=image src="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/GPUacceleratedcustomeffectsforWPF_AD74/image_thumb.png" width=240 height=187 mce_src="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/GPUacceleratedcustomeffectsforWPF_AD74/image_thumb.png"&gt;&lt;/A&gt;&amp;nbsp;&lt;A href="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/GPUacceleratedcustomeffectsforWPF_AD74/image_6.png" mce_href="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/GPUacceleratedcustomeffectsforWPF_AD74/image_6.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" border=0 alt=image src="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/GPUacceleratedcustomeffectsforWPF_AD74/image_thumb_1.png" width=240 height=187 mce_src="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/GPUacceleratedcustomeffectsforWPF_AD74/image_thumb_1.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;ColorComplementEffect, which very much looks like a photographic negative, is just about the simplest Effect one can imagine.&amp;nbsp; Conceptually, all it does is take the RGB color components and create a new color with each component subtracted from 1.0.&amp;nbsp; Let's first show what it takes to write it and add it to your app, then we'll expand and generalize from there in the next post.&lt;/P&gt;
&lt;H3&gt;Creating the HLSL for color complement&lt;/H3&gt;
&lt;P&gt;Here's some simple HLSL for doing the color complement.&amp;nbsp; Note that this series is not in the least intended to be an HLSL tutorial.&amp;nbsp; There are a bunch out on the Net, and there is also &lt;A href="http://msdn.microsoft.com/en-us/library/bb509561(VS.85).aspx" mce_href="http://msdn.microsoft.com/en-us/library/bb509561(VS.85).aspx"&gt;a Programmer's Guide and Reference Guide on MSDN&lt;/A&gt; that can be a good place to start.&amp;nbsp; Also starting from existing examples (like those included here) and tweaking and experimenting is always a good approach.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;FONT color=#004080&gt;sampler2D implicitInput : register(s0);

float4 main(float2 uv : TEXCOORD) : COLOR
{
    float4 color = tex2D(implicitInput, uv);&lt;BR&gt;
    float4 complement;
    complement.r = color.a - color.r;
    complement.g = color.a - color.g;
    complement.b = color.a - color.b;
    complement.a = color.a;&lt;BR&gt;
    return complement;
}&lt;/FONT&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;There are a few initial things worth noting here:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The "implicitInput" shader constant is what's in shader constant sampler register S0.&amp;nbsp; That's going to be the "original" composition of the textbox and button over the image, all converted to a "sampler".&amp;nbsp; We'll see in a bit how the association to register s0 happens. &lt;BR&gt;&lt;/LI&gt;
&lt;LI&gt;"main" is the entrypoint to the pixel shader.&amp;nbsp; It receives as input the texture coordinate (of type 'float2') of where we're currently outputting in the texture coordinate space of the element being applied to.&amp;nbsp; This varies from 0-1 in u and v.&amp;nbsp; Note again that while HLSL in general provides more flexibility on input types to shaders, for WPF currently, this is &lt;U&gt;always&lt;/U&gt; a float2-valued texture coordinate. &lt;BR&gt;&lt;/LI&gt;
&lt;LI&gt;Only a pixel shader is being provided here.&amp;nbsp; No vertex shader. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Given these, we now get to the body of the function.&amp;nbsp; The first line "tex2D" samples our input texture at the current sampling position uv, and receives a float4 (a 4-component vector with each value a float) that represents the color.&amp;nbsp; After declaring a local 'complement' float4, we proceed to assign it's R, G, and B values to&amp;nbsp;A minus the corresponding sampled value.&amp;nbsp; The A value (alpha) receives the corresponding sampled value's alpha directly.&amp;nbsp; Finally, we return that value.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;[May 1, 2009: My esteemed colleagues Ashraf and Don pointed out that my earlier incarnation of this of (1 - component) was wrong, and it should be (A - component).&amp;nbsp; That's because color RGB has their alpha value premultiplied through already.&amp;nbsp;&amp;nbsp;(1 - component) would work for non-premultiplied.&amp;nbsp; The reason it hasn't come up when I used it was the images I supplied were all opaque (A = 1) images, and in this case (1 - component) == (A - component).]&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;When the Effect runs, this main() function is executed on &lt;EM&gt;every&lt;/EM&gt; pixel affected.&amp;nbsp; It's run very fast, and quite a bit in parallel, but it is run.&lt;/P&gt;
&lt;P&gt;The above isn't the best way to express this HLSL.&amp;nbsp; The thing is that HLSL drives a SIMD vector processor, so rather than have these three separate RGB calculations, we can use HLSL to combine them:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;FONT color=#004080&gt;float4 main(float2 uv : TEXCOORD) : COLOR
{
    float4 color = tex2D(implicitInput, uv);&lt;BR&gt;
    float4 complement;
    complement.rgb = color.a - color.rgb;
    complement.a = color.a;&lt;BR&gt;
    return complement;
}&lt;/FONT&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;The syntax "complement.rgb =&amp;nbsp;color.a - color.rgb" will treat the "color.a" as replicated into each element of a 3-vector, and then do the subtraction on each element, all with a single PS 2.0 instruction.&amp;nbsp; (Actually, the HLSL compiler deduces this without me being explicit so the two above shaders generate the same number of instructions, but I never like to count on understanding exactly when compiler optimizations will or won't kick in in super performance sensitive code.)&lt;/P&gt;
&lt;H3&gt;Compiling the HLSL&lt;/H3&gt;
&lt;P&gt;WPF Effects do not take the HLSL text directly.&amp;nbsp; You need to compile it into the binary bytecode that DirectX natively accepts, which is how WPF passes it along.&amp;nbsp; To do this, you run fxc.exe on your shader file.&amp;nbsp; Fxc.exe is the shader compiler that comes with the &lt;A href="http://msdn.microsoft.com/en-us/library/aa139765.aspx" mce_href="http://msdn.microsoft.com/en-us/library/aa139765.aspx"&gt;Microsoft DirectX SDK&lt;/A&gt;.&amp;nbsp; You can find it at Utilities\Bin\x86\fxc.exe in the SDK.&lt;/P&gt;
&lt;P&gt;Say your HLSL was in 'cc.fx', the following command line would generate the compiled bytecode int 'cc.ps' in the same directory:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&amp;gt; &lt;FONT face=Consolas&gt;fxc /T ps_2_0 /E main /Focc.ps cc.fx&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;This says to compile to the PS 2.0 profile, and to look for the entrypoint named "main".&lt;/P&gt;
&lt;P&gt;(We have a rough prototype that adds the fxc.exe compilation as a MSBuild build task so that it can be incorporated directly into projects without having to break out to a command line shader compiler.&amp;nbsp; When that's further along, we'll post this out there for all to use.)&lt;/P&gt;
&lt;H3&gt;Writing your managed code Effect subclass&lt;/H3&gt;
&lt;P&gt;Now it's time to write our managed code that will expose this Effect out to WPF developers.&amp;nbsp; We'll use C# here.&amp;nbsp; &lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;using &lt;/SPAN&gt;System;&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;using &lt;/SPAN&gt;System.Windows;
&lt;SPAN style="COLOR: blue"&gt;using &lt;/SPAN&gt;System.Windows.Media;
&lt;SPAN style="COLOR: blue"&gt;using &lt;/SPAN&gt;System.Windows.Media.Effects;

&lt;SPAN style="COLOR: blue"&gt;namespace &lt;/SPAN&gt;MyEffects
{
    &lt;SPAN style="COLOR: blue"&gt;public class &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ColorComplementEffect &lt;/SPAN&gt;: &lt;SPAN style="COLOR: #2b91af"&gt;ShaderEffect
    &lt;/SPAN&gt;{
        &lt;SPAN style="COLOR: blue"&gt;public &lt;/SPAN&gt;ColorComplementEffect()
        {
            PixelShader = _shader;
            UpdateShaderValue(InputProperty);
        }

        &lt;SPAN style="COLOR: blue"&gt;public &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Brush &lt;/SPAN&gt;Input
        {
            &lt;SPAN style="COLOR: blue"&gt;get &lt;/SPAN&gt;{ &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;(&lt;SPAN style="COLOR: #2b91af"&gt;Brush&lt;/SPAN&gt;)GetValue(InputProperty); }
            &lt;SPAN style="COLOR: blue"&gt;set &lt;/SPAN&gt;{ SetValue(InputProperty, &lt;SPAN style="COLOR: blue"&gt;value&lt;/SPAN&gt;); }
        }

        &lt;SPAN style="COLOR: blue"&gt;public static readonly &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;DependencyProperty &lt;/SPAN&gt;InputProperty =
            &lt;SPAN style="COLOR: #2b91af"&gt;ShaderEffect&lt;/SPAN&gt;.RegisterPixelShaderSamplerProperty(
                    &lt;SPAN style="COLOR: #a31515"&gt;"Input"&lt;/SPAN&gt;, 
                    &lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #2b91af"&gt;ColorComplementEffect&lt;/SPAN&gt;), 
                    0);&lt;/PRE&gt;&lt;PRE class=code&gt;        &lt;SPAN style="COLOR: blue"&gt;private static &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;PixelShader &lt;/SPAN&gt;_shader =
            &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;PixelShader&lt;/SPAN&gt;() { UriSource = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Uri&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;@"pack://application:,,,/MyEffects;component/ColorComplementEffect.ps")&lt;/SPAN&gt; };

    }
}&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;&lt;/BLOCKQUOTE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;Here's basically how this works:&amp;nbsp; &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;We derive from ShaderEffect, itself a subclass of Effect.&amp;nbsp; Most importantly, ShaderEffect exposes a PixelShader property of type PixelShader. &lt;BR&gt;&lt;/LI&gt;
&lt;LI&gt;We define a static PixelShader instance which references the compiled bytecode.&amp;nbsp; It's static because the same PixelShader object can be shared amongst all instances of the Effect. &lt;BR&gt;&lt;/LI&gt;
&lt;LI&gt;We define a Brush-valued DependencyProperty called InputProperty, and the corresponding Input CLR property.&amp;nbsp; This is &lt;EM&gt;almost&lt;/EM&gt; identical to how we define other DPs in WPF.&amp;nbsp; The difference is that we use a helper method called ShaderEffect.RegisterPixelShaderSamplerProperty.&amp;nbsp; As in other DP definitions, both the name and the owning type are specified.&amp;nbsp; But the third parameter here (0, in this case) represents the sampler register that the Input property will be able to be accessed from in the shader.&amp;nbsp; Note that this 0 matches the s0 in the HLSL above: 
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;FONT color=#004080&gt;sampler2D implicitInput : register(s0);&lt;/FONT&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;UL&gt;
&lt;LI&gt;The instance constructor just assigns in the static _shader to the per-instance PixelShader property, and calls UpdateShaderValue() on any DPs that are associated with shader registers.&amp;nbsp; In this case, just the InputProperty.&amp;nbsp; This latter is necessary to ensure it's set for the first time, since DPs don't call their PropertyChangedCallbacks on the setting of their default values. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The other thing worth mentioning here is the gibberish in the "pack://" URI when we reference our pixel shader bytecode file, ColorComponentEffect.ps.&amp;nbsp; Since we don't want to reference a loose file on disk, and we'd like the shader bytecode to live in whatever packaging the C# ColorComponentEffect class goes into (since they should travel together), we use the WPF &lt;A href="http://msdn.microsoft.com/en-us/library/aa970069(VS.85).aspx" mce_href="http://msdn.microsoft.com/en-us/library/aa970069(VS.85).aspx"&gt;"pack://" URI syntax&lt;/A&gt;.&amp;nbsp; In this case, we're building a library called "MyEffects", which is why that appears in the pack URI.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;In order for this "pack://" URI to work, the bytecode needs to make its way into the built component.&amp;nbsp; You do this by adding the shader bytecode file into your project, and ensuring that its Build Action is set to "Resource" as this snip from the Solution Explorer shows:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/IntroductiontowritingEffects_11298/image_4.png" mce_href="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/IntroductiontowritingEffects_11298/image_4.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" border=0 alt=image src="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/IntroductiontowritingEffects_11298/image_thumb_1.png" width=289 height=306 mce_src="http://blogs.msdn.com/blogfiles/greg_schechter/WindowsLiveWriter/IntroductiontowritingEffects_11298/image_thumb_1.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;I have a little helper function that lets me express this URI string without hardwiring in "MyEffects", and without re-generating this same gibberish each time: &lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;PixelShader&lt;/SPAN&gt;() { UriSource = &lt;SPAN style="COLOR: #2b91af"&gt;Global&lt;/SPAN&gt;.MakePackUri(&lt;SPAN style="COLOR: #a31515"&gt;"ColorComplementEffect.ps"&lt;/SPAN&gt;) }&lt;BR&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;I include the code for the Global helper class at the bottom of this post.&lt;/P&gt;
&lt;P&gt;(Note also that PixelShader objects can also be defined via a Stream, which enables, for instance, authoring tools to construct shader bytecode on the fly and pass it to WPF without ever having to persist it to the file system.)&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;FONT color=#ff0000&gt;&amp;lt;Geek-Out-Alert--Somewhat-Esoteric-Stuff-Here&amp;gt;&lt;/FONT&gt;&lt;/STRONG&gt; (as if this whole topic isn't geeky enough to start with)&lt;/P&gt;
&lt;P&gt;Recall that we considered ColorComplementEffect to be a zero-parameter effect.&amp;nbsp; So what's with this "Input" DP?&amp;nbsp; Note that the Effect is invoked via this XAML:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;  &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Grid &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Grid.Effect&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
        &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;eff&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;ColorComplementEffect &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;/&amp;gt;
    &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Grid.Effect&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;

    &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;...&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;
  &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Grid&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN-BOTTOM: 0pt; mso-layout-grid-align: none" class=MsoNormal&gt;The "sampler" that the shader works on is the rasterization of the Grid itself into a bitmap.&amp;nbsp; You can think of the implementation as creating a VisualBrush of the Grid, then providing that Brush as the value for the Input DP.&amp;nbsp; It doesn't quite work like that, and we expose a new type of Brush called ImplicitInput to represent this usage.&amp;nbsp; ImplicitInput is the default value for DPs that defined using "RegisterPixelShaderSamplerProperty", meaning that they automatically receive the "brush" of the element that they're applied to as their shader sampler (register 0 in this case, since that's what we specified).&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN-BOTTOM: 0pt; mso-layout-grid-align: none" class=MsoNormal&gt;We'll see in later posts why exposing these as Brushes, and having the ability to control whether ImplicitInput is used is important.&amp;nbsp; Hint: it has to do with multi-input effects.&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN-BOTTOM: 0pt; mso-layout-grid-align: none" class=MsoNormal&gt;&lt;STRONG&gt;&lt;FONT color=#ff0000&gt;&amp;lt;/Geek-Out-Alert--Somewhat-Esoteric-Stuff-Here&amp;gt;&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;OK, that's it for this post...&amp;nbsp; in the next one we'll get into somewhat more complicated Effect definition.&amp;nbsp; In particular, parameterized effects.&lt;/P&gt;
&lt;H3&gt;Appendix: Global.MakePackUri&lt;/H3&gt;
&lt;P&gt;This is the MakePackUri helper I referenced above.&amp;nbsp; It's nice in that it's not verbose (like the pack:// URI itself), and, more importantly, it doesn't hardwire in a module name.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;internal static class &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Global
&lt;/SPAN&gt;{
    &lt;SPAN style="COLOR: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;Helper method for generating a "pack://" URI for a given relative file based on the
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;/// &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;assembly that this class is in.
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;public static &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Uri &lt;/SPAN&gt;MakePackUri(&lt;SPAN style="COLOR: blue"&gt;string &lt;/SPAN&gt;relativeFile)
    {
        &lt;SPAN style="COLOR: blue"&gt;string &lt;/SPAN&gt;uriString = &lt;SPAN style="COLOR: #a31515"&gt;"pack://application:,,,/" &lt;/SPAN&gt;+ AssemblyShortName + &lt;SPAN style="COLOR: #a31515"&gt;";component/" &lt;/SPAN&gt;+ relativeFile;
        &lt;SPAN style="COLOR: blue"&gt;return new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Uri&lt;/SPAN&gt;(uriString);
    }

    &lt;SPAN style="COLOR: blue"&gt;private static string &lt;/SPAN&gt;AssemblyShortName
    {
        &lt;SPAN style="COLOR: blue"&gt;get
        &lt;/SPAN&gt;{
            &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(_assemblyShortName == &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;)
            {
                &lt;SPAN style="COLOR: #2b91af"&gt;Assembly &lt;/SPAN&gt;a = &lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #2b91af"&gt;Global&lt;/SPAN&gt;).Assembly;

                &lt;SPAN style="COLOR: green"&gt;// Pull out the short name.
                &lt;/SPAN&gt;_assemblyShortName = a.ToString().Split(&lt;SPAN style="COLOR: #a31515"&gt;','&lt;/SPAN&gt;)[0];
            }

            &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;_assemblyShortName;
        }
    }

    &lt;SPAN style="COLOR: blue"&gt;private static string &lt;/SPAN&gt;_assemblyShortName;
}&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8491894" width="1" height="1"&gt;</content><author><name>Greg Schechter</name><uri>http://blogs.msdn.com/Greg-Schechter/ProfileUrlRedirect.ashx</uri></author><category term="WPF" scheme="http://blogs.msdn.com/b/greg_schechter/archive/tags/WPF/" /><category term="Effects" scheme="http://blogs.msdn.com/b/greg_schechter/archive/tags/Effects/" /></entry></feed>