<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Cory Plotts' Blog &#187; Silverlight</title>
	<atom:link href="http://www.cplotts.com/category/silverlight/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.cplotts.com</link>
	<description>Yet another UX guy, working in WPF/Silverlight.</description>
	<lastBuildDate>Fri, 25 Jun 2010 23:59:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Blend Modes: Now Opacity Aware</title>
		<link>http://www.cplotts.com/2009/11/06/blend-modes-now-opacity-aware/</link>
		<comments>http://www.cplotts.com/2009/11/06/blend-modes-now-opacity-aware/#comments</comments>
		<pubDate>Fri, 06 Nov 2009 23:29:30 +0000</pubDate>
		<dc:creator>cplotts</dc:creator>
				<category><![CDATA[Blend Modes]]></category>
		<category><![CDATA[Pixel Shader Effects]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://www.cplotts.com/?p=392</guid>
		<description><![CDATA[After I wrote my trio of blog posts (1, 2, 3) about blend modes using pixel shader effects, I was toying around with it …   The Problem … and noticed that it didn’t handle an opacity changes on the upper layer (B). In fact, this was brought to my attention by a great blog [...]]]></description>
			<content:encoded><![CDATA[<p>After I wrote my trio of blog posts (<a href="http://www.cplotts.com/2009/06/16/blend-modes-part-i/">1</a>, <a href="http://www.cplotts.com/2009/06/16/blend-modes-part-ii/">2</a>, <a href="http://www.cplotts.com/2009/06/30/blend-modes-part-iii/">3</a>) about blend modes using pixel shader effects, I was toying around with it …</p>
<p> </p>
<h2>The Problem</h2>
<p>… and noticed that it didn’t handle an opacity changes on the upper layer (B).</p>
<p>In fact, this was brought to my attention by a great blog <a href="http://www.myinkblog.com/2009/07/14/an-explanation-of-photoshop-blend-modes/">post</a> by Angie Bowen. In it she explains how the blend modes work and, she says:</p>
<blockquote><p>Remember that to get better results you can also adjust the opacity of the upper layer.</p></blockquote>
<p>Trying it out, revealed that some of the blend modes were okay, but most were not. Most of the blend modes would simply result in a black square if you pulled all the opacity out of the upper layer (B). This was obviously wrong, for if you pull all the opacity out of the upper layer (B), you should get the lower layer (A).</p>
<p>Argh!</p>
<p> </p>
<h2>The Solution</h2>
<p>So, I dove back in on the blend mode math, trying to figure out what I needed to do to make these blend modes … opacity aware. <em>That’s got a nice ring to it, doesn’t it!?</em></p>
<p>I started at the top of the list and got the NormalEffect working:</p>
<pre class="brush: cpp;">float4 main(float2 uv : TEXCOORD) : COLOR
{
    float4 inputColor;
    inputColor = tex2D(input, uv);

    float4 blendColor;
    blendColor = tex2D(blend, uv);

    inputColor.rgb = (1 - blendColor.a) * inputColor.rgb + blendColor.rgb;

    return inputColor;
}</pre>
<p>Ok, the above math made sense. When the opacity of the upper layer (blendColor.a) was 1 (opaque), the result was just blendColor. Otherwise when the opacity of the upper layer was 0 (transparent), the result was inputColor.</p>
<p>So, I then started to tackle the darken blend modes (Darken, Multiply, …) and quickly ran into problems. It was at that point, that I ran into this <a href="http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/2940eec8-6689-4ed7-b276-38e637640dd6">post</a> in the WPF Forum. My blend modes were rendering full black (not white), but it provided a crucial piece of knowledge.</p>
<p><strong>Namely, WPF uses pre-multiplied alpha everywhere for performance reasons.</strong></p>
<p>What does that mean? Well, it means that the RGB values for inputColor are already multiplied by the alpha value for inputColor and that the RGB values for blendColor are already multiplied by the alpha value for blendColor.</p>
<p>Ah! Do you see it? This explains why the blend modes were going to a black square when pulling the opacity out. Take the Multiply blend mode. In the above HLSL, it would be:</p>
<pre class="brush: cpp;">// R = Base * Blend
resultColor.rgb = inputColor.rgb * blendColor.rgb</pre>
<p>So, if the alphas were pre-multiplied in and you were pulling opacity out of the blend (upper) layer … then blendColor.rgb would go to zero … which would cause resultColor to go to zero … which would cause the gradient square to go to black!</p>
<p>Thinking about this … brought about the general solution for making these blend modes opacity aware. I needed to simply:</p>
<ol>
<li>Un-pre-multiply the blend layer alpha value out.</li>
<li>Apply the blend mode math.</li>
<li>Then re-multiply the blend layer alpha value in again.</li>
</ol>
<ol>Here is the HLSL for the opacity aware Multiply blend mode:</ol>
<ol>
<pre class="brush: cpp;">float4 main(float2 uv : TEXCOORD) : COLOR
{
    float4 inputColor;
    inputColor = tex2D(input, uv);

    float4 blendColor;
    blendColor = tex2D(blend, uv);

    float4 resultColor;
    resultColor.a = inputColor.a;
    // un-premultiply the blendColor alpha out from blendColor
    blendColor.rgb = clamp(blendColor.rgb / blendColor.a, 0, 1);

    // apply the blend mode math
    // R = Base * Blend
    resultColor.rgb = inputColor.rgb * blendColor.rgb;

    // re-multiply the blendColor alpha in to blendColor
    // weight inputColor according to blendColor.a
    resultColor.rgb =
        (1 - blendColor.a) * inputColor.rgb +
        resultColor.rgb * blendColor.a;

    return resultColor;
}</pre>
<p>A few comments about the above code. Notice that I am clamp(ing) when I un-premultiply (i.e. divide) the alpha out. This assures that the RGB values will be between 0 and 1 (where 0 is black and 1 is white … HLSL operates in ScRGB color space). This is necessary since dividing by values close to 0 (blendColor.a) can yield large numbers or even positive infinity … which throws off the math.</ol>
<p>Secondly, when I re-multiply the blend layer alpha value back in … I need to also properly weight the inputColor … just like I did in the NormalEffect above.</p>
<p>Finally, notice that I really don’t have worry about the opacity on the lower layer (A). I just pass its value off to the result by setting resultColor.a equal to inputColor.a.</p>
<p>Applying this general formula worked in all cases!</p>
<p> </p>
<h2>The Gradient Contour Test Harness</h2>
<p>In order to verify that I was doing math correctly, and to see the effect of pulling the opacity out of the blend modes … I have built a new gradient test harness. I have called it the gradient contour test harness since it not only shows the A + B = R gradient squares but it also shows the R gradient square with contours … just like Paul Dunn’s <a href="http://dunnbypaul.net/blends/">post</a> does when you mouse over the R squares.</p>
<p>It is extremely interesting (to me at least) watching the contours as you pull out the opacities.</p>
<p>For example, Here are three gradient contour squares for the Pin Light blend mode at opacity values of 1.0, 0.5, and 0.0:</p>
<div>
<table border="1" cellspacing="0" cellpadding="2" width="595" align="center">
<tbody>
<tr>
<td width="249" valign="top">
<p align="center">Gradient Squares</p>
</td>
<td width="251" valign="top">
<p align="center">Gradient Contour Squares</p>
</td>
<td width="93" valign="top">
<p align="center">Opacity</p>
</td>
</tr>
<tr>
<td width="249" valign="top"><a href="http://www.cplotts.com/wp-content/uploads/2009/11/PinLight1.00nc.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="PinLight1.00nc" src="http://www.cplotts.com/wp-content/uploads/2009/11/PinLight1.00nc_thumb.png" border="0" alt="PinLight1.00nc" width="204" height="204" /></a> <a href="http://www.cplotts.com/wp-content/uploads/2009/11/PinLight1.00.png"></a></td>
<td width="251" valign="top"><a href="http://www.cplotts.com/wp-content/uploads/2009/11/PinLight1.00.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="PinLight1.00" src="http://www.cplotts.com/wp-content/uploads/2009/11/PinLight1.00_thumb.png" border="0" alt="PinLight1.00" width="204" height="204" /></a><a href="http://www.cplotts.com/wp-content/uploads/2009/11/PinLight0.50.png"></a></td>
<td width="93" valign="top">
<p align="center">1.0</p>
</td>
</tr>
<tr>
<td width="249" valign="top"><a href="http://www.cplotts.com/wp-content/uploads/2009/11/PinLight0.50nc.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="PinLight0.50nc" src="http://www.cplotts.com/wp-content/uploads/2009/11/PinLight0.50nc_thumb.png" border="0" alt="PinLight0.50nc" width="204" height="204" /></a> <a href="http://www.cplotts.com/wp-content/uploads/2009/11/PinLight0.50.png"></a></td>
<td width="251" valign="top"><a href="http://www.cplotts.com/wp-content/uploads/2009/11/PinLight0.50.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="PinLight0.50" src="http://www.cplotts.com/wp-content/uploads/2009/11/PinLight0.50_thumb.png" border="0" alt="PinLight0.50" width="204" height="204" /></a></td>
<td width="93" valign="top">
<p align="center">0.5</p>
</td>
</tr>
<tr>
<td width="249" valign="top"><a href="http://www.cplotts.com/wp-content/uploads/2009/11/PinLight0.00nc.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="PinLight0.00nc" src="http://www.cplotts.com/wp-content/uploads/2009/11/PinLight0.00nc_thumb.png" border="0" alt="PinLight0.00nc" width="204" height="204" /></a> <a href="http://www.cplotts.com/wp-content/uploads/2009/11/PinLight0.00.png"></a></td>
<td width="251" valign="top"><a href="http://www.cplotts.com/wp-content/uploads/2009/11/PinLight0.00.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="PinLight0.00" src="http://www.cplotts.com/wp-content/uploads/2009/11/PinLight0.00_thumb.png" border="0" alt="PinLight0.00" width="203" height="204" /></a></td>
<td width="93" valign="top">
<p align="center">0.0</p>
</td>
</tr>
</tbody>
</table>
</div>
<p align="center"><a href="http://www.cplotts.com/wp-content/uploads/2009/11/PinLight1.00.png"></a></p>
<p align="left">I have also included a button labeled ‘Swap’ which swaps the A and B layers … since not all blend mode effects are commutative.</p>
<p align="left">The gradient contours were made possible via Dwayne Need’s <a href="http://www.codeplex.com/MicrosoftDwayneNeed">library</a>. Check out the code (the class Grayscale4Bitmap) and see this <a href="http://blogs.msdn.com/dwayneneed/archive/2008/06/20/implementing-a-custom-bitmapsource.aspx">post</a> for more info.</p>
<h2>The Image Test Harness</h2>
<p>I’ve also put opacity sliders in the image test harnesses. Let’s take a look at the Pin Light effect at opacity values of 1.0, 0.5, and 0.3.</p>
<table border="1" cellspacing="0" cellpadding="2" width="595">
<tbody>
<tr>
<td width="297" valign="top">
<p align="center">Images</p>
</td>
<td width="297" valign="top">Opacity</td>
</tr>
<tr>
<td width="297" valign="top"><a href="http://www.cplotts.com/wp-content/uploads/2009/11/PinLightImage1.0.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="PinLightImage1.0" src="http://www.cplotts.com/wp-content/uploads/2009/11/PinLightImage1.0_thumb.png" border="0" alt="PinLightImage1.0" width="329" height="248" /></a></td>
<td width="297" valign="top">1.0</td>
</tr>
<tr>
<td width="297" valign="top"><a href="http://www.cplotts.com/wp-content/uploads/2009/11/PinLightImage0.75.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="PinLightImage0.75" src="http://www.cplotts.com/wp-content/uploads/2009/11/PinLightImage0.75_thumb.png" border="0" alt="PinLightImage0.75" width="329" height="248" /></a></td>
<td width="297" valign="top">0.50</td>
</tr>
<tr>
<td width="297" valign="top"><a href="http://www.cplotts.com/wp-content/uploads/2009/11/image.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" src="http://www.cplotts.com/wp-content/uploads/2009/11/image_thumb.png" border="0" alt="image" width="329" height="248" /></a></td>
<td width="297" valign="top">0.3</td>
</tr>
</tbody>
</table>
<p>As you can see … pulling out the opacity … lessens the effect that the upper layer/texture has on the lower layer … and proves the truth of what <a href="http://www.myinkblog.com/">Angie Bowen</a> was saying earlier about using the opacity of the upper layer to achieve better results.</p>
<p> </p>
<h2>The Binaries and the Source Code (aka The Goods)</h2>
<p>So, as I’m fond of saying … without further adieu … <a href="http://www.cplotts.com/wp-content/uploads/2009/11/WPFSLBlendModeFx.zip">here</a> is source code for the Blend Mode library and <a href="http://www.cplotts.com/wp-content/uploads/2009/11/BlendModeLibraryBinaries.zip">here</a> are the library binaries … now opacity aware!</p>
<p>I also have updated the Silverlight <a href="http://www.cplotts.com/BlendModeEffectTestHarness/Default.html">test harness</a> (as always you will need the Silverlight 3.0 runtime).</p>
<p><strong>p.s.</strong></p>
<p>The gradient contour test harness is WPF only &#8230; you won&#8217;t find that on the Silverlight side. Maybe someday I&#8217;ll get my Silverlight test harnesses up to parity with what&#8217;s in the WPF test harnesses &#8230; but I can&#8217;t see when. Any one want to do it for me? Bueller? Bueller?</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save">Share/Save</a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.cplotts.com/2009/11/06/blend-modes-now-opacity-aware/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WPF &amp; Silverlight Charting: A Logarithmic Axis</title>
		<link>http://www.cplotts.com/2009/10/09/wpf-silverlight-charting-a-logarithmic-axis/</link>
		<comments>http://www.cplotts.com/2009/10/09/wpf-silverlight-charting-a-logarithmic-axis/#comments</comments>
		<pubDate>Sat, 10 Oct 2009 00:02:58 +0000</pubDate>
		<dc:creator>cplotts</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[Charting]]></category>

		<guid isPermaLink="false">http://www.cplotts.com/?p=329</guid>
		<description><![CDATA[I love controls. Even more … I love graph controls. In fact, graph controls have been one of the main things I have worked on during my tenure at my current place of employment. A small aside: I think it is what I was meant to do (i.e. work on graph controls). For, my name [...]]]></description>
			<content:encoded><![CDATA[<p>I love controls. Even more … I love graph controls. In fact, graph controls have been one of the main things I have worked on during my tenure at my current place of employment.</p>
<p><em>A small aside: I think it is what I was meant to do (i.e. work on graph controls). For, my name is … Cory <strong>Plotts. </strong>Plotts, you know, as in plots. Ok, never mind, that was lame. </em> <img src='http://www.cplotts.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>So, it was quite natural, and actually part of my job, to take a look at what Microsoft is offering in the WPF and Silverlight toolkits. I have to hand it to <a href="http://blogs.msdn.com/delay/default.aspx">David Anson</a> and the other fellows at Microsoft. They have taken a very nice approach.</p>
<p>First, almost everything is a <span style="font-family: courier new; font-size: small;">System.Windows.Controls.Control</span> that you can restyle and re-template to your heart’s content. So, that makes it very designable.</p>
<p><strong>Second</strong>, I love the data binding model. They have decided to follow an <span style="font-family: courier new; font-size: small;">ItemsControl</span> like approach where you have an <span style="font-family: courier new; font-size: small;">ItemsSource</span> property that you just plunk your data into. Very nice. It literally takes you seconds to get something up and running.</p>
<p><strong>Third</strong>, they are developing it … with Blend in mind. That is, they are trying to provide a positive Blend experience and have gone to pains to make it so. So, not only is it designable … but designers can actually use Blend to do their designing … instead of hacking through xaml in a code editor. Woot! Woot!</p>
<p>Now, this post is not going to be an introduction on how to start using the charting component. Many others have done that already. If that is what you are looking for … I would suggest that you go to this blog <a href="http://blogs.msdn.com/delay/archive/2009/07/19/my-new-home-page-enhanced-updated-collection-of-great-silverlight-wpf-data-visualization-resources.aspx">post</a> by David Anson where he lists out lots and lots of links to other blog posts and articles. In fact, he is so nice … that he has even separated them out by difficulty level.</p>
<p>No, in this blog post, I am going to show you the <strong>fourth thing</strong> I love about this charting component: how extensible it is! And, I am going to do that by showing how I created a logarithmic axis by simply deriving from <span style="font-family: courier new; font-size: small;">NumericAxis</span>.</p>
<p>So, here’s the code (sorry for just dumping it all in one place … but it gives you a nice place to copy out the <em>entire </em>implementation at once):</p>
<pre class="brush: csharp; highlight: [20, 37, 67, 104, 114, 125]">using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Shapes;

namespace System.Windows.Controls.DataVisualization.Charting
{
    /// &lt;summary&gt;
    /// An axis that displays numeric values along a logarithmic range.
    /// &lt;/summary&gt;
    [StyleTypedProperty(Property = "GridLineStyle", StyleTargetType = typeof(Line))]
    [StyleTypedProperty(Property = "MajorTickMarkStyle", StyleTargetType = typeof(Line))]
    [StyleTypedProperty(Property = "MinorTickMarkStyle", StyleTargetType = typeof(Line))]
    [StyleTypedProperty(Property = "AxisLabelStyle", StyleTargetType = typeof(NumericAxisLabel))]
    [StyleTypedProperty(Property = "TitleStyle", StyleTargetType = typeof(Title))]
    [TemplatePart(Name = AxisGridName, Type = typeof(Grid))]
    [TemplatePart(Name = AxisTitleName, Type = typeof(Title))]
    public class LogarithmicAxis : NumericAxis
    {
        /// &lt;summary&gt;
        /// Instantiates a new instance of the LogarithmicAxis
        /// &lt;/summary&gt;
        public LogarithmicAxis()
        {
            ActualRange = new Range&lt;IComparable&gt;(1.0, 2.0);
        }

        /// &lt;summary&gt;
        /// Returns the plot area coordinate of a value.
        /// &lt;/summary&gt;
        /// &lt;param name="value"&gt;The value to plot.&lt;/param&gt;
        /// &lt;param name="range"&gt;The range of values.&lt;/param&gt;
        /// &lt;param name="length"&gt;The length of the axis.&lt;/param&gt;
        /// &lt;returns&gt;The plot area coordinate of the value.&lt;/returns&gt;
        protected override UnitValue? GetPlotAreaCoordinate(object value, Range&lt;IComparable&gt; range, double length)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            if (range.HasData)
            {
                double doubleValue = ValueHelper.ToDouble(value);
                Range&lt;double&gt; actualDoubleRange = range.ToDoubleRange();

                return
                    new UnitValue
                    (
                        length /
                        Math.Log10(actualDoubleRange.Maximum / actualDoubleRange.Minimum) *
                        Math.Log10(doubleValue / actualDoubleRange.Minimum),
                        Unit.Pixels
                    );
            }

            return new UnitValue?();
        }

        /// &lt;summary&gt;
        /// Returns the value range given a plot area coordinate.
        /// &lt;/summary&gt;
        /// &lt;param name="value"&gt;The plot area position.&lt;/param&gt;
        /// &lt;returns&gt;The value at that plot area coordinate.&lt;/returns&gt;
        protected override IComparable GetValueAtPosition(UnitValue value)
        {
            if (ActualRange.HasData &amp;&amp; ActualLength != 0.0)
            {
                if (value.Unit == Unit.Pixels)
                {
                    double coordinate = value.Value;
                    Range&lt;double&gt; actualDoubleRange = ActualRange.ToDoubleRange();

                    double output =
                        Math.Pow
                        (
                            10,
                            coordinate *
                            Math.Log10(actualDoubleRange.Maximum / actualDoubleRange.Minimum) /
                            ActualLength
                        )
                        *
                        actualDoubleRange.Minimum;

                    return output;
                }
                else
                {
                    throw new NotImplementedException();
                }
            }

            return null;
        }

        /// &lt;summary&gt;
        /// Returns a sequence of values to create major tick marks for.
        /// &lt;/summary&gt;
        /// &lt;param name="availableSize"&gt;The available size.&lt;/param&gt;
        /// &lt;returns&gt;A sequence of values to create major tick marks for.
        /// &lt;/returns&gt;
        protected override IEnumerable&lt;IComparable&gt; GetMajorTickMarkValues(Size availableSize)
        {
            return GetMajorValues(availableSize).Cast&lt;IComparable&gt;();
        }

        /// &lt;summary&gt;
        /// Returns a sequence of values to plot on the axis.
        /// &lt;/summary&gt;
        /// &lt;param name="availableSize"&gt;The available size.&lt;/param&gt;
        /// &lt;returns&gt;A sequence of values to plot on the axis.&lt;/returns&gt;
        protected override IEnumerable&lt;IComparable&gt; GetLabelValues(Size availableSize)
        {
            return GetMajorValues(availableSize).Cast&lt;IComparable&gt;();
        }

        /// &lt;summary&gt;
        /// Returns a sequence of major axis values.
        /// &lt;/summary&gt;
        /// &lt;param name="availableSize"&gt;The available size.&lt;/param&gt;
        /// &lt;returns&gt;A sequence of major axis values.
        /// &lt;/returns&gt;
        private IEnumerable&lt;double&gt; GetMajorValues(Size availableSize)
        {
            if (!ActualRange.HasData || ValueHelper.Compare(ActualRange.Minimum, ActualRange.Maximum) == 0 || GetLength(availableSize) == 0.0)
            {
                yield break;
            }

            yield return 125;
            yield return 250;
            yield return 500;
            yield return 1000;
            yield return 2000;
            yield return 4000;
            yield return 8000;
        }
    }
}</pre>
<p>To explain the above code a little bit, I would first direct your attention to two methods. The first is called <strong><span style="font-family: courier new; font-size: small;">GetPlotAreaCoordinate</span></strong>. This method is the method responsible for converting from world coordinates into device coordinates. That is, it converts all the data point values in your Series into pixel coordinates … so that your data point is placed where you expect it should be.</p>
<p>The second method is called <strong><span style="font-family: courier new; font-size: small;">GetValueAtPosition</span></strong>. This method does the exact opposite as <span style="font-family: courier new; font-size: small;">GetPlotAreaCoordinate</span>. It converts from device coordinates into world coordinates. In other words, it takes the mouse position (for example) and it tells you where your mouse is at on the respective axis.</p>
<p>So, the above two methods contain the math behind the axis … and if you look closely, you’ll see the <span style="font-family: courier new; font-size: small;">Math.Log10</span> function getting called. Yep. That’s right. This is a logarithmic axis.</p>
<p>After those two methods, you will see <strong><span style="font-family: courier new; font-size: small;">GetMajorTickValues</span></strong> and <strong><span style="font-family: courier new; font-size: small;">GetLabelValues</span></strong>. They both delegate to a third method called <span style="font-family: courier new; font-size: small;">GetMajorValues</span>. <span style="font-family: courier new; font-size: small;">GetMajorTickValues</span> returns the values at which we want major tick marks and <span style="font-family: courier new; font-size: small;">GetLabelValues</span> returns the values at which we want grid line labels. Pretty straightforward.</p>
<p>Now, a word about my implementation of <span style="font-family: courier new; font-size: small;">GetMajorValues</span>. In it, I have chosen to hardcode very specific values for this axis’ grid lines (i.e. 125, 250, 500, 1000, 2000, 4000, 8000). I did that because I was lazy. For inside of <span style="font-family: courier new; font-size: small;">LinearAxis</span>, there is an <span style="font-family: courier new; font-size: small;">Interval</span> property which you can use to generate the grid lines in a dynamic fashion … and I didn’t feel like figuring out how to make the <span style="font-family: courier new; font-size: small;">Interval</span> property work for the logarithmic axis. (If anyone out there does take the time to do so … please share!)</p>
<p>So, more than likely, you will be wanting to replace those specific values with some of your own … or will be wanting to generate the major values in a much more dynamic way.</p>
<p>Ok, now let me show you how you would use this axis. Check out this xaml (this is just a snippet … I am leaving out all the styling xaml and more):</p>
<pre class="brush: xml; highlight: [11, 12, 13, 14, 15, 16, 17]">&lt;charting:Chart
    x:Name="chart"
    Width="480"
    Height="480"
    Margin="10"
    Title="Response"
    BorderBrush="{x:Null}"
    Style="{StaticResource chartStyle}"
&gt;
    &lt;charting:Chart.Axes&gt;
        &lt;charting:LogarithmicAxis
            Orientation="X"
            ShowGridLines="True"
            Title="Frequency (Hz)"
            Minimum="100"
            Maximum="10000"
        /&gt;
        &lt;charting:LinearAxis
            Orientation="Y"
            ShowGridLines="True"
            Title="Response (dB SPL)"
            Minimum="20"
            Maximum="120"
            Interval="10"
        /&gt;
    &lt;/charting:Chart.Axes&gt;
    &lt;charting:LineSeries
        ItemsSource="{StaticResource responseCurve}"
        IndependentValueBinding="{Binding Frequency}"
        DependentValueBinding="{Binding Response}"
        DataPointStyle="{StaticResource lineDataPointStyle}"
        AnimationSequence="Simultaneous"
        TransitionDuration="0:0:0"
        IsSelectionEnabled="True"
    /&gt;
&lt;/charting:Chart&gt;</pre>
<p>In the above, you can see my new <strong>and proud</strong> <span style="font-family: courier new; font-size: small;">LogarithmicAxis</span> with a Minimum value of 100 and a Maximum value of 10000. Here is a snapshot of the chart that the above xaml creates:</p>
<p><a href="http://www.cplotts.com/wp-content/uploads/2009/10/image.png"><img style="display: inline; border-width: 0px;" title="image" src="http://www.cplotts.com/wp-content/uploads/2009/10/image_thumb.png" border="0" alt="image" width="504" height="504" /></a></p>
<p>Woot! Doesn’t it look sweet!</p>
<p>Now, go out and create some logarithmic charts!</p>
<p><strong>p.s.</strong></p>
<p>I have had to make these changes in a <em>local edit</em> of the toolkits. However, as David Anson points out in this <a href="http://blogs.msdn.com/delay/archive/2009/09/13/a-preview-of-upcoming-charting-changes-silverlight-wpf-data-visualization-development-release-1.aspx">post</a> … they are unsealing everything! So, in a little while … you will no longer need to do this. You will be free to simply derive a new axis at your leisure. <strong>In my mind, that is another point for extensibility!</strong></p>
<p><strong>p.s.s.</strong></p>
<p>Here is the <a href="http://www.cplotts.com/wp-content/uploads/2009/10/WPFSLDataVisualization.zip">source code</a> for this article &#8230; note that it contains <a href="http://blogs.msdn.com/delay/archive/2009/09/13/a-preview-of-upcoming-charting-changes-silverlight-wpf-data-visualization-development-release-1.aspx">David Anson&#8217;s development release version 1</a> &#8230; and it contains his DataVisualizationDemos applications. Finally, and most importantly for this article, it contains the sample code for the above &#8230; under the title <strong>Visibility</strong> (I was working on some DataPoint visibility functionality at the time I drafted up that test harness).</p>
<p><strong>p.s.s.s.</strong></p>
<p>David Anson and the fellows at Microsoft have finally released the version of the Silverlight Toolkit that unseals everything. Check out this blog <a href="http://blogs.msdn.com/delay/archive/2009/10/19/silverlight-and-wpf-data-visualization-classes-unsealed-silverlight-toolkit-october-2009-release-now-available.aspx">post</a> for more info. When David publishes another development release, I’ll update the source code for this article so that the above is not a local edit.</p>
<p><strong>p.s.s.s.s.</strong></p>
<p>I have finally gotten around to getting the source code together where the above logarithmic axis is just an extension of toolkit … versus the local edit as before. So, here is that <a href="http://www.cplotts.com/wp-content/uploads/2010/01/DataVisualizationDemos.zip">source code</a>. It is actually from David Anson’s <a href="http://blogs.msdn.com/delay/archive/2009/11/30/two-birds-squared-silverlight-wpf-data-visualization-development-release-3-and-a-datavisualizationdemos-update.aspx">development release 3</a> (although I have stripped out the WPF 4 and Silverlight 4 projects). I won’t remove the above <a href="http://www.cplotts.com/wp-content/uploads/2009/10/WPFSLDataVisualization.zip">source code</a> … as some people might want to see both ways of doing it.</p>
<p>One additional comment. In David’s <a href="http://blogs.msdn.com/delay/archive/2009/10/21/two-birds-one-stone-silverlight-wpf-data-visualization-development-release-2-and-datavisualizationdemos-update.aspx">development release 2</a>, there was an internal NumericAxis constructor. So, even though he <a href="http://blogs.msdn.com/delay/archive/2009/10/19/silverlight-and-wpf-data-visualization-classes-unsealed-silverlight-toolkit-october-2009-release-now-available.aspx">unsealed</a> everything, that internal constructor was inhibiting me from inheriting a new numeric axis type via an extension. That meant I had to wait till <a href="http://blogs.msdn.com/delay/archive/2009/11/30/two-birds-squared-silverlight-wpf-data-visualization-development-release-3-and-a-datavisualizationdemos-update.aspx">development release 3</a> in order to provide this code. (I also had to find some time too. <img src='http://www.cplotts.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> )</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save">Share/Save</a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.cplotts.com/2009/10/09/wpf-silverlight-charting-a-logarithmic-axis/feed/</wfw:commentRss>
		<slash:comments>42</slash:comments>
		</item>
		<item>
		<title>Silverlight 3 Launches and Blend 3 RC is Released</title>
		<link>http://www.cplotts.com/2009/07/10/silverlight-3-launches-and-blend-3-rc-is-released/</link>
		<comments>http://www.cplotts.com/2009/07/10/silverlight-3-launches-and-blend-3-rc-is-released/#comments</comments>
		<pubDate>Fri, 10 Jul 2009 17:06:16 +0000</pubDate>
		<dc:creator>cplotts</dc:creator>
				<category><![CDATA[Silverlight]]></category>

		<guid isPermaLink="false">http://www.cplotts.com/2009/07/10/silverlight-3-launches-and-blend-3-rc-is-released/</guid>
		<description><![CDATA[Today is the launch of Silverlight 3! Also being released is a release candidate of Expression Blend 3! Here is the official launch site and here is a new Microsoft site on Silverlight. The silverlight.net site has been updated as well. One of my favorite new features of Silverlight 3 is, of course, Pixel Shader [...]]]></description>
			<content:encoded><![CDATA[<p>Today is the launch of Silverlight 3! Also being released is a release candidate of Expression Blend 3!</p>
<p><a href="http://www.seethelight.com">Here</a> is the official launch site and <a href="http://www.microsoft.com/silverlight/">here</a> is a new Microsoft site on Silverlight. The <a href="http://silverlight.net/">silverlight.net</a> site has been updated as well.</p>
<p>One of my favorite new features of Silverlight 3 is, of course, Pixel Shader Effects. The Microsoft Silverlight <a href="http://www.microsoft.com/silverlight/">site</a> has a great <a href="http://www.microsoft.com/silverlight/overview/top-features/default.aspx">overview</a> of the main features and one of those sections is on these GPU rendered effects. <a href="http://www.microsoft.com/silverlight/silverlight/demos/PixelShaders/default.html">Here</a> is a link to a Silverlight 3 application that lets you play with them.</p>
<p>In honor of the Silverlight 3 launch, I have updated my <a href="http://www.cplotts.com/BlendModeEffectTestHarness/Default.html">test harness</a> for my blend mode effects library. These effects, of course, are implemented with the new Pixel Shader Effects.</p>
<p>And, let’s not forget Blend! <a href="http://electricbeach.org/?p=217">Here</a> is Christian Schormann’s blog post announcing the Expression Blend 3 RC. In this version of Expression Blend, <a href="http://electricbeach.org/?p=214">Sketch Flow</a> is finally being released to the general public. This is an awesome tool that is geared toward the early, conceptual design phase and enables one to quickly mock up concepts allowing you to explore ideas at a much lower cost. SketchFlow is just the tip of the iceberg of what’s new in Blend 3. I personally just love the usability improvements (for example, the direct selection improvements) … but what about behaviors (<a href="http://blogs.msdn.com/expression/archive/2009/03/23/an-introduction-to-behaviors-triggers-and-actions.aspx">1</a>, <a href="http://blogs.msdn.com/expression/archive/2009/05/19/link-round-up-behaviors-related-posts.aspx">2</a>, <a href="http://blog.kirupa.com/?p=391">3</a>)? Whoa! Can we say powerful?!</p>
<p><a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;FamilyID=9442b0f2-7465-417a-88f3-5e7b5409e9dd">Here</a> is the link to download the Silverlight 3 Tools for Visual Studio 2008 SP1.</p>
<p><a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;FamilyID=92e1db7a-5d36-449b-8c6b-d25f078f3609">Here</a> is the link to download the Expression Blend 3 + SketchFlow RC.</p>
<p><a href="http://silverlight.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=24246">Here</a> is the link to latest version of the Silverlight Toolkit (July 2009) which also released in conjunction with the Silverlight 3 release.</p>
<p>A bunch of blog posts are hitting the internet about these releases and I see that Scott Guthrie’s highly anticipated <a href="http://weblogs.asp.net/scottgu/archive/2009/07/10/silverlight-3-released.aspx">post</a> has finally been published.</p>
<p>Woot! Woot! Go Silverlight 3 and Blend 3!</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save">Share/Save</a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.cplotts.com/2009/07/10/silverlight-3-launches-and-blend-3-rc-is-released/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Blend Modes for Silverlight</title>
		<link>http://www.cplotts.com/2009/06/17/blend-modes-for-silverlight/</link>
		<comments>http://www.cplotts.com/2009/06/17/blend-modes-for-silverlight/#comments</comments>
		<pubDate>Thu, 18 Jun 2009 02:41:48 +0000</pubDate>
		<dc:creator>cplotts</dc:creator>
				<category><![CDATA[Blend Modes]]></category>
		<category><![CDATA[Pixel Shader Effects]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://www.cplotts.com/?p=277</guid>
		<description><![CDATA[Given the great response to my series on Blend Modes &#8230; I decided to quickly convert the library so that it could be compiled for the Silverlight platform. I pretty much copied how the WPF Pixel Shader Effect Library did it. Oh, and I renamed a bunch of things too. So, here it is &#8230; [...]]]></description>
			<content:encoded><![CDATA[<p>Given the great response to my series on Blend Modes &#8230; I decided to quickly convert the library so that it could be compiled for the Silverlight platform. I pretty much copied how the <a href="http://www.codeplex.com/wpffx">WPF Pixel Shader Effect Library</a> did it. Oh, and I renamed a bunch of things too.</p>
<p>So, here it is &#8230; the new and improved <a href="http://www.cplotts.com/wp-content/uploads/2009/06/wpfslblendmodefx.zip">blend mode effects library</a> &#8230; now with a little Silverlight love!</p>
<p>p.s. And here are the WPF <a href="http://www.cplotts.com/wp-content/uploads/2009/06/wpfblendmodefxbinaries.zip">binaries</a> and here are the Silverlight <a href="http://www.cplotts.com/wp-content/uploads/2009/06/slblendmodefxbinaries.zip">binaries</a>.</p>
<p>p.s.s. I now have a live <a href="http://www.cplotts.com/BlendModeEffectTestHarness/Default.html">Silverlight test harness</a> (you will need the Silverlight 3.0 runtime, 3.0.40624).</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save">Share/Save</a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.cplotts.com/2009/06/17/blend-modes-for-silverlight/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Blend Modes, Part II</title>
		<link>http://www.cplotts.com/2009/06/16/blend-modes-part-ii/</link>
		<comments>http://www.cplotts.com/2009/06/16/blend-modes-part-ii/#comments</comments>
		<pubDate>Wed, 17 Jun 2009 04:25:11 +0000</pubDate>
		<dc:creator>cplotts</dc:creator>
				<category><![CDATA[Blend Modes]]></category>
		<category><![CDATA[Pixel Shader Effects]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://www.cplotts.com/?p=259</guid>
		<description><![CDATA[In Part I of this series, I showed how I was able to eventually figure out how to create the Linear Burn blend mode effect and how to apply this effect to a Border element. In Part II of this series, I am going to start off by showing how I was able to truly [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://www.cplotts.com/2009/06/16/blend-modes-part-i/">Part I</a> of this series, I showed how I was able to eventually figure out how to create the Linear Burn blend mode effect and how to apply this effect to a Border element.</p>
<p>In Part II of this series, I am going to start off by showing how I was able to truly verify that I had written the Linear Burn blend mode effect correctly. And, then, I will share a few of the A + B = R gradient squares for a few of the blend modes that Paul Dunn’s <a href="http://dunnbypaul.net/blends/">post</a> didn’t have. Finally, I will share the full blend mode effect library and the test harnesses that go with it.</p>
<p>So … here we go …</p>
<p>With the Linear Burn blend mode effect that I had created, it bothered me that the gradient that I had blended with the green … was white to gray … and not white to black as Robby’s <a href="http://blog.nerdplusart.com/archives/blend-modes-youre-soaking-in-it">post</a> had shown. Was I doing things correctly? Was the HLSL that I written, right?</p>
<p>A little more searching and I ran into Paul Dunn’s <a href="http://dunnbypaul.net/blends/">post</a> on Photoshop’s blend modes. Ah! Perfect! Exactly what I wanted, and sure enough, I had written Linear Burn correctly. Check out the screen shot below (from my test harness) and compare it to what you see on Paul Dunn’s post. A match. Whew!</p>
<p><a href="http://www.cplotts.com/wp-content/uploads/2009/06/linearburnverified.png"><img class="alignnone size-full wp-image-247" title="Linear Burn: Verified!" src="http://www.cplotts.com/wp-content/uploads/2009/06/linearburnverified.png" alt="linearburnverified.png" width="600" height="450" /></a></p>
<p> </p>
<p>At that point, I started creating and going through every blend mode in his blog post, verifying each along the way. This went along fine until I hit the Vivid Light blend mode. The math that he had just wasn’t working. I tried to figure out what was wrong with it, but eventually I ran into another <a href="http://mouaif.wordpress.com/2009/01/05/photoshop-math-with-glsl-shaders">post</a> that had a different way of expressing the math … it was in HLSL! Plugging in this HLSL worked! And what’s better, he had some additional effects that could be added to the library I was creating. And, so, I finished it off.</p>
<p>Now, as mentioned above, mouaif’s <a href="http://mouaif.wordpress.com/2009/01/05/photoshop-math-with-glsl-shaders/">post</a> had some blend mode effects that Paul Dunn’s <a href="http://dunnbypaul.net/blends/">post</a> didn’t show visually. And, so, I will share those here:</p>
<p><strong><span style="text-decoration: underline;">Glow Effect</span></strong></p>
<p><a href="http://www.cplotts.com/wp-content/uploads/2009/06/gloweffect.png"><img class="alignnone size-full wp-image-249" title="gloweffect.png" src="http://www.cplotts.com/wp-content/uploads/2009/06/gloweffect.png" alt="gloweffect.png" width="600" height="196" /></a></p>
<p> </p>
<p><strong> </strong></p>
<p><strong><span style="text-decoration: underline;">Reflect Effect</span></strong></p>
<p>  <a href="http://www.cplotts.com/wp-content/uploads/2009/06/reflecteffect.png"><img class="alignnone size-full wp-image-251" title="reflecteffect.png" src="http://www.cplotts.com/wp-content/uploads/2009/06/reflecteffect.png" alt="reflecteffect.png" width="600" height="196" /></a></p>
<p><strong> </strong></p>
<p><strong><span style="text-decoration: underline;">Hard Mix Effect</span></strong></p>
<p> <a href="http://www.cplotts.com/wp-content/uploads/2009/06/hardmixeffect.png"><img class="alignnone size-full wp-image-253" title="hardmixeffect.png" src="http://www.cplotts.com/wp-content/uploads/2009/06/hardmixeffect.png" alt="hardmixeffect.png" width="600" height="196" /></a></p>
<p><strong> </strong></p>
<p><strong><span style="text-decoration: underline;">Negation Effect</span></strong></p>
<p> <a href="http://www.cplotts.com/wp-content/uploads/2009/06/negationeffect.png"><img class="alignnone size-full wp-image-255" title="negationeffect.png" src="http://www.cplotts.com/wp-content/uploads/2009/06/negationeffect.png" alt="negationeffect.png" width="600" height="196" /></a></p>
<p><strong> </strong></p>
<p><strong><span style="text-decoration: underline;">Phoenix Effect</span></strong></p>
<p> <a href="http://www.cplotts.com/wp-content/uploads/2009/06/phoenixeffect.png"><img class="alignnone size-full wp-image-257" title="phoenixeffect.png" src="http://www.cplotts.com/wp-content/uploads/2009/06/phoenixeffect.png" alt="phoenixeffect.png" width="600" height="196" /></a></p>
<p> </p>
<p>Finally, Nathan’s <a href="http://www.nathanm.com/photoshop-blending-math/">post</a> had a visual way of verifying things as well (near the bottom) and so I included in my test harness a window that let’s you apply the various blend mode effects to images from Nathan’s page. Here’s a screen shot of that window (with the Phoenix blend mode effect applied … which I think looks cool):</p>
<p><a href="http://www.cplotts.com/wp-content/uploads/2009/06/testharnessimages.png"><img class="alignnone size-full wp-image-261" title="Test Harness Window (Images)" src="http://www.cplotts.com/wp-content/uploads/2009/06/testharnessimages.png" alt="Test Harness Window (Images)" width="600" height="343" /></a></p>
<p> </p>
<p>Without any further adieu, here’s the <a href="http://www.cplotts.com/wp-content/uploads/2009/06/blendmodeeffects.zip">blend mode effects library</a> and the test harness. All the same caveats apply to what you need on your machine to build the sample code (.NET 3.5 SP1, DirectX SDK, and the Shader Effects BuildTask and Templates from the <a href="http://www.codeplex.com/wpf">WPF Futures</a> stuff on CodePlex).</p>
<p>If you don&#8217;t want to build the library and test harness yourself &#8230; here are the <a href="http://www.cplotts.com/wp-content/uploads/2009/06/blendmodeeffectsbinaries.zip">binaries</a>.</p>
<p>Also, I now have a live <a href="http://www.cplotts.com/BlendModeEffectTestHarness/Default.html">Silverlight test harness</a> (you will need the Silverlight 3.0 runtime, 3.0.40624). </p>
<p>Enjoy!</p>
<p>p.s. Thanks to <a href="http://work.j832.com/">Kevin Moore</a> for the Color Picker that I used in this sample code. I believe I created that Color Picker from an article he did at one point. In fact, I think that some variant of this Color Picker ended up in his <a href="http://j832.com/bagotricks/">Bag-o-Tricks</a>.</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save">Share/Save</a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.cplotts.com/2009/06/16/blend-modes-part-ii/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Blend Modes, Part I</title>
		<link>http://www.cplotts.com/2009/06/16/blend-modes-part-i/</link>
		<comments>http://www.cplotts.com/2009/06/16/blend-modes-part-i/#comments</comments>
		<pubDate>Wed, 17 Jun 2009 00:56:44 +0000</pubDate>
		<dc:creator>cplotts</dc:creator>
				<category><![CDATA[Blend Modes]]></category>
		<category><![CDATA[Pixel Shader Effects]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://www.cplotts.com/?p=198</guid>
		<description><![CDATA[A while back (now some time ago), I was inspired by Robby Ingebretsen’s post on blend modes that were made possible with pixel shader effects, a new feature of .NET 3.5 SP1. In his post, he suggested that someone take a weekend and create a library of these effects for the community to use. Well, [...]]]></description>
			<content:encoded><![CDATA[<p>A while back (now some time ago), I was inspired by Robby Ingebretsen’s <a href="http://blog.nerdplusart.com/archives/blend-modes-youre-soaking-in-it">post</a> on <a href="http://en.wikipedia.org/wiki/Blend_modes">blend modes</a> that were made possible with <a href="http://msdn.microsoft.com/en-us/library/system.windows.media.effects.shadereffect.aspx">pixel shader effects</a>, a new feature of .NET 3.5 SP1. In his post, he suggested that someone take a weekend and create a library of these effects for the community to use. Well, a little late, but I have eventually gotten around to this and done so … because I wanted to give a designer I work with some power tools that he is familiar with in applications like Photoshop.</p>
<p>In this trio (<a href="http://www.cplotts.com/2009/06/16/blend-modes-part-i/">1</a>, <a href="http://www.cplotts.com/2009/06/16/blend-modes-part-ii/">2</a>, <a href="http://www.cplotts.com/2009/06/30/blend-modes-part-iii/">3</a>) of blog posts, I will not be covering how to create a shader effect in WPF, Greg Schlecter has a great introductory <a href="http://blogs.msdn.com/greg_schechter/archive/2008/05/12/a-series-on-gpu-based-effects-for-wpf.aspx">series</a> on that already. In particular, it is the <a href="http://blogs.msdn.com/greg_schechter/archive/2008/09/16/introducing-multi-input-shader-effects.aspx">multi-input shader effects</a> that make blend modes possible, so be sure to read all the way through his series.</p>
<p>In order to write this library of blend mode effects, I first needed to find the math behind them. Then, I needed to convert this math into the proper HLSL. And finally, I needed some way to verify that the HLSL that I had written … was actually correct. I will cover these topics in the first two blog (<a href="http://www.cplotts.com/2009/06/16/blend-modes-part-i/">first</a>, <a href="http://www.cplotts.com/2009/06/16/blend-modes-part-ii/">second</a>) posts.</p>
<p>In the <a href="http://www.cplotts.com/2009/06/30/blend-modes-part-iii/">third</a> blog post, I will show how you can use <a href="http://jmorrill.hjtcentral.com/">Jeremiah Morrill’s</a> <a href="http://jmorrill.hjtcentral.com/Home/tabid/428/EntryId/403/Glass-Behavior-for-WPF.aspx">GlassBehavior</a> to blend two shapes with differing geometries.</p>
<p>So … let’s jump in.</p>
<p>I quickly started off with a simple Google search and it led me to Nathan Moinvaziri’s <a href="http://www.nathanm.com/photoshop-blending-math/">post</a> which is all the blend mode math in C. So, I decided to buckle down and see if I could do Linear Burn … which is the subject of Robby’s post. Nathan had the math (for each channel) for Linear Burn as:</p>
<pre class="brush: c#">#define ChannelBlend_Subtract(B, L)
     ((uint8)((B + L &lt; 255) ? 0 : (B + L – 255)))
#define ChannelBlend_LinearBurn(B, L)
     (ChannelBlend_Subtract(B, L))</pre>
<p> </p>
<p>Just plugging in the macro definitions into the .fx file didn’t work and through some trial and error, I discovered that the correct HLSL was:</p>
<pre class="brush: c#;">inputColor.r = inputColor.r + blendColor.r - 1;
inputColor.g = inputColor.g + blendColor.g - 1;
inputColor.b = inputColor.b + blendColor.b - 1;</pre>
<p> </p>
<p>This finally gave me the blending Robby had talked about in his post:</p>
<p><a href="http://www.cplotts.com/wp-content/uploads/2009/06/linearburn.png"><img class="alignnone size-full wp-image-245" title="Linear Burn" src="http://www.cplotts.com/wp-content/uploads/2009/06/linearburn.png" alt="Linear Burn" width="600" height="405" /></a></p>
<p>Following is the xaml for the above rectangle which is using the Linear Burn blend mode effect:</p>
<pre class="brush: xml; highlight: [5, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]">&lt;Border
    Width="300"
    Height="100"
    Margin="0,10"
    Background="#FF6AB400"
&gt;
    &lt;Border.Effect&gt;
        &lt;bme:LinearBurnEffect&gt;
            &lt;bme:LinearBurnEffect.Texture&gt;
                &lt;ImageBrush&gt;
                    &lt;ImageBrush.ImageSource&gt;
                        &lt;DrawingImage&gt;
                            &lt;DrawingImage.Drawing&gt;
                                &lt;GeometryDrawing&gt;
                                    &lt;GeometryDrawing.Geometry&gt;
                                        &lt;RectangleGeometry Rect="0,0,1,1"/&gt;
                                    &lt;/GeometryDrawing.Geometry&gt;
                                    &lt;GeometryDrawing.Brush&gt;
                                        &lt;LinearGradientBrush
                                            StartPoint="0,0"
                                            EndPoint="0,1"
                                        &gt;
                                            &lt;GradientStop
                                                Color="#FFFFFFFF"
                                                Offset="0"
                                            /&gt;
                                            &lt;GradientStop
                                                Color="#FF808080"
                                                Offset="1"
                                            /&gt;
                                        &lt;/LinearGradientBrush&gt;
                                    &lt;/GeometryDrawing.Brush&gt;
                                &lt;/GeometryDrawing&gt;
                            &lt;/DrawingImage.Drawing&gt;
                        &lt;/DrawingImage&gt;
                    &lt;/ImageBrush.ImageSource&gt;
                &lt;/ImageBrush&gt;
            &lt;/bme:LinearBurnEffect.Texture&gt;
        &lt;/bme:LinearBurnEffect&gt;
    &lt;/Border.Effect&gt;
&lt;/Border&gt;</pre>
<p>As you can see above, it is rather easy to apply the blend mode effect. Each blend mode effect takes two shader effect inputs (where input is a shader effect sampler input).</p>
<p>The first input is the element it is set on which is in this case the Border element with the #FF6AB400 background.</p>
<p>The second input is the ImageBrush (it can also be a VisualBrush) that is set on the Texture property. Notice that the alpha channels for the GradientStop(s) are set 100% and not 50% like the Border with opacity overlay (see the attached code, .zip file below). That is, the two layers are being blended by the blend mode effect and not with opacity.</p>
<p>Another thing to mention is that the first input maps to <strong>A</strong> in the picture above and the second input maps to <strong>B</strong> in the picture above. <strong>R</strong> maps to the blend result which is what the user sees. In the next post, I will use this mapping (<strong>A + B = R</strong>) to illustrate what each blend mode effect does.</p>
<p>Here is the <a href="http://www.cplotts.com/wp-content/uploads/2009/06/linearburnblendmodeeffect.zip">code</a> for this post and here are the <a href="http://www.cplotts.com/wp-content/uploads/2009/06/linearburnbinaries.zip">binaries</a>. Also, I now have a live <a href="http://www.cplotts.com/BlendModeEffectTestHarness/Default.html">Silverlight test harness</a> (you will need the Silverlight 3.0 runtime, 3.0.40624).</p>
<p>Enjoy!</p>
<p>(To build the above sample code, you need .NET 3.5 SP1 and you need a version of the DirectX SDK installed on your machine. Besides all that, you must also install the Shader Effects BuildTask and Templates from the <a href="http://www.codeplex.com/wpf">WPF Futures</a> CodePlex site.)</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save">Share/Save</a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.cplotts.com/2009/06/16/blend-modes-part-i/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Code to Work Along With While Watching Jason Dolinger’s M-V-VM Video</title>
		<link>http://www.cplotts.com/2009/06/16/code-to-work-along-with-while-watching-jason-dolingers-m-v-vm-video/</link>
		<comments>http://www.cplotts.com/2009/06/16/code-to-work-along-with-while-watching-jason-dolingers-m-v-vm-video/#comments</comments>
		<pubDate>Tue, 16 Jun 2009 17:35:06 +0000</pubDate>
		<dc:creator>cplotts</dc:creator>
				<category><![CDATA[Patterns]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://www.cplotts.com/?p=202</guid>
		<description><![CDATA[I meant to post this to my blog sometime ago … but I forgot. I was recently reminded about it when a fellow software engineer I work with was looking for good information on M-V-VM. I pointed him to my answer to a StackOverflow question on the matter and then pointed him to Jason’s video … [...]]]></description>
			<content:encoded><![CDATA[<p>I meant to post this to my blog sometime ago … but I forgot. I was recently reminded about it when a fellow software engineer I work with was looking for good information on M-V-VM.</p>
<p>I pointed him to my <a href="http://stackoverflow.com/questions/275098/what-applications-could-i-study-to-understand-datamodel-view-viewmodel/275357#275357">answer</a> to a <a href="http://stackoverflow.com/">StackOverflow</a> question on the matter and then pointed him to Jason’s <a href="http://blog.lab49.com/archives/2650">video</a> … sending him at the same time the code that I captured while working through this great video/screen cast. But, hey, why not share this with the wider community?!</p>
<p>What’s great about this <a href="http://www.cplotts.com/wp-content/uploads/2009/06/mvvmdemo.zip">sample code</a> is that I’ve captured ‘snapshots’ along every step of the way.</p>
<p>Enjoy, and I would appreciate you leaving a comment if you find it useful. It&#8217;s always fun to know that you&#8217;ve helped someone.</p>
<p>p.s. I didn’t start out at ground zero for this code, Robert’s <a href="http://reyntjes.blogspot.com/2008/12/my-version-of-jason-dollingers.html">code</a> helped me get started. So, thanks Robert!</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save">Share/Save</a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.cplotts.com/2009/06/16/code-to-work-along-with-while-watching-jason-dolingers-m-v-vm-video/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Kaxaml: Don&#8217;t Leave Home Without It</title>
		<link>http://www.cplotts.com/2009/02/13/kaxaml-dont-leave-home-without-it/</link>
		<comments>http://www.cplotts.com/2009/02/13/kaxaml-dont-leave-home-without-it/#comments</comments>
		<pubDate>Fri, 13 Feb 2009 22:17:42 +0000</pubDate>
		<dc:creator>cplotts</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Utilities]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://www.cplotts.com/2009/02/13/kaxaml-dont-leave-home-without-it/</guid>
		<description><![CDATA[Ok, I just have to give a shout out to one of the best tools out there for authoring loose xaml. And, if the logo didn’t give it away … it’s Robby Ingebretsen’s Kaxaml tool. It is available here for download … free of charge! It’s been out for quite some time … so the [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.cplotts.com/wp-content/uploads/2009/02/kaxamllogo.png"><img style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" title="KaxamlLogo" src="http://www.cplotts.com/wp-content/uploads/2009/02/kaxamllogo-thumb.png" border="0" alt="KaxamlLogo" width="244" height="244" /></a></p>
<p>Ok, I just have to give a shout out to one of the best tools out there for authoring loose xaml. And, if the logo didn’t give it away … it’s <a href="http://nerdplusart.com/about/">Robby Ingebretsen’s</a> Kaxaml tool. It is available <a href="http://www.kaxaml.com">here</a> for download … free of charge!</p>
<p>It’s been out for quite some time … so the purpose of this blog post is really to just publicly thank him for making such an awesome tool … one, in fact, that I don’t leave home without.</p>
<p>Recently, I have been composing Haikus … just because a tool like this … deserves <a href="http://blog.nerdplusart.com/archives/kaxaml-swag">poetry</a> … and poetry better than mine!</p>
<p>But, in case you haven’t heard about it or haven’t played with it much … here is some quick info. I believe you pronounce it &lt;ka-zam-al&gt; … and I like to think like <a href="http://en.wikipedia.org/wiki/Shazam_(comics_character)">Shazam</a>! Pow! (I have not confirmed this was the intent of its author … it might just be the meanderings of this crazy mind of mine.)</p>
<p>It has a pretty sweet list of features:</p>
<ul>
<li>A snippet library with the ability to insert snippets via shortcut</li>
<li>IntelliSense</li>
<li>A folding editor</li>
<li>An integrated color picker</li>
<li>A xaml scrubber (or pretty printer or formatter or whatever you want to call it)</li>
<li>The ability to zoom in and out on your rendered xaml</li>
<li>The ability to make your xaml larger (use ctrl-wheel)</li>
<li>Handles both WPF and Silverlight</li>
<li>And more!</li>
</ul>
<ul>Bonus: Robby recently recorded several videos that will bring you up to Kaxaml power user status in a matter of minutes. Check <a href="http://blog.nerdplusart.com/archives/become-a-kaxaml-power-user-in-about-7-minutes">them</a> out.</ul>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save">Share/Save</a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.cplotts.com/2009/02/13/kaxaml-dont-leave-home-without-it/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
