<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" media="screen" href="/styles/xslt/rss.xslt"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:c9="http://channel9.msdn.com">
<channel>
	<title>Channel 9 - Entries tagged with WebCam</title>
    <atom:link rel="self" type="application/rss+xml" href="http://channel9.msdn.com/Tags/webcam/RSS"/>
    <itunes:summary></itunes:summary>
    <itunes:author>Microsoft</itunes:author>
    <itunes:subtitle></itunes:subtitle>
    <image>
      <url>http://mschnlnine.vo.llnwd.net/d1/Dev/App_Themes/C9/images/feedimage.png</url>
      <title>Channel 9 - Entries tagged with WebCam</title>
      <link>http://channel9.msdn.com/Tags/webcam</link>
    </image>
    <itunes:image href=""/>
    <itunes:category text="Technology"/>
    <description>Channel 9 keeps you up to date with the latest news and behind the scenes info from Microsoft that developers love to keep up with. From LINQ to SilverLight – Watch videos and hear about all the cool technologies coming and the people behind them.</description>
    <link>http://channel9.msdn.com/Tags/webcam</link>
    <language>en</language>
    <pubDate>Sun, 12 Feb 2012 12:32:03 GMT</pubDate>
    <lastBuildDate>Sun, 12 Feb 2012 12:32:03 GMT</lastBuildDate>
    <generator>Rev9</generator>
    <c9:totalResults>9</c9:totalResults>
    <c9:pageCount>1</c9:pageCount>
    <c9:pageSize>25</c9:pageSize>
  <item>
      <title>SilverShader – Introduction to Silverlight and WPF Pixel Shaders</title>
      <description><![CDATA[
<p>This article explains how to write pixel shaders for the Microsoft Silverlight and WPF platform with HLSL, as well as how to write an extensible Silverlight application for shader demos.

</p>
<h3>Introduction</h3>
<p>Almost 10 years ago, <a href="http://www.microsoft.com/Presspass/press/2000/nov00/directxlaunchpr.mspx">
Microsoft announced DirectX 8.0</a>, including the huge real-time computer graphics milestone, Direct3D 8.0. Direct3D 8.0 introduced programmable
<a href="http://en.wikipedia.org/wiki/Shader_(computer_science)">shaders</a> and gave the developers a chance to create never-before-seen effects and experiences apart from the fixed-function graphics pipeline. With Direct3D 8.0's new shader capabilities, it
 became possible to compute neat custom-rendering effects on mainstream graphics hardware. Today's graphics hardware is capable of running hundreds of shaders in parallel and modern games make heavy use of this technology t to achieve stunning effects.
</p>
<p>A shader is a rather small program, a so-called kernel function, typically executed in parallel for each data element.
<a href="http://en.wikipedia.org/wiki/Pixel_shader">Pixel shaders</a>, for example, are executed for each pixel of a bitmap, and therefore used to implement per-pixel effects.
</p>
<p>This introductory article will explain how to write pixel shaders for Silverlight and WPF, what tools should be used, and how to work with the tools. Furthermore, it will show how to build an extensible Silverlight shader application.</p>
<h3>Demo Application</h3>
<p>The demo application makes it possible to apply different shaders to an image or to the live stream from the webcam. The application not only comes with the two shaders that will be implemented in this article, it also contains three other shaders I've written
 before. The complete source code is licensed under the <a href="http://www.opensource.org/licenses/ms-pl.html">
Ms-PL</a> and can be downloaded from the <a href="http://silvershader.codeplex.com">
CodePlex site</a>.</p>
<p>You need at least the Silverlight 4 runtime installed to run the sample and a webcam is needed in order to exploit the full functionality. The runtime is available for
<a href="http://go.microsoft.com/fwlink/?LinkID=149156">Windows</a> and <a href="http://go.microsoft.com/fwlink/?LinkId=107365">
Mac</a>. </p>
<p><a href="http://dl.dropbox.com/u/2681028/CodeplexData/SilverShader/Sample/SilverShaderTestPage.html">Open the sample</a></p>
<p align="center"><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/5428.clip_5F00_image002_5F00_3589A3B6.jpg"><strong><img title="clip_image002" border="0" alt="clip_image002" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/5444.clip_5F00_image002_5F00_thumb_5F00_5DF85FFD.jpg" width="500" height="526"></strong></a></p>
<p align="center"><strong>Figure 1: Screenshot of the demo application</strong></p>
<h4>How To Use?</h4>
<p>You can start and stop the webcam with the <a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/6014.clip_5F00_image004_5F00_7B8A3AFC.gif">
<img title="clip_image004" border="0" alt="clip_image004" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/5037.clip_5F00_image004_5F00_thumb_5F00_467DABCC.gif" width="21" height="21"></a>
 Button, or you can load an image from disk with the <a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/2311.clip_5F00_image006_5F00_023D4480.gif">
<img title="clip_image006" border="0" alt="clip_image006" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/8662.clip_5F00_image006_5F00_thumb_5F00_3AE7EE8D.gif" width="20" height="20"></a>
 Button. Use the ComboBox to change the pixel shader that is applied to the source. Each shader has its own controls to change the used parameters. The controls should be pretty much self-explaining. Just try them out.
</p>
<p>When you click the <a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/3465.clip_5F00_image007_5F00_4CC4825A.gif">
<img title="clip_image007" border="0" alt="clip_image007" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/4035.clip_5F00_image007_5F00_thumb_5F00_217FEB53.gif" width="20" height="20"></a>
 Button for the first time, you'll need to give permission for the capturing. This application uses the default Silverlight capture device. You can specify default video and audio devices with the Silverlight Configuration. Just press the right mouse button
 over the application, click &quot;Silverlight&quot; in the context menu, and select the &quot;Webcam / Mic&quot; tab to set them.</p>
<h3>Where do start?</h3>
<h4>What do we have in Silverlight and WPF? </h4>
<p>Pixel shaders were introduced with WPF 3.5 SP1, and later with Silverlight 3, as so-called
<a href="http://msdn.microsoft.com/en-us/library/system.windows.media.effects.shadereffect.aspx">
ShaderEffects</a>. <a href="http://msdn.microsoft.com/en-us/library/system.windows.media.effects.shadereffect.aspx">
ShaderEffects</a> can be applied to any control to create both nice visual effects and new user experiences. WPF 3.5 SP1 and Silverlight support the
<a href="http://msdn.microsoft.com/en-us/library/bb219843%28v=VS.85%29.aspx">Shader Model 2</a>, which is limited to a total of 96 instructions (64 arithmetic and 32 texture instructions). Modern DirectX 11 graphics cards already support
<a href="http://msdn.microsoft.com/en-us/library/ff471356(v=VS.85).aspx">Shader Model 5</a>, which doesn't have such limits. Silverlight pixel shaders, however, are executed on the
<a href="http://en.wikipedia.org/wiki/Central_processing_unit">CPU</a> and not on the specialized
<a href="http://en.wikipedia.org/wiki/Graphics_processing_unit">GPU</a>. Since the software rendering pipelines make use of modern CPU capabilities like
<a href="http://en.wikipedia.org/wiki/Streaming_SIMD_Extensions">SSE</a> and multi-core execution, they still
<a href="http://kodierer.blogspot.com/2009/08/silverlight-3-writeablebitmap.html">
run pretty fast and are the right way to implement effects</a> in Silverlight. </p>
<p>WPF renders the shaders slightly different. If the shader is applied to an element which is rendered on the graphics card, the shader will also be executed on the GPU. But if the element is being rendered for printing, certain
<a href="http://msdn.microsoft.com/en-us/library/system.windows.media.tilebrush.aspx">
TileBrushs</a> are used or any other reason <a href="http://msdn.microsoft.com/en-us/library/ms742196.aspx">
prevents hardware acceleration</a>, the element and the shader will be rendered in software. This rendering is done on WPF's render thread and the software shader unit also uses fast SSE instructions like Silverlight's renderer, but does not take advantage
 of multiple CPU cores.</p>
<p>WPF 4 supports <a href="http://msdn.microsoft.com/en-us/library/bb509656(v=VS.85).aspx">
Shader Model 3</a> with a much <a href="http://msdn.microsoft.com/en-us/library/bb219845(v=VS.85).aspx">
higher instruction count limit</a> and these pixel shaders are only executed on the GPU. Due to the more complex computation there's no software rendering fallback. The shader will simply be ignored if it's applied to an element being rendered in software or
 the graphics hardware doesn't support Shader Model 3.</p>
<p>This article targets Silverlight and WPF and therefore stays within the bounds of the
<a href="http://msdn.microsoft.com/en-us/library/bb219843%28v=VS.85%29.aspx">Shader Model 2</a>.</p>
<p></p>
<p></p>
<p></p>
<h4>How to program shaders?</h4>
<p>There are several ways to write and compile shader programs. Nowadays, the most common method used in the
<a href="http://en.wikipedia.org/wiki/Direct3D">Direct3D</a> and Windows world is a language called High Level Shading Language (<a href="http://en.wikipedia.org/wiki/High_Level_Shader_Language">HLSL</a>). The Direct3D shader compiler
<a href="http://msdn.microsoft.com/en-us/library/bb232919(VS.85).aspx">fxc.exe</a> compiles the HLSL code into byte-code, which is then executed by the runtime.
</p>
<p>HLSL is a C-style language with some special data types and intrinsic functions, but without pointers. If you know how to write code in a C-style language like C#, you will quickly learn how to write a shader with HLSL. By the way, if you know HLSL, you
 also know NVIDIA's shading language <a href="http://en.wikipedia.org/wiki/Cg_(programming_language)">
Cg</a>. Cg and HLSL have the same root and are very similar.</p>
<p>HLSL defines scalar and various vector / matrix <a href="http://msdn.microsoft.com/en-us/library/bb509587(v=VS.85).aspx">
data types</a> for integer and floating point operations. The <a href="http://msdn.microsoft.com/en-us/library/ff471376(v=VS.85).aspx">
built-in intrinsic functions</a> support scalar and vector data types. <a href="http://msdn.microsoft.com/en-us/library/bb509600(v=VS.85).aspx">
Flow-control statements</a>—such as if, switch, for, and while—are also possible. Of course, the curly brace is used for code blocks and most of the C
<a href="http://msdn.microsoft.com/en-us/library/bb509631(v=VS.85).aspx">operators</a> are also supported. The compiler uses
<a href="http://msdn.microsoft.com/en-us/library/bb509647(v=VS.85).aspx#PS">semantics</a> to both determine the intended usage of a parameter and provide the right data for it. The
<a href="http://msdn.microsoft.com/en-us/library/dd607359(v=VS.85).aspx">register</a> keyword is typically used to pass a parameter into the shader program. The elements of the vector types can be accessed through various aliases, such as x, y, z, w; r, g,
 b, a; u, v; etc. It's also possible to combine these and write nice and short statements by using swizzling:</p>
<p><b>HLSL <br>
</b></p>
<pre class="csharpcode"><span class="rem">// Create 3D float vector a and b with different syntax</span>
float3 a = float3(1, 2, 3);
float3 b = {5, 6, 7};

<span class="rem">// Calculate cross product of vector a and b using swizzling</span>
float3 crossProduct = a.yzx * b.zxy - a.zxy * b.yzx;</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The <a href="http://msdn.microsoft.com/en-us/library/bb509638(v=VS.85).aspx">MSDN</a> is a great resource for HLSL and provides detailed explanations of the syntax and functions. The following examples will make it clearer and the explanations should help
 to get you started.</p>
<h4>What tools to use?</h4>
<p>Of course, it's possible to write a pixel shader with a simple text editor and compile it with the command line tool
<a href="http://msdn.microsoft.com/en-us/library/bb232919(VS.85).aspx">fxc.exe</a>, but there's a great tool available that makes the process a lot easier. The
<a href="http://shazzam-tool.com/">Shazzam Tool</a> by <a href="http://blog.waltritscher.com">
Walt Ritscher</a> is THE utility for Silverlight and WPF shader development. It comes with an HLSL editor, which includes syntax highlighting, that compiles the shader and applies it right away to a sample input. It also generates controls for each parameter,
 which may be used to change the shader settings on the fly, and it creates the needed C# or VB source code file with a class that is derived from
<a href="http://msdn.microsoft.com/en-us/library/system.windows.media.effects.shadereffect.aspx">
ShaderEffect</a>. </p>
<p>Here's what you need to get started:</p>
<ol>
<li><a href="http://msdn.microsoft.com/en-us/directx/aa937788.aspx">Download the DirectX SDK</a> and install it.
</li><li><a href="http://shazzam-tool.com/publish.htm">Download the Shazzam Tool</a> and install it.
</li><li>After the Shazzam Tool is started, verify that the path to the <i>DirectX FX compiler</i> is set (Figure 2). The fxc.exe is normally located in the DirectX SDK installation folder under Utilities\bin\x86. Also make sure the right
<i>Target framework</i> is selected and a <i>Generated namespace</i> is set. </li><li>To see if everything works, open a <i>Sample Shader</i> with the <i>Shader Loader</i>, select a sample tab page, and try the controls on the
<i>Change Shader Settings</i> page (Figure 3). </li></ol>
<p align="center"><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/5037.clip_5F00_image009_5F00_6C735C22.jpg"><strong><img title="clip_image009" border="0" alt="clip_image009" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/3872.clip_5F00_image009_5F00_thumb_5F00_32F04C2B.jpg" width="271" height="536"></strong></a></p>
<p align="center"><strong>Figure 2: Shazzam Tool Settings</strong></p>
<p align="center"><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/5543.clip_5F00_image011_5F00_796D3C33.jpg"><strong><img title="clip_image011" border="0" alt="clip_image011" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/1323.clip_5F00_image011_5F00_thumb_5F00_1124739A.jpg" width="500" height="429"></strong></a></p>
<p align="center"><strong>Figure 3: Shazzam Tool Overview</strong></p>
<h3>How to write a pixel shader?</h3>
<p>Now that we have the right tools installed and configured, we are ready to write the first pixel shader and the Silverlight application that will use it.</p>
<h4>Example 1: The Tint Shader</h4>
<p>The first pixel shader we're writing is a rather simple tint shader that converts the pixel into gray and tints it with a parameterized color.</p>
<p>In the Shazzam Tool, select <i>File </i>à<i> New Shader File</i>,<i> </i>choose a location for the HLSL FX file, and name it TintShader. Shazzam will automatically create the basic pixel shader code, including a
<b>float</b> parameter SampleI. Hit the F5 key to compile and apply the shader to the selected sample image.</p>
<p><b>HLSL <br>
</b></p>
<pre class="csharpcode">sampler2D input : register(s0);

<span class="rem">/// &lt;summary&gt;Explain the purpose of this variable.&lt;/summary&gt;</span>
<span class="rem">/// &lt;minValue&gt;05/minValue&gt;</span>
<span class="rem">/// &lt;maxValue&gt;10&lt;/maxValue&gt;</span>
<span class="rem">/// &lt;defaultValue&gt;3.5&lt;/defaultValue&gt;</span>
<span class="kwrd">float</span> SampleI : register(C0);

float4 main(float2 uv : TEXCOORD) : COLOR 
{
    float4 Color; 
    Color = tex2D(input, uv.xy);
    <span class="kwrd">return</span> Color; 
}</pre>
<p>The input register is the actual bitmap / texture that holds the pixels and is sampled inside the pixel shader. This pixel shader
<b>main</b> function is the entry point and is executed for each pixel of the input bitmap. The coordinate of the current pixel that is processed is passed as the<b> float2</b> parameter uv. This coordinate is normalized to the range [0, 1]. The color of the
 pixel at the passed uv coordinate is sampled as <b>float4 </b>with the built-in <a href="http://msdn.microsoft.com/en-us/library/bb509677(v=VS.85).aspx">
<b>tex2D</b> intrinsic function</a>. A <b>float4</b> <b>COLOR</b> value is expected as the return value of the pixel shader.</p>
<p align="center"><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/7178.clip_5F00_image013_5F00_0ADF78AA.jpg"><strong></strong></a><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/5100.clip_5F00_image013_5F00_236F15FA.jpg"><img title="clip_image013" border="0" alt="clip_image013" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/7026.clip_5F00_image013_5F00_thumb_5F00_14E2186A.jpg" width="398" height="262"></a></p>
<p align="center"><strong>Figure 4: Output of the initial shader code (original image)</strong></p>
<p>The initial pixel shader code returns the original color for each pixel and we use this as the starter for our gray scale conversion.</p>
<h4>Gray Conversion</h4>
<p><b>HLSL <br>
</b></p>
<pre class="csharpcode">sampler2D input : register(s0);

float4 main(float2 uv : TEXCOORD) : COLOR 
{
   <span class="rem">// Sample the original color at the coordinate</span>
   float4 color = tex2D(input, uv);
    
   <span class="rem">// Convert the color to gray</span>
  <span class="kwrd">float</span> gray = dot(color.rgb, float3(0.2126, 0.7152, 0.0722));
    
   <span class="rem">// Return gray with the original alpha value</span>
   <span class="kwrd">return</span> float4(gray, gray, gray, color.a); 
}</pre>
<p></p>
<p>The original color is sampled and then converted to gray using the <a href="http://msdn.microsoft.com/en-us/library/bb509594(v=VS.85).aspx">
<b>dot</b></a> product of the <b>r</b>ed, <b>g</b>reen, and <b>b</b>lue values with a constant
<b>float3</b> vector. The result actually represents the <a href="http://en.wikipedia.org/wiki/Luminance_(relative)">
luminance</a> of the pixel. The <a href="http://en.wikipedia.org/wiki/Dot_product">
dot product</a> multiplies the elements of the color vector with the elements of constant vector and adds the three products, thus resulting in a scalar
<b>float</b> value. The return value of the pixel shader is a new color made up of the gray value for RGB and the original alpha (transparency) of the sampled pixel.</p>
<p align="center"><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/5826.clip_5F00_image015_5F00_5C19C007.jpg"><strong></strong></a><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/3365.clip_5F00_image015_5F00_709F0F85.jpg"><img title="clip_image015" border="0" alt="clip_image015" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/4073.clip_5F00_image015_5F00_thumb_5F00_79C9495B.jpg" width="398" height="268"></a></p>
<p align="center"><strong>Figure 5: Output of the gray conversion shader</strong></p>
<h4>Parametric Tinting </h4>
<p>The gray conversion shader can now be extended to tint the output in a color that is passed as a parameter through a shader
<b>register</b>.</p>
<p><b>HLSL <br>
</b></p>
<pre class="csharpcode"><span class="rem">/// &lt;summary&gt;The tint color.&lt;/summary&gt;</span>
<span class="rem">/// &lt;type&gt;Color&lt;/type&gt;</span>
<span class="rem">/// &lt;defaultValue&gt;0.9,0.7,0.3,1&lt;/defaultValue&gt;</span>
float4 TintColor : register(C0);

sampler2D Input : register(s0);

float4 main(float2 uv : TEXCOORD) : COLOR 
{
   <span class="rem">// Sample the original color at the coordinate</span>
   float4 color = tex2D(Input, uv);
    
   <span class="rem">// Convert the color to gray</span>
   <span class="kwrd">float</span> gray = dot(color.rgb, float3(0.2126, 0.7152, 0.0722)); 
    
   <span class="rem">// Create the gray color with the original alpha value</span>
   float4 grayColor = float4(gray, gray, gray, color.a); 
   
   <span class="rem">// Return the tinted pixel</span>
   <span class="kwrd">return</span> grayColor * TintColor;
}</pre>
<p>The color used to tint every pixel is passed as a parameter and therefore defined as the first
<b>register</b> C0 (the next parameter should then be in the <b>register</b> C1). The XML comment is used by Shazzam to both create convenient controls and initialize the generated code. Shazzam creates the appropriate controls for the data type and uses the
 defaultValue, minValue and maxValue (Figure 6). The changed value of the control is applied directly to the Sample image, which allows a quick and easy shader development.
</p>
<p>Each element (RGBA) of the passed TintColor parameter is then multiplied with the
<b>float4</b> gray color and returned. The result of the default TintColor values is a
<a href="http://en.wikipedia.org/wiki/Sepia_tone">sepia-toned</a> image (Figure 7).</p>
<p align="center"><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/5481.clip_5F00_image017_5F00_7D676438.jpg"><img title="clip_image017" border="0" alt="clip_image017" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/5700.clip_5F00_image017_5F00_thumb_5F00_4378214C.jpg" width="528" height="344"></a></p>
<p align="center"><strong>Figure 6: Shazzam Tool Shader Settings</strong></p>
<p align="center"><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/2744.clip_5F00_image019_5F00_62BAC81F.jpg"><img title="clip_image019" border="0" alt="clip_image019" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/1754.clip_5F00_image019_5F00_thumb_5F00_624E952A.jpg" width="398" height="268"></a></p>
<p align="center"><strong>Figure 7: Output of the tint shader</strong></p>
<h4>Wiring it together with Silverlight </h4>
<p>Now it's time to use the shader in a Silverlight application and apply it to an Image, MediaElement, or whatever
<a href="http://msdn.microsoft.com/en-us/library/system.windows.uielement(VS.95).aspx">
UIElement</a> you like.</p>
<ol>
<li>Start Visual Studio, create a new <i>Silverlight Application</i> project, and select at least Silverlight 3 as the target framework.
</li><li>In the Shazzam Tool, click on <i>Compile Shader</i> in the<i> Tools</i> menu and then on
<i>Explore Compiled Shaders</i>. Make sure the <i>Generated namespace</i> setting (Figure 2) matches the assembly name of the Silverlight application.
</li><li>Copy the compiled shader file TintShader.ps and the corresponding C# or VB TintShaderEffect.cs|vb file from the
<i>GeneratedShaders</i> folder and the CS|VB subfolder into the Silverlight project directory.
</li><li>In Visual Studio, add the TintShaderEffect.cs|vb and the TintShader.ps file to the project. The property
<i>Build Action</i> of the TintShader.ps file must be set to <i>Resource</i>. Rebuild the solution.
</li><li>Open the MainPage.xaml file and add the namespace declaration and a Button or any other control that has the TintShaderEffect class applied (see below).
</li><li>Hit the F5 key and see your Silverlight shader application in action (Figure 8).
</li></ol>
<p><b>XAML </b></p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">UserControl</span> <span class="attr">x:Class</span><span class="kwrd">=&quot;ShaderDemoApp.MainPage&quot;</span>
    <span class="attr">xmlns</span><span class="kwrd">=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span>
    <span class="attr">xmlns:x</span><span class="kwrd">=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span>
    <span class="attr">xmlns:d</span><span class="kwrd">=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;</span>
    <span class="attr">xmlns:mc</span><span class="kwrd">=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;</span>
    <span class="attr">mc:Ignorable</span><span class="kwrd">=&quot;d&quot;</span>
    <span class="attr">d:DesignHeight</span><span class="kwrd">=&quot;300&quot;</span> <span class="attr">d:DesignWidth</span><span class="kwrd">=&quot;400&quot;</span>
    <span class="attr">xmlns:local</span><span class="kwrd">=&quot;clr-namespace:ShaderDemoApp&quot;</span><span class="kwrd">&gt;</span>

    <span class="kwrd">&lt;</span><span class="html">Grid</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;LayoutRoot&quot;</span> <span class="attr">Background</span><span class="kwrd">=&quot;Gray&quot;</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">Button</span> <span class="attr">Content</span><span class="kwrd">=&quot;Big Tinted Button&quot;</span> <span class="attr">Width</span><span class="kwrd">=&quot;200&quot;</span> 
                <span class="attr">Height</span><span class="kwrd">=&quot;200&quot;</span> <span class="attr">Background</span><span class="kwrd">=&quot;Blue&quot;</span><span class="kwrd">&gt;</span>
            <span class="kwrd">&lt;</span><span class="html">Button.Effect</span><span class="kwrd">&gt;</span>
                <span class="kwrd">&lt;</span><span class="html">local:TintShaderEffect</span> <span class="kwrd">/&gt;</span>
            <span class="kwrd">&lt;/</span><span class="html">Button.Effect</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;/</span><span class="html">Button</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">Grid</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">UserControl</span><span class="kwrd">&gt;</span></pre>
<p>&nbsp;</p>
<p align="center"><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/1667.clip_5F00_image021_5F00_41C75578.jpg"><strong><img title="clip_image021" border="0" alt="clip_image021" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/6064.clip_5F00_image021_5F00_thumb_5F00_61762F40.jpg" width="398" height="296"></strong></a></p>
<p align="center"><strong>Figure 8: The TintShader applied to the Button</strong></p>
<p>That's all that's needed to get a pixel shader working inside a Silverlight application. Please note that no manual C# or VB code-behind was written.</p>
<h4>Example 2: The Mosaic Shader aka The Donut Shader</h4>
<p>The second post process shader effect we'll write is a bit more advanced. It starts with pixelating the image before rounding the blocks until we've the final Mosaic-like result.
</p>
<p>For the development of this shader, we can use a different image. To do so, click the
<i>Open Image File</i> menu item in Shazzam's <i>File</i> menu. I used a famous test picture for image processing algorithms:
<a href="http://en.wikipedia.org/wiki/Lenna">Lenna</a>. By the way, there's an interesting
<a href="http://ndevilla.free.fr/lena/">story</a> behind this picture of Lena Söderberg.</p>
<p align="center"><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/7127.clip_5F00_image023_5F00_0EF74F04.jpg"><strong><img title="clip_image023" border="0" alt="clip_image023" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/7633.clip_5F00_image023_5F00_thumb_5F00_3F3E23BA.jpg" width="284" height="284"></strong></a></p>
<p align="center"><strong>Figure 9: Original Lenna test image</strong></p>
<h4>Pixelating the Input</h4>
<p><b>HLSL <br>
</b></p>
<pre class="csharpcode"><span class="rem">/// &lt;summary&gt;The number of pixel blocks.&lt;/summary&gt;</span>
<span class="rem">/// &lt;type&gt;Single&lt;/type&gt;</span>
<span class="rem">/// &lt;defaultValue&gt;25&lt;/defaultValue&gt;</span>
<span class="kwrd">float</span> BlockCount : register(C0);

sampler2D input : register(S0);

<span class="rem">// Static computed vars for optimization</span>
<span class="kwrd">static</span> <span class="kwrd">float</span> BlockSize = 1.0f / BlockCount; 

float4 main(float2 uv : TEXCOORD) : COLOR
{
   <span class="rem">// Calculate block center</span>
   float2 blockPos = floor(uv * BlockCount);
   float2 blockCenter = blockPos * BlockSize &#43; BlockSize * 0.5;
            
   <span class="rem">// Sample color at the calculated coordinate</span>
   <span class="kwrd">return</span> tex2D(input, blockCenter);
}</pre>
<p>The <b>float </b>BlockCount parameter defines into the number of blocks (large pixels) into which the resulting image will be divided (pixelated). The size of a block (BlockSize) is the inverse of the BlockCount and calculated as
<b>static </b><b>float</b> to save some clock cycles. The coordinate of the current pixel (uv) is then used to determine the block to which it belongs. This determination depends on the BlockCount and is a result of the built-in
<a href="http://msdn.microsoft.com/en-us/library/bb509599(v=VS.85).aspx">floor</a> function. To get the color of the output pixel, the center coordinate of each block is sampled for all the pixels that are part of the block.</p>
<p align="center"><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/4745.clip_5F00_image025_5F00_6CBF437D.jpg"><strong><img title="clip_image025" border="0" alt="clip_image025" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/6557.clip_5F00_image025_5F00_thumb_5F00_6C531088.jpg" width="284" height="284"></strong></a></p>
<p align="center"><strong>Figure 10: Output of the pixelation step</strong></p>
<h4>Rounding the Pixels </h4>
<p><b>HLSL </b></p>
<pre class="csharpcode"><span class="rem">/// &lt;summary&gt;The number of pixel blocks.&lt;/summary&gt;</span>
<span class="rem">/// &lt;type&gt;Single&lt;/type&gt;</span>
<span class="rem">/// &lt;defaultValue&gt;25&lt;/defaultValue&gt;</span>
<span class="kwrd">float</span> BlockCount : register(C0);

<span class="rem">/// &lt;summary&gt;The rounding of a pixel block.&lt;/summary&gt;</span>
<span class="rem">/// &lt;type&gt;Single&lt;/type&gt;</span>
<span class="rem">/// &lt;defaultValue&gt;0.45&lt;/defaultValue&gt;</span>
<span class="kwrd">float</span> Max : register(C2);

sampler2D input : register(S0);

<span class="rem">// Static computed vars for optimization</span>
<span class="kwrd">static</span> <span class="kwrd">float</span> BlockSize = 1.0f / BlockCount; 

float4 main(float2 uv : TEXCOORD) : COLOR
{
   <span class="rem">// Calculate block center</span>
   float2 blockPos = floor(uv * BlockCount);
   float2 blockCenter = blockPos * BlockSize &#43; BlockSize * 0.5;
        
   <span class="rem">// Round the block by testing the distance </span>
   <span class="rem">// of the pixel coordinate to the center</span>
   <span class="kwrd">float</span> dist = length(uv - blockCenter) * BlockCount;
   <span class="kwrd">if</span>(dist &gt; Max)
   {
      <span class="kwrd">return</span> 0;
   }
    
   <span class="rem">// Sample color at the calculated coordinate</span>
   <span class="kwrd">return</span> tex2D(input, blockCenter);
}</pre>
<b></b>
<p>The Max parameter defines the maximum distance of a pixel to its block center and, therefore, the rounding of a pixel block. If the length of the vector between the current pixel coordinate (uv) and its block center is greater than the Max parameter, a transparent
 pixel (0) is returned. The built-in <a href="http://msdn.microsoft.com/en-us/library/bb509617(v=VS.85).aspx">
<b>length</b></a> function is used to calculate the scalar length of the distance vector.</p>
<p align="center"><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/0310.clip_5F00_image027_5F00_424589D8.jpg"><strong></strong></a><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/6082.clip_5F00_image027_5F00_6FC6A99B.jpg"><img title="clip_image027" border="0" alt="clip_image027" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/6560.clip_5F00_image027_5F00_thumb_5F00_6A3611BF.jpg" width="284" height="284"></a></p>
<p align="center"><strong>Figure 11: Output of the rounding step (Max = 0.45)</strong></p>
<p align="center"><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/6507.clip_5F00_image029_5F00_683B3A2E.jpg"><strong></strong></a><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/0333.clip_5F00_image029_5F00_15BC59F2.jpg"><img title="clip_image029" border="0" alt="clip_image029" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/6406.clip_5F00_image029_5F00_thumb_5F00_27E2F97C.jpg" width="284" height="284"></a></p>
<p align="center"><strong>Figure 12: Output of the rounding step (Max = 0.60)</strong></p>
<h4>Baking Donuts </h4>
<p><b>HLSL</b></p>
<pre class="csharpcode"><span class="rem">/// &lt;summary&gt;The number of pixel blocks.&lt;/summary&gt;</span>
<span class="rem">/// &lt;type&gt;Single&lt;/type&gt;</span>
<span class="rem">/// &lt;defaultValue&gt;25&lt;/defaultValue&gt;</span>
<span class="kwrd">float</span> BlockCount : register(C0);

<span class="rem">/// &lt;summary&gt;The rounding of a pixel block.&lt;/summary&gt;</span>
<span class="rem">/// &lt;type&gt;Single&lt;/type&gt;</span>
<span class="rem">/// &lt;defaultValue&gt;0.2&lt;/defaultValue&gt;</span>
<span class="kwrd">float</span> Min : register(C1);

<span class="rem">/// &lt;summary&gt;The rounding of a pixel block.&lt;/summary&gt;</span>
<span class="rem">/// &lt;type&gt;Single&lt;/type&gt;</span>
<span class="rem">/// &lt;defaultValue&gt;0.45&lt;/defaultValue&gt;</span>
<span class="kwrd">float</span> Max : register(C2);

sampler2D input : register(S0);

<span class="rem">// Static computed vars for optimization</span>
<span class="kwrd">static</span> <span class="kwrd">float</span> BlockSize = 1.0f / BlockCount; 

float4 main(float2 uv : TEXCOORD) : COLOR
{
   <span class="rem">// Calculate block center</span>
   float2 blockPos = floor(uv * BlockCount);
   float2 blockCenter = blockPos * BlockSize &#43; BlockSize * 0.5;
        
   <span class="rem">// Round the block by testing the distance </span>
   <span class="rem">// of the pixel coordinate to the center</span>
   <span class="kwrd">float</span> dist = length(uv - blockCenter) * BlockCount;
   <span class="kwrd">if</span>(dist &lt; Min || dist &gt; Max)
   {
      <span class="kwrd">return</span> 0;
   }
    
   <span class="rem">// Sample color at the calculated coordinate</span>
   <span class="kwrd">return</span> tex2D(input, blockCenter);
} </pre>
<b></b>
<p>The last thing left to do in order to get some nice rings (donuts) is to add a test for the minimum distance. This is pretty easy and done with the additional Min parameter.</p>
<p align="center"><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/4861.clip_5F00_image031_5F00_4747C787.jpg"><strong></strong></a><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/8640.clip_5F00_image031_5F00_3492CDD0.jpg"><img title="clip_image031" border="0" alt="clip_image031" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/2625.clip_5F00_image031_5F00_thumb_5F00_48C64656.jpg" width="284" height="284"></a></p>
<p align="center"><strong>Figure 13: Output of the ring step (Min = 0.20, Max = 0.45)</strong></p>
<p>Please note that all of the parameters can be animated, which could result in a nice (transition) effect when two images are overlaid. The Shazzam Tool also supports animation with the generated Shader Settings controls.</p>
<h3>How does the Demo Application work? </h3>
<p>The Silverlight demo application is quite flexible and can be used for many different shader effects without touching the core functionality. This last part of the article will show how this extensibility was achieved. Explanations of how to use the webcam
 with Silverlight and how to load an image from disk were detailed in my last <a href="http://blogs.msdn.com/coding4fun/archive/2010/03/24/9984015.aspx">
Silverlight Face Detection</a> article.</p>
<p>The application's extensibility was mainly accomplished by using the <a href="http://en.wikipedia.org/wiki/Managed_Extensibility_Framework">
Managed Extensibility Framework (MEF)</a> and a <a href="http://en.wikipedia.org/wiki/Model_View_ViewModel">
View-ViewModel approach</a> for the shader parameters. MEF is a great way to make decoupled and flexible applications and has been part of the Silverlight framework since version 4. MEF is like
<a href="http://www.drugabuse.gov/drugpages/methamphetamine.html">Meth</a> for .Net and Silverlight developers, but without all the undesirable side effects.
</p>
<p>The beauty of MEF is best illustrated using source code. As you can see in the demo application (Figure 1), it's possible to select a pixel shader with a ComboBox. The items in the MainPage's shader ComboBox are populated through
<a href="http://msdn.microsoft.com/en-us/library/cc278072(VS.95).aspx">data binding</a> an
<a href="http://msdn.microsoft.com/en-us/library/ms668604(VS.95).aspx">ObservableCollection &lt;T&gt;</a> and MEF is used to build this collection.</p>
<p><b>C# <br>
</b></p>
<pre class="csharpcode"><span class="rem">/// &lt;summary&gt;</span>
<span class="rem">/// The main Page of the application.</span>
<span class="rem">/// &lt;/summary&gt;</span>
<span class="kwrd">public</span> <span class="kwrd">partial</span> <span class="kwrd">class</span> MainPage : UserControl
{
   [ImportMany(AllowRecomposition = <span class="kwrd">true</span>)]
   <span class="kwrd">public</span> ObservableCollection&lt;IShaderViewModel&gt; Shaders;

   <span class="kwrd">public</span> MainPage()
   {
      InitializeComponent();
   }

   <span class="kwrd">private</span> <span class="kwrd">void</span> Initialize()
   {
      <span class="rem">// Compose the parts with MEF</span>
      var container = <span class="kwrd">new</span> CompositionContainer(
            <span class="kwrd">new</span> AssemblyCatalog(GetType().Assembly));
      container.ComposeParts(<span class="kwrd">this</span>);

      <span class="rem">// Fill ComboBox</span>
      CmbShaders.ItemsSource = Shaders;
      CmbShaders.DisplayMemberPath = <span class="str">&quot;Name&quot;</span>;
      CmbShaders.SelectedIndex = 0;

      <span class="rem">// ...</span>
   }

   <span class="rem">// ...</span>
}

<span class="rem">/// &lt;summary&gt;</span>
<span class="rem">/// Interface of a ViewModel for a shader effect.</span>
<span class="rem">/// &lt;/summary&gt;</span>
[InheritedExport]
<span class="kwrd">public</span> <span class="kwrd">interface</span> IShaderViewModel
{
   <span class="kwrd">string</span> Name { get; }
   ShaderEffect Shader { get; }
   UserControl View { get; }
}</pre>
<p>The MainPage has a Shaders collection property containing items that implement the IShaderViewModel interface. This collection is initialized by using MEF's CompositionContainer with an AssemblyCatalog and the ComposeParts method. ComposeParts analyses all
 types in the provided Catalog (here, the assembly), checks if they have certain <a href="http://msdn.microsoft.com/en-us/library/e8kc3626(v=VS.100).aspx">
attributes</a> attached, and wires these so-called parts together. To put it simply, an instance of a type decorated with an
<a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.composition.exportattribute(VS.95).aspx">
Export attribute</a> is created and assigned to each field / property / parameter of the type that has an
<a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.composition.importattribute(v=VS.95).aspx">
Import attribute</a> attached.</p>
<p>The IShaderViewModel interface has the <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.composition.inheritedexportattribute(v=VS.95).aspx">
InheritedExport attribute</a> attached, which means that implementations of this interface will automatically provide that export. The Shaders collection in turn uses the
<a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.composition.importmanyattribute(v=VS.95).aspx">
ImportMany attribute</a>, telling MEF to populate the list with all matching exports (here, all classes that implement the IShaderViewModel interface).</p>
<p>After MEF fills the collection, it is data bound to the ItemsSource property of the ComboBox. The Name property of the IShaderViewModel interface is used as DisplayMember.</p>
<p>The advantage of MEF should be pretty obvious here: you have to implement an IShaderViewModel and maybe a View
<a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.usercontrol(VS.95).aspx">
UserControl</a> for the shader's parameters, but you don't need to add an instance of the shader ViewModel to the Shaders collection manually. Since the IShaderViewModel has the
<a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.composition.inheritedexportattribute(v=VS.95).aspx">
InheritedExport attribute</a> attached, it's not even necessary to add a special MEF attribute to the new shader ViewModel type. Additionally, it's possible to load an extra assembly asynchronously and let MEF compose the parts and update the collection afterwards.
 By setting the AllowRecomposition parameter of the <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.composition.importmanyattribute(v=VS.95).aspx">
ImportMany attribute</a> to true we're asking MEF to allow dynamic updates.</p>
<p>As you can see, MEF is pretty easy but also very powerful. But we have just scratched the surface—this
<a href="http://blogs.msdn.com/mcsuksoldev/archive/2010/04/28/managed-extensibility-framework-overview.aspx">
blog post</a> and the MSDN are good starters if you want to <a href="http://msdn.microsoft.com/en-us/library/ee155691(v=VS.100).aspx">
learn more about MEF</a>. </p>
<h3>Further Resources </h3>
<p>There are many great HLSL shader development resources available on the web. The following list contains some sites focused on Silverlight / WPF pixel shaders. If I forgot a great resource, please post it in a comment.
</p>
<ul>
<li>The open source <a href="http://wpffx.codeplex.com">WPF Pixel Shader Effects Library at CodePlex</a> contains a lot of common pixel shader effects.
</li><li>Nikola Mihaylov (aka Nokola) wrote a <a href="http://nokola.com/EasyPainter">
great online image editor</a> in Silverlight that uses pixel shaders for the effects. He
<a href="http://nokola.com/blog/?tag=/Pixel&#43;Shader">released the pixel shaders</a> that are used in EasyPainter as open source. And he also released the custom controls from his tool. The Slider and the ColorPicker used in the demo application are from
<a href="http://nokola.com/blog/post/2010/03/11/EasyPainter-Source-Pack-1-Refresh-(Bug-Fixes).aspx">
there</a>. I just changed some properties to <a href="http://msdn.microsoft.com/en-us/library/cc221408(VS.95).aspx">
Dependency Properties</a> to make the controls bindable. So Kudos to Nikola! </li><li>Walt Ritscher's amazing <a href="http://shazzam-tool.com/">Shazzam Tool</a> also comes with many cool pixel shaders as samples. Kudos to Walt for making such a great tool!
</li><li>Additionally, from time to time I write some shaders and put them <a href="http://kodierer.blogspot.com/search/label/Shader">
up on my blog</a>. Now that we have an extensible Silverlight shader demo application, I will surely integrate my upcoming shaders directly into it.
</li></ul>
<p>While I was writing this article, an open source project called <a href="http://wpfmetaeffects.codeplex.com">
WPF Meta-Effects</a> was released on CodePlex. The WPF Meta-Effects framework makes it possible to write Shaders for WPF in C# by using attributes, delegates, and dynamic HLSL compilation. It's a neat idea, but due to its dynamic compilation of shaders it's
 limited to WPF and can't be used with Silverlight. Additionally, I much prefer the simplicity of HLSL to C# when writing shaders. There's a reason why HLSL was invented:
<a href="http://wpfmetaeffects.codeplex.com/">see the examples yourself</a>.</p>
<h3>Conclusion</h3>
<p>This article explained what shaders and HLSL are, as well as how to write pixel shaders for Silverlight and WPF. It also showed what tools / frameworks to use for the best developer experience and gave an introduction on how to write an extensible application
 with MEF. </p>
<p>I hope it diminished any fear of the HLSL language and the shader development. I also hope it both inspires and helps you to write your own shaders. I'm eager to see what you come up with. Have fun!</p>
<p>The links to the live demo app and source code are at the top of the article.</p>
<h3>About The Author</h3>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/8463.clip_5F00_image033_5F00_60E9B0B1.jpg"><img title="clip_image033" border="0" hspace="12" alt="clip_image033" align="right" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10014965/7506.clip_5F00_image033_5F00_thumb_5F00_192827CA.jpg" width="140" height="140"></a>René
 Schulte is a .Net / Silverlight developer and Microsoft <a href="http://mvp.support.microsoft.com/profile/Rene.Schulte">
Silverlight MVP</a> passionate about real-time computer graphics, physics, AI, and algorithms. He loves C#, Shaders, Augmented Reality, and computer vision. He started the
<a href="http://SLARToolkit.codeplex.com">SLARToolkit</a>, the <a href="http://WriteableBitmapEx.codeplex.com">
WriteableBitmapEx</a>, and the <a href="http://Matrix3DEx.codeplex.com">Matrix3DEx</a> Silverlight open source projects, and he has a
<a href="http://rene-schulte.info">Silverlight website</a> powered by real time soft body physics. He is also a regular author for Microsoft's Coding4Fun. Contact information can be found on his
<a href="http://rene-schulte.info">Silverlight website</a>, his <a href="http://blog.rene-schulte.info">
blog</a>, or via <a href="http://twitter.com/rschu">Twitter</a>.</p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/webcam/RSS&WT.dl=0&WT.entryid=Entry:RSSView:db33c6aa6ce24903b5059e7600c94b7c">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/SilverShader--Introduction-to-Silverlight-and-WPF-Pixel-Shaders</comments>
      <itunes:summary>
This article explains how to write pixel shaders for the Microsoft Silverlight and WPF platform with HLSL, as well as how to write an extensible Silverlight application for shader demos.


Introduction
Almost 10 years ago, 
Microsoft announced DirectX 8.0, including the huge real-time computer graphics milestone, Direct3D 8.0. Direct3D 8.0 introduced programmable
shaders and gave the developers a chance to create never-before-seen effects and experiences apart from the fixed-function graphics pipeline. With Direct3D 8.0&#39;s new shader capabilities, it
 became possible to compute neat custom-rendering effects on mainstream graphics hardware. Today&#39;s graphics hardware is capable of running hundreds of shaders in parallel and modern games make heavy use of this technology t to achieve stunning effects.

A shader is a rather small program, a so-called kernel function, typically executed in parallel for each data element.
Pixel shaders, for example, are executed for each pixel of a bitmap, and therefore used to implement per-pixel effects.

This introductory article will explain how to write pixel shaders for Silverlight and WPF, what tools should be used, and how to work with the tools. Furthermore, it will show how to build an extensible Silverlight shader application.
Demo Application
The demo application makes it possible to apply different shaders to an image or to the live stream from the webcam. The application not only comes with the two shaders that will be implemented in this article, it also contains three other shaders I&#39;ve written
 before. The complete source code is licensed under the 
Ms-PL and can be downloaded from the 
CodePlex site.
You need at least the Silverlight 4 runtime installed to run the sample and a webcam is needed in order to exploit the full functionality. The runtime is available for
Windows and 
Mac. 
Open the sample

Figure 1: Screenshot of the demo application
How To Use?
You can start and stop the webcam with the 

 Button, or you can </itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/SilverShader--Introduction-to-Silverlight-and-WPF-Pixel-Shaders</link>
      <pubDate>Tue, 25 May 2010 15:51:14 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/SilverShader--Introduction-to-Silverlight-and-WPF-Pixel-Shaders</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/10014965_100.jpg" height="75" width="100"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/10014965_220.jpg" height="165" width="220"/>      
      <dc:creator>Rene Schulte</dc:creator>
      <itunes:author>Rene Schulte</itunes:author>
      <slash:comments>10</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/SilverShader--Introduction-to-Silverlight-and-WPF-Pixel-Shaders/RSS</wfw:commentRss>
      <category>HLSL</category>
      <category>media</category>
      <category>Silverlight</category>
      <category>WebCam</category>
      <category>WPF</category>
      <category>Pixel Shaders</category>
    </item>
  <item>
      <title>Pete at PDC09: Mike Wolf on Stop Motion with the Silverlight 4 Webcam</title>
      <description><![CDATA[Pete Brown and his lovely assistant <img src='http://ecn.channel9.msdn.com/o9/content/images/emoticons/emotion-5.gif' alt='Wink' />, Tim Heuer, interview Mike Wolf from Cynergy Systems at PDC09. Mike has built a Silverlight 4 demo application that uses the new webcam feature, and a png sequencer of his own design, to create stop-motion animation.<br>
<br>
<a href="http://www.cynergysystems.com/blogs/page/michaelwolf">Mike's Blog</a><br>
<a href="http://timheuer.com/blog/">Tim's Blog</a><br>
<a href="http://www.irritatedvowel.com/blog">Pete's Blog</a>&nbsp;  <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/webcam/RSS&WT.dl=0&WT.entryid=Entry:RSSView:502af16de3164f049c969deb0035b8ab">]]></description>
      <comments>http://channel9.msdn.com/Blogs/Psychlist1972/Pete-at-PDC09-Mike-Wolf-on-Stop-Motion-with-the-Silverlight-4-Webcam</comments>
      <itunes:summary>Pete Brown and his lovely assistant , Tim Heuer, interview Mike Wolf from Cynergy Systems at PDC09. Mike has built a Silverlight 4 demo application that uses the new webcam feature, and a png sequencer of his own design, to create stop-motion animation.

Mike&#39;s Blog
Tim&#39;s Blog
Pete&#39;s Blog&amp;nbsp; </itunes:summary>
      <itunes:duration>407</itunes:duration>
      <link>http://channel9.msdn.com/Blogs/Psychlist1972/Pete-at-PDC09-Mike-Wolf-on-Stop-Motion-with-the-Silverlight-4-Webcam</link>
      <pubDate>Thu, 17 Dec 2009 22:15:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/Psychlist1972/Pete-at-PDC09-Mike-Wolf-on-Stop-Motion-with-the-Silverlight-4-Webcam</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/100/513994_100x75.jpg" height="75" width="100"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/220/513994_220x165.jpg" height="165" width="220"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/4/9/9/3/1/5/PeteAtPDC09MikeWolfStopMotionSilverlight4_320_ch9.png" height="240" width="320"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/4/9/9/3/1/5/PeteAtPDC09MikeWolfStopMotionSilverlight4_512_ch9.png" height="384" width="512"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/4/9/9/3/1/5/PeteAtPDC09MikeWolfStopMotionSilverlight4_85_ch9.png" height="64" width="85"/>
      <media:group>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/4/9/9/3/1/5/PeteAtPDC09MikeWolfStopMotionSilverlight4_2MB_ch9.wmv" expression="full" duration="407" fileSize="161247893" type="video/x-ms-wmv" medium="video"/>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/4/9/9/3/1/5/PeteAtPDC09MikeWolfStopMotionSilverlight4_ch9.mp3" expression="full" duration="407" fileSize="3264873" type="audio/mp3" medium="audio"/>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/4/9/9/3/1/5/PeteAtPDC09MikeWolfStopMotionSilverlight4_ch9.mp4" expression="full" duration="407" fileSize="73797700" type="video/mp4" medium="video"/>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/4/9/9/3/1/5/PeteAtPDC09MikeWolfStopMotionSilverlight4_ch9.wma" expression="full" duration="407" fileSize="3312381" type="audio/x-ms-wma" medium="audio"/>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/4/9/9/3/1/5/PeteAtPDC09MikeWolfStopMotionSilverlight4_ch9.wmv" expression="full" duration="407" fileSize="90251231" type="video/x-ms-wmv" medium="video"/>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/4/9/9/3/1/5/PeteAtPDC09MikeWolfStopMotionSilverlight4_Zune_ch9.wmv" expression="full" duration="407" fileSize="57979283" type="video/x-ms-wmv" medium="video"/>
      </media:group>      
      <enclosure url="http://ecn.channel9.msdn.com/o9/ch9/4/9/9/3/1/5/PeteAtPDC09MikeWolfStopMotionSilverlight4_ch9.wmv" length="90251231" type="video/x-ms-wmv"/>
      <dc:creator>Pete Brown</dc:creator>
      <itunes:author>Pete Brown</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/Psychlist1972/Pete-at-PDC09-Mike-Wolf-on-Stop-Motion-with-the-Silverlight-4-Webcam/RSS</wfw:commentRss>
      <category>Animation</category>
      <category>PDC09</category>
      <category>Silverlight 4</category>
      <category>WebCam</category>
    </item>
  <item>
      <title>BugCamSmash in Action!</title>
      <description><![CDATA[
<p>At PDC09, we released&nbsp;<a shape="rect" href="http://silverlight.net/getstarted/silverlight-4-beta/" shape="rect">Silverlight 4 Beta</a> and announced one of the availability of, one of the most requested features, Web Cam Support.</p>
<p>Wanting to have fun with the new feature, I thought of a fun sample to create – smashing bugs with motion detection. First step was to get bugs to crawl across the screen. Next I added the WebCam with frame diff calculation, which was intensive so took advantage
 of the multiple thread support. And finally I added a little Mantis Boy avatar to visualize the smashing of the bugs.</p>
<p><a shape="rect" href="http://adamkinney.wordpress.com/2009/12/03/bugcamsmash-motion-detection-with-silverlight-4-beta/" shape="rect">Learn how the BugCamSmash Demo was created</a></p>
<p>&nbsp;</p>
<p>Drum loop from <a shape="rect" href="http://www.freesound.org/samplesViewSingle.php?id=4852" shape="rect">
Zajo</a>, Karate Shout from <a shape="rect" href="http://www.freesound.org/samplesViewSingle.php?id=66595" shape="rect">
Robinhood76</a></p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/webcam/RSS&WT.dl=0&WT.entryid=Entry:RSSView:b701d4eb25fc45d2859c9dea01170440">]]></description>
      <comments>http://channel9.msdn.com/Blogs/AdamKinney/BugCamSmash-in-Action</comments>
      <itunes:summary>
At PDC09, we released&amp;nbsp;Silverlight 4 Beta and announced one of the availability of, one of the most requested features, Web Cam Support.
Wanting to have fun with the new feature, I thought of a fun sample to create – smashing bugs with motion detection. First step was to get bugs to crawl across the screen. Next I added the WebCam with frame diff calculation, which was intensive so took advantage
 of the multiple thread support. And finally I added a little Mantis Boy avatar to visualize the smashing of the bugs.
Learn how the BugCamSmash Demo was created
&amp;nbsp;
Drum loop from 
Zajo, Karate Shout from 
Robinhood76
</itunes:summary>
      <itunes:duration>91</itunes:duration>
      <link>http://channel9.msdn.com/Blogs/AdamKinney/BugCamSmash-in-Action</link>
      <pubDate>Thu, 03 Dec 2009 18:01:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/AdamKinney/BugCamSmash-in-Action</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/100/510513_100x75.jpg" height="75" width="100"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/220/510513_220x165.jpg" height="165" width="220"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/3/1/5/0/1/5/BugCamSmash_320_ch9.png" height="240" width="320"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/3/1/5/0/1/5/BugCamSmash_512_ch9.png" height="384" width="512"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/3/1/5/0/1/5/BugCamSmash_85_ch9.png" height="64" width="85"/>
      <media:group>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/3/1/5/0/1/5/BugCamSmash_2MB_ch9.wmv" expression="full" duration="91" fileSize="18614193" type="video/x-ms-wmv" medium="video"/>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/3/1/5/0/1/5/BugCamSmash_ch9.mp3" expression="full" duration="91" fileSize="729867" type="audio/mp3" medium="audio"/>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/3/1/5/0/1/5/BugCamSmash_ch9.mp4" expression="full" duration="91" fileSize="10973014" type="video/mp4" medium="video"/>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/3/1/5/0/1/5/BugCamSmash_ch9.wma" expression="full" duration="91" fileSize="746965" type="audio/x-ms-wma" medium="audio"/>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/3/1/5/0/1/5/BugCamSmash_ch9.wmv" expression="full" duration="91" fileSize="14406807" type="video/x-ms-wmv" medium="video"/>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/3/1/5/0/1/5/BugCamSmash_Zune_ch9.wmv" expression="full" duration="91" fileSize="9270859" type="video/x-ms-wmv" medium="video"/>
      </media:group>      
      <enclosure url="http://ecn.channel9.msdn.com/o9/ch9/3/1/5/0/1/5/BugCamSmash_ch9.wmv" length="14406807" type="video/x-ms-wmv"/>
      <dc:creator>Adam Kinney</dc:creator>
      <itunes:author>Adam Kinney</itunes:author>
      <slash:comments>1</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/AdamKinney/BugCamSmash-in-Action/RSS</wfw:commentRss>
      <category>Motion Detection</category>
      <category>Silverlight</category>
      <category>WebCam</category>
    </item>
  <item>
      <title>Microsoft LifeCam Cinema</title>
      <description><![CDATA[Daniel Anguiano sat down with us to show us Microsoft's newest webcam, the <a shape="rect" href="http://www.microsoft.com/presspass/press/2009/aug09/08-20cinemapr.mspx" shape="rect">LifeCam Cinema</a>. This is the best webcam on the market today with full HD resolution, an incredible framerate, and the ability to compensate for low light conditions to give excellent picture quality. <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/webcam/RSS&WT.dl=0&WT.entryid=Entry:RSSView:34bf1c160c7a4a18a91c9e1000fe64be">]]></description>
      <comments>http://channel9.msdn.com/Blogs/LarryLarsen/Microsoft-LifeCam-Cinema</comments>
      <itunes:summary>Daniel Anguiano sat down with us to show us Microsoft&#39;s newest webcam, the LifeCam Cinema. This is the best webcam on the market today with full HD resolution, an incredible framerate, and the ability to compensate for low light conditions to give excellent picture quality.</itunes:summary>
      <link>http://channel9.msdn.com/Blogs/LarryLarsen/Microsoft-LifeCam-Cinema</link>
      <pubDate>Thu, 10 Sep 2009 06:26:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/LarryLarsen/Microsoft-LifeCam-Cinema</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/100/on10_53443_100x75.jpg" height="75" width="100"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/220/on10_53443_220x165.jpg" height="165" width="220"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/4/1/4/3/6/4/LifecamHD_320_ch9.png" height="240" width="320"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/4/1/4/3/6/4/LifecamHD_85_ch9.png" height="64" width="85"/>
      <media:group>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/4/1/4/3/6/4/LifecamHD_ch9.mp3" expression="full" fileSize="2378040" type="audio/mp3" medium="audio"/>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/4/1/4/3/6/4/LifecamHD_ch9.mp4" expression="full" fileSize="21826814" type="video/mp4" medium="video"/>
        <media:content url="http://ecn.channel9.msdn.com/o9/ch9/4/1/4/3/6/4/LifecamHD_ch9.wma" expression="full" fileSize="2411181" type="audio/x-ms-wma" medium="audio"/>
      </media:group>      
      <enclosure url="http://ecn.channel9.msdn.com/o9/ch9/4/1/4/3/6/4/LifecamHD_ch9.mp4" length="21826814" type="video/mp4"/>
      <dc:creator>Larry Larsen</dc:creator>
      <itunes:author>Larry Larsen</itunes:author>
      <slash:comments>2</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/LarryLarsen/Microsoft-LifeCam-Cinema/RSS</wfw:commentRss>
      <category>Hardware</category>
      <category>WebCam</category>
    </item>
  <item>
      <title>LifeCam Cinema HD Unveiled</title>
      <description><![CDATA[ <p>Microsoft just unveiled the latest in their line of LifeCam devices, the LifeCam Cinema HD. This is no basic webcam by any means as it offers 1280 x 720 HD resolution at 30 frames per second. That makes it the first consumer webcam support this level of HD, in fact. (It will also lead to some seriously high-quality&nbsp;Vimeo vids!) </p><p>The camera also features USB 2.0 connectivity, auto focus, a glass lens, a 4x digital zoom, a noise-canceling microphone, and a technology called “ClearFrame” which aims to deliver smooth and detailed video. </p><p>The new webcam is compatible with Windows 7, Windows Vista, and Windows XP out-of-the-box and also integrates with the <a shape="rect" href="http://download.live.com" shape="rect">Windows Live</a> suite of tools including Live Messenger, Live Photo Gallery, and Live Movie Maker. </p><p>However, before you run out to purchase this hardware (which becomes available on September 9th), you’ll need to first check the hardware requirements. Since this camera does some heavy lifting, you’ll need at least a dual core 1.6 GHz processor in order to use it. However, a 3 GHz processor is recommended. You’ll also need 2 GB of memory. </p><p>The camera will retail for $79.99 here in the U.S. </p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/webcam/RSS&WT.dl=0&WT.entryid=Entry:RSSView:7b6e2de62c364140bc359e0e00f576b3">]]></description>
      <comments>http://channel9.msdn.com/Blogs/coolstuff/LifeCam-Cinema-HD-Unveiled</comments>
      <itunes:summary> Microsoft just unveiled the latest in their line of LifeCam devices, the LifeCam Cinema HD. This is no basic webcam by any means as it offers 1280 x 720 HD resolution at 30 frames per second. That makes it the first consumer webcam support this level of HD, in fact. (It will also lead to some seriously high-quality&amp;nbsp;Vimeo vids!) The camera also features USB 2.0 connectivity, auto focus, a glass lens, a 4x digital zoom, a noise-canceling microphone, and a technology called “ClearFrame” which aims to deliver smooth and detailed video. The new webcam is compatible with Windows 7, Windows Vista, and Windows XP out-of-the-box and also integrates with the Windows Live suite of tools including Live Messenger, Live Photo Gallery, and Live Movie Maker. However, before you run out to purchase this hardware (which becomes available on September 9th), you’ll need to first check the hardware requirements. Since this camera does some heavy lifting, you’ll need at least a dual core 1.6 GHz processor in order to use it. However, a 3 GHz processor is recommended. You’ll also need 2 GB of memory. The camera will retail for $79.99 here in the U.S. </itunes:summary>
      <link>http://channel9.msdn.com/Blogs/coolstuff/LifeCam-Cinema-HD-Unveiled</link>
      <pubDate>Tue, 18 Aug 2009 16:23:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/coolstuff/LifeCam-Cinema-HD-Unveiled</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/100/on10_35567_100x75.jpg" height="75" width="100"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/220/on10_35567_220x165.jpg" height="165" width="220"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/320/on10_52238426-0551-4b2d-8501-af623b5bb093.jpg" height="302" width="320"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/85/on10_62b44d4b-eed1-41d1-81bd-1736390ead96.jpg" height="64" width="85"/>      
      <dc:creator>Sarah Perez</dc:creator>
      <itunes:author>Sarah Perez</itunes:author>
      <slash:comments>1</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/coolstuff/LifeCam-Cinema-HD-Unveiled/RSS</wfw:commentRss>
      <category>Hardware</category>
      <category>WebCam</category>
      <category>camera</category>
    </item>
  <item>
      <title>New LifeCams Have Arrived!</title>
      <description><![CDATA[ <p>Microsoft recently announced two new LifeCams that join the <a shape="rect" href="http://store.microsoft.com/microsoft/Hardware-Webcams-Headsets/category/404" shape="rect">lineup of webcams</a> designed for users of Windows PCs: the <a shape="rect" href="http://store.microsoft.com/microsoft/LifeCam-Show/product/8F5E0C2D" shape="rect">LifeCam Show</a> and the <a shape="rect" href="http://store.microsoft.com/microsoft/LifeCam-VX-5500/product/D1105BE3" shape="rect">LifeCam VX-5500</a>. The LifeCam Show is an ultrathin camera with a 2.0MP sensor and three different attachment options – a laptop clip, a desktop stand, and an attachment disk. This one is the more expensive of the two at $99.95. The LifeCam VX-5500 is only $59.95 and features a VGA sensor with great low-light performance. It also has interchangeable colored faceplates in red, white, and blue (how patriotic!). </p><p><a shape="rect" href="http://on10.net/Link/835d9dce-b942-41e4-aecd-a9da6567cb07/" shape="rect"><img width="340" height="113" width="340" height="113" title="vx-5500" alt="vx-5500" src="http://on10.net/Link/dbc4ab70-da08-4866-89ea-94a960d2c8db/" border="0"></a></p><p>By combining these cameras with <a shape="rect" href="http://download.live.com" shape="rect">Windows Live Messenger</a>, you can can engage in live video chats with your friends and family at any time. And if your friends aren’t available online (or if they live on the other side of the globe and you don’t want to wake them!), you can always record a video message using the new Video Messages site at <a shape="rect" href="http://videomessages.live.com" shape="rect">http://videomessages.live.com</a>.&nbsp; </p><p>Want to buy one now? Both are available from the new <a shape="rect" href="http://store.microsoft.com/microsoft/LifeCam-VX-5500/product/D1105BE3" shape="rect">Microsoft Store</a>. </p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/webcam/RSS&WT.dl=0&WT.entryid=Entry:RSSView:916f3a3d04d94a0e88d09e0e001c7263">]]></description>
      <comments>http://channel9.msdn.com/Blogs/coolstuff/New-LifeCams-Have-Arrived</comments>
      <itunes:summary> Microsoft recently announced two new LifeCams that join the lineup of webcams designed for users of Windows PCs: the LifeCam Show and the LifeCam VX-5500. The LifeCam Show is an ultrathin camera with a 2.0MP sensor and three different attachment options – a laptop clip, a desktop stand, and an attachment disk. This one is the more expensive of the two at $99.95. The LifeCam VX-5500 is only $59.95 and features a VGA sensor with great low-light performance. It also has interchangeable colored faceplates in red, white, and blue (how patriotic!). By combining these cameras with Windows Live Messenger, you can can engage in live video chats with your friends and family at any time. And if your friends aren’t available online (or if they live on the other side of the globe and you don’t want to wake them!), you can always record a video message using the new Video Messages site at http://videomessages.live.com.&amp;nbsp; Want to buy one now? Both are available from the new Microsoft Store. </itunes:summary>
      <link>http://channel9.msdn.com/Blogs/coolstuff/New-LifeCams-Have-Arrived</link>
      <pubDate>Wed, 19 Nov 2008 18:42:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/coolstuff/New-LifeCams-Have-Arrived</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/320/on10_22929b6b-2220-40d6-b26b-8f56d4c32d0a.jpg" height="0" width="0"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/85/on10_564a20fc-deb0-4740-8024-7eeb159b7035.jpg" height="64" width="85"/>      
      <dc:creator>Sarah Perez</dc:creator>
      <itunes:author>Sarah Perez</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/coolstuff/New-LifeCams-Have-Arrived/RSS</wfw:commentRss>
      <category>Hardware</category>
      <category>Video</category>
      <category>WebCam</category>
      <category>Windows Live Messenger</category>
      <category>messages</category>
      <category>shopping</category>
    </item>
  <item>
      <title>Create Dynamic Display Pictures In Messenger</title>
      <description><![CDATA[From <a href="http://livechronicles.spaces.live.com/Blog/cns!31AFDCD75FEE9899!1522.entry?wa=wsignin1.0">Windows Live Chronicles</a>, I just learned another great trick for use in the latest version of Windows Live Messenger, v9.0 beta. In this newest version of Live Messenger you have the option to create your own, dynamic&nbsp; display picture by using your webcam. To do so, go into Tools –&gt; Change Display Picture. You’ll see a new option (a button) that reads “Webcam Snapshot.” Select this button and you can record a quick snapshot of you in motion. Make a funny expression, hold up a sign, whatever, then click “Save” when you’re finished recording. The new video snapshot will then become available to choose from among all the other static images already available in Messenger. Set the new video as your display picture and from then on, your friends will see that when they’re IM’ing you in Messenger. To view a quick demo of this in action, check out <a href="http://video.msn.com/?mkt=en-US&amp;playlist=videoByUuids:uuids:4edc5368-9706-4f3e-a59c-f0ecbcf88199&amp;showPlaylist=true">this video on Soapbox</a>. <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/webcam/RSS&WT.dl=0&WT.entryid=Entry:RSSView:12de8a5511b141a388619e0e00c29442">]]></description>
      <comments>http://channel9.msdn.com/Blogs/coolstuff/Create-Dynamic-Display-Pictures-In-Messenger</comments>
      <itunes:summary>From Windows Live Chronicles, I just learned another great trick for use in the latest version of Windows Live Messenger, v9.0 beta. In this newest version of Live Messenger you have the option to create your own, dynamic&amp;nbsp; display picture by using your webcam. To do so, go into Tools –&amp;gt; Change Display Picture. You’ll see a new option (a button) that reads “Webcam Snapshot.” Select this button and you can record a quick snapshot of you in motion. Make a funny expression, hold up a sign, whatever, then click “Save” when you’re finished recording. The new video snapshot will then become available to choose from among all the other static images already available in Messenger. Set the new video as your display picture and from then on, your friends will see that when they’re IM’ing you in Messenger. To view a quick demo of this in action, check out this video on Soapbox.</itunes:summary>
      <link>http://channel9.msdn.com/Blogs/coolstuff/Create-Dynamic-Display-Pictures-In-Messenger</link>
      <pubDate>Mon, 06 Oct 2008 19:08:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/coolstuff/Create-Dynamic-Display-Pictures-In-Messenger</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/320/on10_33c45dc6-9eed-4cf5-9f5c-f7f60f71c5e1.jpg" height="0" width="0"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/85/on10_9a481f38-ed23-4dbb-ba7b-a340e9cfe4c7.jpg" height="64" width="85"/>      
      <dc:creator>Sarah Perez</dc:creator>
      <itunes:author>Sarah Perez</itunes:author>
      <slash:comments>1</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/coolstuff/Create-Dynamic-Display-Pictures-In-Messenger/RSS</wfw:commentRss>
      <category>live messenger</category>
      <category>WebCam</category>
      <category>Windows Live Messenger</category>
      <category>IM</category>
    </item>
  <item>
      <title>Use Any Object as a Controller With Cam-Trax</title>
      <description><![CDATA[<a href="http://www.camspace.com/">Cam-Trax</a> lets you play any PC game you want using almost any object you can find as a game controller - you just need to have a PC and a webcam to do so. The software uses the webcam to scan the object you’re holding and then the object can be used to control your game! (See it in action <a href="http://www.youtube.com/watch?v=v0srY37kkMw">here</a>). Crazy! What’s even crazier is that I just discovered that the Xbox 360 can do this, too, but not many people know about it. The Xbox can be paired with a camera and through <a href="http://msdn.microsoft.com/en-us/xna/default.aspx">XNA</a>, casual game designers can experiment with their ideas. In fact, here are a couple of videos of people doing the machine vision thing with their Xbox: <a href="http://www.youtube.com/watch?v=UR3xPIkIrPE">video 1</a>, <a href="http://www.youtube.com/watch?v=1s63YEWwgqI">video 2</a>. Want to give that a try yourself, <a href="http://www.codeproject.com/KB/game/VidTextureClassWebcamApp.aspx">this guy documented</a> some of the techie details on how to access the <a href="http://forums.microsoft.com/msdn/ShowPost.aspx?PostID=799243&amp;SiteID=1">elusive</a> camera frame buffer. The documentation is available as a download <a href="http://www.codeproject.com/KB/game/VidTextureClassWebcamApp/XnaVideoHelp.zip">here</a>. Now, who’s got a&nbsp; machine vision system that works with XNA? <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/webcam/RSS&WT.dl=0&WT.entryid=Entry:RSSView:3a2225f1f32644c296609e0e0019a60f">]]></description>
      <comments>http://channel9.msdn.com/Blogs/coolstuff/Use-Any-Object-as-a-Controller-With-Cam-Trax</comments>
      <itunes:summary>Cam-Trax lets you play any PC game you want using almost any object you can find as a game controller - you just need to have a PC and a webcam to do so. The software uses the webcam to scan the object you’re holding and then the object can be used to control your game! (See it in action here). Crazy! What’s even crazier is that I just discovered that the Xbox 360 can do this, too, but not many people know about it. The Xbox can be paired with a camera and through XNA, casual game designers can experiment with their ideas. In fact, here are a couple of videos of people doing the machine vision thing with their Xbox: video 1, video 2. Want to give that a try yourself, this guy documented some of the techie details on how to access the elusive camera frame buffer. The documentation is available as a download here. Now, who’s got a&amp;nbsp; machine vision system that works with XNA?</itunes:summary>
      <link>http://channel9.msdn.com/Blogs/coolstuff/Use-Any-Object-as-a-Controller-With-Cam-Trax</link>
      <pubDate>Fri, 13 Jun 2008 19:39:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/coolstuff/Use-Any-Object-as-a-Controller-With-Cam-Trax</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/320/on10_05b8017b-5699-4a65-b725-c1bee41d272a.jpg" height="0" width="0"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/85/on10_49f50917-1d88-4fac-a751-25a097e47bf6.jpg" height="64" width="85"/>      
      <dc:creator>Sarah Perez</dc:creator>
      <itunes:author>Sarah Perez</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/coolstuff/Use-Any-Object-as-a-Controller-With-Cam-Trax/RSS</wfw:commentRss>
      <category>Gaming</category>
      <category>PC</category>
      <category>software</category>
      <category>WebCam</category>
      <category>Xbox</category>
      <category>XNA</category>
    </item>
  <item>
      <title>Everyone Loves Babies! Webcams and Motion Detection</title>
      <description><![CDATA[<span id="c4fmetadata">
<table class="" cellspacing="0" cellpadding="1" width="100%" border="0">
<tbody>
<tr class="entry_overview">
<td class="" width="50">&nbsp;</td>
<td class=""><span class="entry_description">In the belated seventh installment of the &quot;Some Assembly Required&quot; column, Scott Hanselman extends, with permission, Andrew Kirillov's Motion Detector to .NET 2.0 and ClickOnce. He also works around some of the quirks
 in the AirLink AIC250 Network Camera by tracing network traffic and using a little intuition.</span></td>
</tr>
<tr>
<td class="" colspan="2">
<div class="entry_author">Scott Hanselman</div>
<div class="entry_company"><a href="http://www.corillian.com/">Corillian Corporation</a></div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Intermediate</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
1-3 hours</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">$50-$100</span></div>
<div class="entry_details"><b>Software: </b><span class="entry_details_input"><a href="http://msdn.com/express/">Visual Studio C# Express Editions</a></span></div>
<div class="entry_details"><b>Hardware: </b><span class="entry_details_input"><a href="http://www.airlink101.com/products/aic250.html">AIC 250 Network Camera</a></span></div>
<div class="entry_details"><b>Download: </b>
<ul>
<li><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/904439/BabycamAndMotionDetection_CS.msi">C# Download</a></li></ul>
</div>
</td>
</tr>
</tbody>
</table>
</span>
<p><b>April 7, 2006</b></p>
<p><b>Summary:</b> In the belated seventh installment of the &quot;Some Assembly Required&quot; column, Scott Hanselman extends, with permission,
<a href="http://www.codeproject.com/cs/media/Motion_Detection.asp">Andrew Kirillov's Motion Detector</a> to .NET 2.0 and ClickOnce. He also works around some of the quirks in the AirLink AIC250 Network Camera by tracing network traffic and using a little intuition.</p>
<h2>The AIC250 Network Camera</h2>
<p>Some Assembly Required has been out of circulation for a while, but I'm back. I hope you all didn't forget about me. My wife and I had a baby boy, Zenzo, just 12 weeks ago and he's been a handful. He's mostly sleeping through the night now and I'm back to
 work, so I'll get back into the rhythm of writing this column on a regular basic. Please do continue to send in suggestions on what kinds of gadgets I can hook up to .NET.</p>
<p><img alt="" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/904439/babies_1.jpg" border="0"></p>
<p>I wanted to be able to see Zenzo while I'm at work, so I evaluated a number of solutions. I could use Video Chat built into MSN Messenger or other chat tools, but it's kind of inconvenient to bring the baby into the computer room and I often have trouble
 getting the video to work through the firewall. Using video chat would also mean that both sides would have to negotiate the conversation. If I wanted to make things simpler for my wife (and increase the WAF—Wife Acceptance Factor—of the solution), I'd want
 to just call her at home and start the camera remotely with no effort on her part.
</p>
<p>I wanted a camera that would have its own network connection and wouldn't require an attached computer. This means that the camera would have some kind of integrated internal Web Server.</p>
<p>Additionally, my parents live two hours out of town and might want to occasionally peek in on the baby, and I want to make the process as easy as possible on them. Finally, I might want to hook up some kind of motion monitor if the camera detects that the
 baby is thrashing in his sleep.</p>
<p>I looked around at a number of Network Cameras and since price was my background priority, I settled on the AIC250 Network Camera. I picked up the Wired Ethernet version for US$99, but I understand that a wireless version of the same camera can be found
 around the net for $99 as well. </p>
<p><img alt="" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/904439/babies_2.jpg" border="0"></p>
<p>Seting up the camera is trivial: plug it in and it gets an IP address via DHCP. It has an integrated Web Server that lets you manage the camera's settings via your browser. The way the web-based interface displays the video stream is interesting, though.
 It includes two options, a Java Applet or an ActiveX control. These widgets are built into the firmware of the camera and, while the camera's firmware can be updated via software direct from the manufacturer, the video can officially only be viewed in the
 web interface in one of these two ways.</p>
<p>Being the hacker-type that I am, I wanted to get access to the underlying video stream. It's great that the camera includes all the software you need built-in, but if I could get access to the stream I could do all sorts of fun stuff.
</p>
<h2>MotionJPEG</h2>
<p>I used <a href="http://www.pocketsoap.com/tcptrace/">Simon Fell's TCPTrace</a> to peek at the network traffic as I logged into the web interface and looked at the video using the built-in Java applet. I noticed that the traffic was a series of JPEGs, one
 after the other. It was an HTTP GET that never ends. The connection stayed open and spit out JPEGs as fast as I could take it, around 10-15 frames a second. I had never seen traffic like this. I'd assumed that the camera would produce AVIs or MPEG files. Then
 I realized that spitting out JPEGs would be the cheapest possible way to produce video because there'd be no licensing of Video Codecs (Compressor/Decompressor). A little Googling showed me that this technique was called MotionJPEG or MJPEG.</p>
<p>I think of <a href="http://www.webopedia.com/TERM/M/motion_JPEG.html">MotionJPEG</a> as a clever hack, with the emphasis on clever. It's not the MPEG (Motion Picture Experts Group) video that you may be familiar with. Instead, MotionJPEG is a stream of JPEG
 images, one after the other. There doesn't appear to be a formal specification, just varying implementations.</p>
<p><i>There is really no such standard as &quot;motion JPEG&quot; or &quot;MJPEG&quot; for video. Various vendors have applied JPEG to individual frames of a video sequence, and have called the renkinfgsult &quot;M-JPEG&quot;. JPEG is designed for compressing either full-color or gray-scale
 images of natural, real-world scenes. [</i><a href="http://archive.dstc.edu.au/RDU/staff/jane-hunter/video-streaming.html">Review of Video Streaming</a><i>]</i></p>
<p>MotionJPEG over HTTP uses the Content-Type header &quot;multipart/x-mixed-replace&quot; along with a configurable boundary. This means that the stream is made up of Multiple Parts (hence multipart) and each new frame should replace the previous frame (hence x-mixed-replace).
 This particular camera sends an HTTP Header like this:</p>
<p><i>Content-Type: multipart/x-mixed-replace;boundary=--video boundary--</i></p>
<p>The boundary can be anything the server chooses, in this case &quot;--video boundary--&quot; which is a particularly intuitive choice. After the boundary there are additional headers including the actual Content-Type of the part, in this case, image/jpeg.</p>
<p>I started writing a parser/renderer from scratch in .NET 2.0 and the built-in WebClient libraries. It would be fairly easy to read the data into a buffer and watch for the boundary to go by, and then use the
<b>System.Drawing</b> libraries to read the JPEGs in and render them as came in. However, I figured that there might be a library out there that would already do the work for me. That's when I found
<a href="http://www.thecodeproject.com/script/profile/whos_who.asp?id=1181072">Andrew Kirillov's</a>
<a href="http://www.thecodeproject.com/cs/media/Motion_Detection.asp">CodeProject article on Motion Detection</a>.
</p>
<p>The MJPEG handling in Andrew's is actually secondary to his code. His .NET 1.1 project is a showcase for his motion detection algorithms that we'll talk about in a moment, but I was interested in his pluggable VideoSource implementation.</p>
<h2>Andrew's Implementation</h2>
<p>Andrew created an interface called <b>IVideoSource</b>. He includes a number of concrete implementations, one being
<b>MJPEGSourcem</b> the one I needed.</p>
<p><b>Visual C#</b></p>
<pre><code>public interface IVideoSource
{
  event CameraEventHandler NewFrame;
  string VideoSource{get; set;}
  string Login{get; set;}
  string Password{get; set;}
  int BytesReceived{get;}
  object UserData{get; set;}
  bool Running{get;}
  void Start();
  void SignalToStop();
  void WaitForStop();
  void Stop();
  
}
</code></pre>
<p>The most inspired aspect of Andrew's implementation, the one I wouldn't have thought of myself, is the
<b>CameraEventHandler</b>. </p>
<p><b>Visual C#</b></p>
<pre><code>public delegate void CameraEventHandler(object sender, CameraEventArgs e);
public class CameraEventArgs : EventArgs
{
  private System.Drawing.Bitmap bmp;
  public CameraEventArgs(System.Drawing.Bitmap bmp)
  {
    this.bmp = bmp;
  }
  public System.Drawing.Bitmap Bitmap
  {
    get { return bmp; }
  }

}</code></pre>
<p>The VideoSource throws each frame it finds as bitmaps packaged within an event. This might seem inefficient at first glance, but remember that this event would likely not fire more than 30 times a second, more likely around 5-10 times a second. Additionally,
 he's throwing a reference to a bitmap, so it's not like copies of bitmaps are flying around the system. Using eventing in this manner not only makes for a clean interface and separation between an
<b>IVideoSource</b> implementation and the form that chooses to render it, but it also allows Andrew to insert his post-processing filters and motion detection algorithm.</p>
<h2>Working Around Quirks of the AIC250</h2>
<p>I had hoped that I'd be able to plug the Motion application directly into the AIC250 camera's MJPEG source. That turned out to be wishful thinking. There weren't any problems with the MJPEG implementation in Andrew's code, but there were a few quirks in
 the AIC250's embedded Web Server's handling of authentication. </p>
<p><i>(Note the misspelled &quot;Auther&quot; (sic) HTTPHeader that tells us that Steven Wu wrote this Web Server that reports itself as Camera Web Server/1.0.)</i></p>
<p>The AIC250 Camera supports HTTP Basic Authorization. When you visit the administration home page for the first time, you're prompted for a name and password using HTTP Basic Auth, then the ActiveX control or Java Applet is on the next page. My TCP sniffing
 session earlier told me that the stream of JPEGs was the result of an HTTP GET to an endpoint called /mjpeg.cgi.
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/904439/babies_3.png" target="_Top"><img alt="Click here for larger image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/904439/babies_3_thumb.png" border="0"></a></p>
<p><b>(click image to zoom)</b></p>
<p>I assumed that I could make a call to /mjpeg.cgi with .NET, passing in the name and password via HTTP Basic Auth and things would work great. It didn't work, though. However, if I &quot;visited&quot; the home page programmatically first, THEN requested /mjpeg.cgi,
 the MJPEG stream began. Apparently the Camera sets an internal flag after a user hits the home page that allows the next request to hit /mjpeg.cgi. I suspect this is because the /mjpeg.cgi endpoint is coded to simply return JPEGs, nothing else. They (Steven
 Wu?) likely decided that getting /mjpeg.cgi to support authentication and meet the HTTP spec exactly would have been a hassle and wouldn't have provided value. Their use case never suspected that some fool (me) would try to get to the video stream directly.</p>
<p>The next thing I ran into was that HTTP Basic Authentication is supposed to wait for an Authentication Challenge first before sending credentials. This web server seems to want the credentials sent right away. Fortunately the
<b>WebRequest</b> class supports a <b>PreAuthenticate</b> property that sends the authentication credentials first, before the challenge.
</p>
<p>I changed the MJPEGSource to support both &quot;PreAuthentication&quot; and &quot;Authentication with the Home Page&quot; options and I was off and running.</p>
<h2>More Quirks - UnsafeHeaderParsing</h2>
<p>That wasn't the end of the quirks I'd have to fight. After upgrading the application from .NET 1.1 to .NET 2.0, I started getting exceptions while calling
<b>HttpWebRequest.GetResponse()</b>. However, the exceptions weren't very informative. The only thing that had changed was the upgrade from 1.1 to 2.0. A little Googling, MSDNing, and digging led me to
<a href="http://blogs.msdn.com/mflasko/archive/2005/11/02/488370.aspx">Mike Flasko's Blog</a>:</p>
<p><i>&quot;By default, the .NET Framework strictly enforces RFC 2616 for URI parsing. Some server responses may include control characters in prohibited fields, which will cause the System.Net.HttpWebRequest.GetResponse method to throw a WebException. If
<b>useUnsafeHeaderParsing</b> is set to <b>true</b>, <b>System.Net.HttpWebRequest.GetResponse</b> will not throw in this case; however, your application will be vulnerable to several forms of URI parsing attacks. The best solution is to change the server so
 that the response does not include control characters.&quot;</i></p>
<p>Of course, Steven Wu's built-in Web Server in this Camera isn't going to change, so I had little choice but to include an app.config like this:</p>
<pre><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
&lt;configuration&gt;
  &lt;system.net&gt;
    &lt;settings&gt;
      &lt;httpWebRequest useUnsafeHeaderParsing=&quot;true&quot; /&gt;
    &lt;/settings&gt;
  &lt;/system.net&gt;
&lt;/configuration&gt;</code></pre>
<h2>Motion Detection</h2>
<p>Andrew includes four different motion detection algorithms that he describes in detail in his
<a href="http://www.codeproject.com/cs/media/Motion_Detection.asp">CodeProject Article</a>. His algorithms are focused on image processing, rather than video processing, which is why he throws each frame as a bitmap, saving the last frame and comparing it to
 the current frame. Not only can he plug in different video sources, since he &quot;normalizes&quot; all video sources to a series of bitmaps he can apply any motion detection algorithm to any video source.</p>
<p><img alt="" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/904439/babies_4.png" border="0"></p>
<p><img alt="" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/904439/babies_5.png" border="0"></p>
<p>In the image above, the teddy bear on the right has just been moved with a string. The red boxes around the bear were added by the motion detection algorithm indicating what portion of the image changed.</p>
<h2>ClickOnce</h2>
<p>At this point I had a WinForms 2.0 application that let me view the camera in my son's room. I forwarded a port from my cable modem's external IP address to the internal IP address of the camera so I could connect to it from outside or at work. The next
 step was to make the application a ClickOnce application so my parents or I could run it from anywhere.</p>
<p>Visual Studio makes creating a ClickOnce application very straightforward. Right-click on the project within the Visual Studio Solution Explorer and select Properties. First visit the Signing tab and create a Test Certificate (unless you have your own Signing
 Certificate). The certificate will be used to sign the ClickOnce manifest that will be published to the web site. Next visit the Security tab and select &quot;This is a Full Trust application.&quot; If you create your own ClickOnce application, you can specific the
 exact permissions that your application needs to run. Finally, from the Publish tab you can indicate the publishing location and ultimate URL. I chose to publish to a &quot;publish&quot; folder, then upload the contents to my website manually because I'm a control freak.
</p>
<p><img alt="" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/904439/babies_6.png" border="0"></p>
<p>Once the project is configured, you can also build and publish a ClickOnce application by running
<b>msbuild /target:publish </b>from a Visual Studio command line.</p>
<p><i>As an interesting sidenote, I originally blogged about problems with </i><a href="http://www.hanselman.com/blog/ClickOnceAndFireFoxWithACustomSetupEqualsClickThriceAndBeDisappointed.aspx">ClickOnce and FireFox</a><i> but a member of the
</i><a href="http://blogs.msdn.com/saurabh/archive/2006/03/02/541988.aspx">ClickOnce team blogged an explanation</a><i>. Fortunately this will be fixed in the next version of the Framework.</i></p>
<p>Now, anyone in my family can visit our private website, ClickOnce and run this .NET 2.0 WinForms application and connect with a name and password to the AIC250 Network Camera. Andrew's motion detection is an added bonus.</p>
<h2>Conclusion</h2>
<p>There are a number of fun things that could be extended, added, and improved on with this project. Here are some ideas to get you started:
</p>
<ul>
<li>Add your own video source that reads Animated GIFs, DivX or other formats.<br>
<br>
</li><li>Build a video source implementation that connects to WIA (Windows Image Acquisition) devices.<br>
<br>
</li><li>Hook up to other Network Cameras.<br>
<br>
</li><li>Create your own Motion Detection algorithm that compares to frames and see how it stacks up against Andrew's.<br>
<br>
</li><li>Make an event that fires on motion and plugins to react to that motion. Hook up lights, send emails, or whatever you like!<br>
<br>
</li><li>Extend the application to support multiple cameras (maybe up to 4) via a &quot;split screen&quot; feature.
</li></ul>
<p>Have fun and have no fear when faced with the words: Some Assembly Required! </p>
<p>If you do extend this application, be sure to release the source. Thanks again to Andrew Kirillov for allowing me to extend his wonderful source. My family thanks you.</p>
<hr>
<p>Scott Hanselman is the Chief Architect at the Corillian Corporation, an eFinance enabler. He has thirteen years experience developing software in C, C&#43;&#43;, VB, COM, and most recently in VB.NET and C#. Scott is proud to be both a Microsoft RD and Architecture
 MVP. He is co-author of Professional ASP.NET 2.0 with Bill Evjen, available on BookPool.com and Amazon. His thoughts on the Zen of .NET, Programming and Web Services can be found on his blog at
<a href="http://www.computerzen.com/">http://www.computerzen.com/</a>.</p>
<span>In the belated seventh installment of the &quot;Some Assembly Required&quot; column, Scott Hanselman extends, with permission, Andrew Kirillov's Motion Detector to .NET 2.0 and ClickOnce. He also works around some of the quirks in the AirLink AIC250 Network Camera
 by tracing network traffic and using a little intuition. Scott Hanselman Corillian Corporation http://www.corillian.com http://ecn.channel9.msdn.com/o9/c4fcontent/migration/904439/BabycamAndMotionDetection_CS.msi Intermediate 1-3 hours
 Visual Studio C# Express Editions]]&gt; ]]&gt;</span> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/webcam/RSS&WT.dl=0&WT.entryid=Entry:RSSView:7628a39b3a39463c92aa9e7600dc31f2">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Everyone-Loves-Babies-Webcams-and-Motion-Detection</comments>
      <itunes:summary>



&amp;nbsp;
In the belated seventh installment of the &amp;quot;Some Assembly Required&amp;quot; column, Scott Hanselman extends, with permission, Andrew Kirillov&#39;s Motion Detector to .NET 2.0 and ClickOnce. He also works around some of the quirks
 in the AirLink AIC250 Network Camera by tracing network traffic and using a little intuition.



Scott Hanselman
Corillian Corporation

Difficulty: Intermediate
Time Required: 
1-3 hours
Cost: $50-$100
Software: Visual Studio C# Express Editions
Hardware: AIC 250 Network Camera
Download: 

C# Download






April 7, 2006
Summary: In the belated seventh installment of the &amp;quot;Some Assembly Required&amp;quot; column, Scott Hanselman extends, with permission,
Andrew Kirillov&#39;s Motion Detector to .NET 2.0 and ClickOnce. He also works around some of the quirks in the AirLink AIC250 Network Camera by tracing network traffic and using a little intuition.
The AIC250 Network Camera
Some Assembly Required has been out of circulation for a while, but I&#39;m back. I hope you all didn&#39;t forget about me. My wife and I had a baby boy, Zenzo, just 12 weeks ago and he&#39;s been a handful. He&#39;s mostly sleeping through the night now and I&#39;m back to
 work, so I&#39;ll get back into the rhythm of writing this column on a regular basic. Please do continue to send in suggestions on what kinds of gadgets I can hook up to .NET.

I wanted to be able to see Zenzo while I&#39;m at work, so I evaluated a number of solutions. I could use Video Chat built into MSN Messenger or other chat tools, but it&#39;s kind of inconvenient to bring the baby into the computer room and I often have trouble
 getting the video to work through the firewall. Using video chat would also mean that both sides would have to negotiate the conversation. If I wanted to make things simpler for my wife (and increase the WAF—Wife Acceptance Factor—of the solution), I&#39;d want
 to just call her at home and start the camera remotely with no effort on her part.

I wanted a camera that would have its own network c</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Everyone-Loves-Babies-Webcams-and-Motion-Detection</link>
      <pubDate>Mon, 30 Oct 2006 19:05:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Everyone-Loves-Babies-Webcams-and-Motion-Detection</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/904439_100.jpg" height="75" width="100"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/904439_220.jpg" height="165" width="220"/>      
      <dc:creator>Scott Hanselman</dc:creator>
      <itunes:author>Scott Hanselman</itunes:author>
      <slash:comments>3</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Everyone-Loves-Babies-Webcams-and-Motion-Detection/RSS</wfw:commentRss>
      <category>Video</category>
      <category>WebCam</category>
      <category>motion detection</category>
    </item>    
</channel>
</rss>
