開発環境 Microsoft Visual Studio Express 2013 for Windows Desktop
実行環境 Microsoft Windows 8.1 (64bit)
プロジェクトの種類 Visual C#/WPF アプリケーション
プロジェクト名 WpfHlslTest

以下のファイルをプロジェクトに追加する。
TestShader.cs クラス
TestShader.fx 既存の項目 ビルド アクション:なし
TestShader.ps 既存の項目 ビルド アクション:Resource

MainWindow.xaml
<Window x:Class="WpfHlslTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfHlslTest"
        Title="MainWindow" Height="500" Width="500">
    <Grid>
        <Grid.Effect>
            <local:TestShader x:Name="TestShader" />
        </Grid.Effect>
        <Canvas Background="LightBlue" />
    </Grid>
</Window>
 

MainWindow.xaml.cs
using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media.Media3D;
using System.Windows.Threading;
 
namespace WpfHlslTest
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        private DispatcherTimer intervalTimer = new DispatcherTimer();
        private Point3D pos = new Point3D(0, 0, 1);
 
        public MainWindow()
        {
            InitializeComponent();
 
            intervalTimer.Interval = TimeSpan.FromMilliseconds(30);
            intervalTimer.Tick += intervalTimer_Tick;
            intervalTimer.Start();
        }
 
        void intervalTimer_Tick(object sender, EventArgs e)
        {
            if (Keyboard.IsKeyDown(Key.Escape)) Application.Current.Shutdown();
            if (Keyboard.IsKeyDown(Key.Up)) pos.Z *= 0.99;
            if (Keyboard.IsKeyDown(Key.Down)) pos.Z *= 1.01;
            if (Keyboard.IsKeyDown(Key.Left)) pos.X -= pos.Z * 0.01;
            if (Keyboard.IsKeyDown(Key.Right)) pos.X += pos.Z * 0.01;
            TestShader.Center = pos;
        }
    }
}
 

TestShader.cs
using System;
using System.Reflection;
using System.Windows;
using System.Windows.Media.Effects;
using System.Windows.Media.Media3D;
 
namespace WpfHlslTest
{
    public class TestShader : ShaderEffect
    {
        private static PixelShader _pixelShader =
            new PixelShader() { UriSource = MakePackUri("TestShader.ps") };
 
        public TestShader()
        {
            PixelShader = _pixelShader;
 
            UpdateShaderValue(CenterProperty);
        }
 
        private static Uri MakePackUri(string relativeFile)
        {
            Assembly a = typeof(TestShader).Assembly;
 
            string assemblyShortName = a.ToString().Split(',')[0];
 
            string uriString = "pack://application:,,,/" +
                assemblyShortName +
                ";component/" +
                relativeFile;
 
            return new Uri(uriString);
        }
 
        //----------------------------------------------------------------------
        public Point3D Center
        {
            get { return (Point3D)GetValue(CenterProperty); }
            set { SetValue(CenterProperty, value); }
        }
 
        public static readonly DependencyProperty CenterProperty =
            DependencyProperty.Register("Center", typeof(Point3D), typeof(TestShader),
            new UIPropertyMetadata(new Point3D(0, 0, 1), PixelShaderConstantCallback(0)));
    }
}
 

TestShader.fx
float4 center : register(c0);
 
float4 main(float2 uv : TEXCOORD) : COLOR
{
	float4 color;
 
	float x = uv.x - 0.5 - center.x;
	float y = uv.y - 0.5;
	float r2 = x * x + y * y;
	if (r2 * center.z < 0.125) {
		color = float4(1, 0, 0, 1);
	}
	else {
		color = float4(1, 1, 1, 1);
	}
 
	return color;
}
 

makefx.bat
"C:\Program Files (x86)\Windows Kits\8.1\bin\x86\fxc.exe"^
 /T ps_2_0 /E main /Fo TestShader.ps TestShader.fx
pause
 
最終更新:2014年05月31日 11:30