ピクセルシェーダー③ ShaderEffect
PsPad でビルド・保存したシェーダーバイトコード(.ps)をプロジェクトに組み込む方法を解説します。ShaderEffect の継承する具象クラスを実装します、詳細は MSDN ライブラリーの ShaderEffect クラス(WPF, Silverlight)を参照してください。Silverlight でも WPF でもほとんど同じ手順です。
VS2010で新規プロジェクトを作成し、画像(Stove.jpg)を表示して、その画像にGray.psを適用するとしましょう。
- PsPad で Gray.fx をコンパイルしてバイトコード Gray.ps を保存(WPF 4 以外で使う時は PS2_0 でコンパイル)
- Visual Studio 2010 でプロジェクトにGray.psを追加([プロジェクト]→[既存項目の追加])
- Gray.ps のプロパティのビルドアクションを resource に設定。
- 新しいクラス MyGrayEffect.cs を追加([プロジェクト]→[クラスの追加])
- 名前空間に System.Windows.Media.Effects を追加
- MyGrayEffect クラスを ShaderEffect の派生クラスにする
- コンストラクターを記述(Silverlight と WPF では Uri のパスの記述が違うので注意)
- シェーダーへのサンプラー入力レジスタ用の依存プロパティを記述(なぜか Silverlight では明示的に定義しなくても動作します)
using System.Windows.Media.Effects;
namespace MyApplication
{
class MyGrayEffect : ShaderEffect
{
// コンストラクター
public MyGrayEffect()
{
PixelShader ps = new PixelShader();
// Silverlight のとき
// Uri u = new Uri(@"/MyApplication;component/Gray.ps",
// UriKind.RelativeOrAbsolute);
// WPF のとき
Uri u = new Uri(
@"pack://application:,,,/MyApplication;component/Gray.ps",
UriKind.RelativeOrAbsolute);
ps.UriSource = u;
this.PixelShader = ps;
UpdateShaderValue(InputProperty);
}
// 依存プロパティ
public Brush Input
{
get { return (Brush)GetValue(InputProperty); }
set { SetValue(InputProperty, value); }
}
public static readonly DependencyProperty InputProperty =
ShaderEffect.RegisterPixelShaderSamplerProperty("Input",
typeof(MyGrayEffect), 0);
}
}
MainWindow.xaml (WPF) あるいは MainPage.xaml (Silverlight) 内で、エフェクトを適用すると Image 要素は以下のようになります。
<Image Name="MyImage" Source="Stove.jpg">
<Image.Effect>
<local:MyGrayEffect />
</Image.Effect>
</Image>
Gray ピクセル シェーダー エフェクト適用前と適用後