Wednesday, December 30, 2009

Ye Olde Kamera - Silverlight 4 Webcam & Old Movie Shader

Another great and successful year comes to an end and I hope that the next year will get even better. We all don't get younger and we change over the years, but the last Silverlight demo I made for this year allows you take some fake aged memories with your webcam. The Silverlight 4 webcam and microphone support is always fun and even more when it's combined with a pixel shader. This demo uses my Old Movie Pixel Shader to create a neat real time webcam effect that simulates scratches, noise and other effects you might have seen in old movies. I also brushed things up a bit by framing the video output with a filmstrip and using some nice new icons from eggheadcafe.

Live
The Silverlight 4 runtime must be installed to run the demo. It's available for Windows and Mac.



The Webcam capturing could be started and stopped with the camera Button. If you press it for the first time you need to give your permission for the capturing. This application uses the default Silverlight capture device. You can specify the video and audio devices that are used by default with the Silverlight Configuration. Just press the right mouse button over the application, click "Silverlight" in the context menu and select the new "Webcam / Mic" tab to set them.
Press the disk Button to take a framed snapshot and save it to a JPEG file on your harddisk.
The amount of noise can be changed using the Slider and the movie ToggleButton allows you to disable the Old Movie Shader.

How it works
It's basically the Silverlight 4 CaptureSource class and my Old Movie Pixel Shader attached to the video output. I covered the Silverlight webcam and shader usage in this blog post and the JPEG encoding in this one. The Old Movie Shader was presented here.

Source code
The Visual Studio 2010 solution including the refactored Old Movie Shader is available here.

Final words
Thanks to my kids and especially to my wife for all her patience in 2009. I love her!
I also like to thank all the people and new friends I got to know this year and especially the Silverlight community. I hope you liked my blog posts and enjoyed the Silverlight demos I've made. I have more to come next year.
I wish you all a great new year, all the best in 2010 and peace!

Update 03-20-2010
Updated to the Silverlight 4 release candidate.

Update 04-15-2010
Updated to the final Silverlight 4 RTW build.

8 comments:

  1. Hi! I like your movie shader :) have to implent it for nGENE :)

    ReplyDelete
  2. Thanks. It's done with shader model 2 only and I'm a bit proud of the changing noise trick. I only use one generated static noise texture and just 4 random base coordinates that change every frame for the noise texture lookup.
    The details were covered in the original blog post:
    http://kodierer.blogspot.com/2009/08/ye-olde-pixels-silverlight-3-old-movie.html

    But why re-implement it, feel free to use my shader for nGene directly if possible. The HLSL .fx file is also included in the source code and the usage code can be found in the associated .cs file. You can also copy it from the original blog post's listing:
    http://kodierer.blogspot.com/2009/08/ye-olde-pixels-silverlight-3-old-movie.html

    ReplyDelete
  3. OK, so I'll go with your implementation then (of course there will be note you're the author of it).

    ReplyDelete
  4. @Riddlemaster: Sure, that's fine with me.

    ReplyDelete
  5. Hello Rene,

    I used your OldCam as a strting point to learn more about pixel shaders. Excellent work and exactly enough features to get a hold of it.

    Now I am working on two pixel shaders for myself:
    * the first one is a green screen shader to isolate a subject in front of a green screen. This one works good enough.
    * The second one serves the same purpose in another fashion; first shooting an image of the background without subject, then processing a live feed with (moving) subject and 'subtracting' the background to isolate the subject.

    The second one doesn't work yet. I think this has something todo with the way I pass the initial static image to the shader (as a WritableBitmap) to register 0 (I hope).

    Can you advice on how to do this?

    Best regards,

    Komawi --> Martijn at komawi.com

    ReplyDelete
  6. Hi Komawi,

    The first shader sounds like a Color Key shader. There's also one as part of the WPF FX library (ColorKeyAlpha):
    http://wpffx.codeplex.com

    Your second shader uses a static bitmap and a stream. I guess you apply it to a MediaElement or a shape that is filled with a VideoBrush.
    You need two registers in the shader:
    sampler2D InputSampler : register(S0);
    sampler2D StaticSubSampler : register(S1);

    In the relevant code they map to:
    public static DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(ScratchedShader), 0);
    public static DependencyProperty StaticImageProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("StaticImage", typeof(ScratchedShader), 1);

    As you see, the Input (live feed) has to use the S0 register. This is important! Silverlight passes the element the shader is applied to into the S0 register. The static image will be passed to the S1 register.
    Both properties are typeof System.Windows.Media.Brush. So you can't use the WriteableBitmap directly, instead you have to do this:
    ImageBrush brush = new ImageBrush();
    brush.ImageSource = writeableBmp;
    StaticImage = brush;

    See how I use them in my old movie shader code. I do all these things there.
    The Shazzam Tool is also great for devleloping shaders and now supports multiple inputs.

    Good luck!

    ReplyDelete
  7. Thanks a zillion Rene!

    Have't got it working yet, but I'm sure this is enough input to get there.

    Komawi

    ReplyDelete
  8. Excellent demo man, I can see you're really creative and original, I'd like to develop something similar because I have to do a task related to it at the highschool.

    ReplyDelete