CAD System Web Site - Computer Aided Design Software
i NET1000.COM
by Makoto Honda
Last Update: 2012-January-28                                        Update Info     Site Index     Licensing     Copyright Notice     Privacy Policy     Contact Us  
 

 

HOME

_________________

HLSL Notes
_________________

                                               Return to   C# / WPF Implementation       

  High Level Shading Language / GPU / WPF / C# /                                          

   HLSL Example by Ira Lukhezo & Greg        2012-January-28

    This simple HLSL code will be applied to every pixel on the image using GPU (graphics card) and saturate/desaturate the image.

       

   0.  PREPARATION

    This will install Visual Studio Project Templates and Item Templates for building Shader Effects for WPF.

    Link to Greg .... http://wpf.codeplex.com/releases/view/14962

    http://lukhezo.com/2011/03/12/saturationdesaturation-with-hlslpixel-shaders-and-wpf/

    Download Application Shader Effects BuildTask and Templates.zip

    1) Unzip the above to create : Shader Effects BuildTask and Templates
        -->  ShaderBuildTaskSetup.msi
        -->  Templates.zip

    2) Install ShaderBuildTaskSetup.msi

    3) Right click on Templates.zip and choose Extract All. Choose your Visual Studio directory (C:\Users\makoto\My Documents\Visual Studio 2008) as the directory to extract into.
        This will ask you if you want to merge files into the existing directory structure. Say Yes. This will then merge the new VS templates into the "Templates" directory under your VS directory.
        If you've set up your VS user project/item template directories to something other than the default, you'll want to extract there.
        Check what they are: In VS2008, Tools-->Options-->Projects and Solutions-->General.
 

   1.  CREATE VS2010 SOLUTION

    Now that the required components are installed, create a new WPF Application (solution) in Visual Studio 2010 Express (or Visual Studio 2008, the Express Editions or Silverlight).
    Name the project
Project_01_Main. When closing VS, it asks where to save the solution!!!  So save and bring it back...

    This becomes the name of the solution as well as the name of the project under the solution. The solution name can be changed freely later,
    but changing the project name (and file name) is tricky, so choose the name carefully. This also becomes the namespace name as well....
 

   2. ADD NEW PROJECT

    Next, add a new project to the solution: From the VS Solution Explorer, R-click the solution and Add... New Project. Then, select WPF Shader Effect Library.
    Call it
Project_02_ShaderLibrary. (To use WPF Shader Effect Library ensure the templates linked to above are installed.)

    This new shader effects library hooks up the plumbing required to easily create pixel shaders.
 

   

    You have created a WPF Shader Effect Library project. It currently has an effect called Effect1, and some utility functionality in it.
    To add a new ShaderEffect, choose Add New Item..., and then select WPF Shader Effect. This will generate a .cs file and a .fx file.
    Make sure that you R-click Properties of the .fx file and set BuildAction to "Effect". Otherwise, it won't be compiled.


   3. DELETE Effect1.cs and Effect1.fx

    Delete the automatically added Effect1.cs and Effect1.fx files. Make sure not to delete EffectLibrary.cs as this will be used by any effects that you add.
 

   4. ADD NEW EFFECT FILE

   Add an item (new shader effect) to the above Project_02_ShaderLibrary project by R-click Add... New Item and select "WPF Shader Effect". Call it MyShaderEffect.

   

    When you installed the build tasks and templates in step 0 above, this key component was added to this type of dll.
    S
o whenever you add a new effect file, ensure that the .fx file has its build action set to effect as follows, else things will not work.

    Whenever you create a new "WPF Shader Effect" Item, R-click the .fx file in Solution Explorer and choose Properties.
    Then for "Build Action" select "Effect" from the dropdown. Otherwise the effect won't build.

   
 

   5. COPY .CS

    Copy the following code into cs file;

    using System;
   
using System.Windows;
   
using System.Windows.Media;
   
using System.Windows.Media.Effects;

   
namespace ns_ShaderLibrary
    {
       
public class MyShaderEffect : ShaderEffect
        {
           
#region Constructors
           
static MyShaderEffect()
            {
                _pixelShader.UriSource =
Global.MakePackUri("MyShaderEffect.ps");
            }
           
public MyShaderEffect()
            {
               
this.PixelShader = _pixelShader;
               
// Update each DependencyProperty that痴 registered with a shader register. This
                // is needed to ensure the shader gets sent the proper default value.

           
    UpdateShaderValue(InputProperty);
                UpdateShaderValue(SaturationProperty);
            }
           
#endregion

           
#region Dependency Properties
           
public Brush Input
            {
               
get { return (Brush)GetValue(InputProperty); }
               
set { SetValue(InputProperty, value); }
            }

          
  // Brush-valued properties turn into sampler-property in the shader.
            // This helper sets "ImplicitInput" as the default, meaning the default
            // sampler is whatever the rendering of the element it痴 being applied to is.

          
  public static readonly DependencyProperty InputProperty =
            RegisterPixelShaderSamplerProperty("
Input", typeof(MyShaderEffect), 0);

           
public double Saturation
            {
                 
get { return (double)GetValue(SaturationProperty); }
                 
set { SetValue(SaturationProperty, value); }
            }
           
public static readonly DependencyProperty SaturationProperty =
                 
DependencyProperty.Register("Saturation",
                 
typeof(double),
                 
typeof(MyShaderEffect),
                 
new UIPropertyMetadata(1.0, PixelShaderConstantCallback(0)));

           
#endregion

           
#region Member Data
           
private static PixelShader _pixelShader = new PixelShader();
           
#endregion
        }
    }

 

   6. COPY .FX

    Copy the following code into fx file;

  // WPF ShaderEffect HLSL -- MyShaderEffect

  //覧覧覧覧覧覧覧覧覧覧覧覧覧覧蘭
  // Shader constant register mappings (scalars float, double, Point, Color, Point3D, etc.)
  //覧覧覧覧覧覧覧覧覧覧覧覧覧覧蘭
  float4 Saturation : register(c0);

  //覧覧覧覧覧覧覧覧覧覧覧覧覧覧
  // Sampler Inputs (Brushes, including ImplicitInput)
  //覧覧覧覧覧覧覧覧覧覧覧覧覧覧
  sampler2D implicitInputSampler : register(S0);

  //覧覧覧覧覧覧覧覧覧覧覧覧覧覧
  // Pixel Shader
  //覧覧覧覧覧覧覧覧覧覧覧覧覧覧
  float4 main(float2 uv : TEXCOORD) : COLOR
  {
  float3 LuminanceWeights = float3(0.299,0.587,0.114);
  float4 srcPixel = tex2D(implicitInputSampler, uv);
  float luminance = dot(srcPixel,LuminanceWeights);
  float4 dstPixel = lerp(luminance,srcPixel,Saturation);
  //retain the incoming alpha
  dstPixel.a = srcPixel.a;
  return dstPixel;
  }
 

   7. COPY MainWindow.xaml

    In the MainWindow.xaml copy the following code;

    <Window x:Class="ns_Main.MainWindow"
       
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       
xmlns:shaders="clr-namespace:ns_ShaderLibrary;assembly=Project_02_ShaderLibrary"
       
Title="MainNewMakotoWindow" Height="600" Width="500">
        <
Grid>
            <
Grid.RowDefinitions>
                <
RowDefinition Height="*"/>
                <
RowDefinition Height="30"/>
            </
Grid.RowDefinitions>
            <
Image Source="/Project_01_Main;component/Images/cobraplant.jpg" Grid.Row="0" >
                <
Image.Effect>
                    <
shaders:MyShaderEffect Saturation="{Binding ElementName=slider, Path=Value}" />
                </
Image.Effect>
            </
Image>
            <
Slider x:Name="slider" Minimum="0" Maximum="6" Value="1" Grid.Row="1" />
        </
Grid>
    </
Window>
 

   8. REFERENCE SETTING

    In Solution Explorer, R-Click References of Project_01_Main and Add Reference, select Project_02_ShaderLibrary.

   
 

   9. SET IMAGE TO USE

    To use an image in this shader program, using Windows Explorer, bring a JPEG file under "Images" folder created under Project_01_Main folder.
    Then in VS2010 Solution Explorer, R-click Add New Folder on Project_01_Main and create a folder named "Images."
   
Then R-click Add Existing Item on that Images folder, and select the JPEG file.
 

   10. NEW JPEG IMAGE

    If you want to try different images, bring a JPEG to Images folder, and in VS2010, Add - Existing Item to Images. 
    You must change XAML to point to that new image, and try. If the image does not show up in the program, try changing Mainwindow "width" in XAML and try...
 

   11. CHANGE NAMESPACE NAME

    Now the solution should build and run OK. By default, VS gives the same name for "project" and "namespace". I do not like that.
    So I am going to change my namespaces as unique "ns_xxx" naming instead of being the same as the "project" name.
    Find all the occurrences of "project" name and replace 3 of them to "ns_xxx".

    TIP:  assembly=
projectname
            assembly:AssemblyTitle (
projectname)
            assembly:AssemblyProduct (
projectname)

    TIP:  Application x:Class="
ns_namespace"
            namespace
ns_namespace.Properties
           
ns_namespace.Properties.Resources
 

   FINALLY

    (IRA & GREG) --- If you add an image and compare the saturation with a program like Paint.NET you will see that you have saturation added to your WPF images with a very few lines of code, and best of all it is very fast. I would also recommend you search codeplex for a shader effects library that contains many more shader effects and will help you get started and understand how they work.

    (IRA & GREG) --- I would also advise you to ensure that you remember to freeze all pixel shader instances (in your effect .cs files) and remove any static references (especially static constructors and shaders), as they are a prime candidate for memory leaks.
 

   

          

 

CAD System Web Site - Computer Aided Design Software:  Copyright ゥ 2010-2013 Makoto Honda. All Rights Reserved.  

 

   

Copyright ゥ 2010-2013 Makoto Honda. All Rights Reserved.