Microsoft Visual Web Developer 2008 Express Edition
 Silverlight 3
 Shazzam 1.2

■Silverlightでピクセルシェーダー Prev  Top  Next

ドメイン

今回はSilverlightでピクセルシェーダーをやります。 現在はSilverlight上で3Dを使用できないのでポストエフェクトくらいしかできませんが、それでもWeb上でピクセルシェーダーを実行できるというのは面白い試みだと思います。 とか書いてるけど既にFlashで可能だったりして(笑)。

今回のサンプルでは当サイトで紹介していないネタを実装します。 ラスタースクロールです。まあたいしたネタでないですが。

まずピクセルシェーダーの解説サイトを紹介します。
MSDN
このサイトでは、ピクセルシェーダーの実装方法を解説しています。
またHLSLを使用してピクセルシェーダーをコーディングする際に便利な開発ツールを紹介してます。
Shazzam
せっかくなのでShazzamを使用した開発スタイルを紹介します。

1.まずHLSLをコンパイルするために必要となる fxc.exe を取得する必要があります。これは DirectX SDK に添付されていますので、まずは DirectX SDK をダウンロードしてインストールしてください。
2.次にShazzamのサイトから Shazzam をインストールします。
3.Shazzamのインストールが終了したら、起動してみてください。
Shazzam
画面は大きく3分割されています。
左側は各種設定やfxファイルの変更などを行います。
右上はテスト表示で使用するサンプル画像の変更を行います。自分で用意した画像を使用することも可能です。
右下はfxファイルおよびマネージドコードのソースの内容を表示します。シェーダーのパラメータの変更を変更することも可能です。

画面構成とインターフェースは単純なので特別解説する必要もないと思うので、重要な部分だけ説明します。

かならずやらなければならないことはfxc.exeへのパスを設定することです。これをやらないとHLSLで記述されたfxファイルをコンパイルできません。
fxc.exeへのパスを設定
このように操作して設定します。なおfxc.exeがある場所は、"DirectX SDKをインストールしたルートフォルダ\Utilities\Bin\x86"です。 パスについてはSDKのバージョンによっては変更されているかもしれませんのでご注意を。

4.次にfxファイルを新規作成して、ピクセルシェーダーをコーディングします。なお、マネージドコードは修正しないで とコメントに書かれているので修正しない方がいいかと。

---RasterScroll.fx---


// 2Dテクスチャー
sampler2D input : register(s0);

// 周期
float Period : register(C0);

// 振幅
float Amplitude : register(C1);

// 波の移動
float Offset : register(C2);

float4 main(float2 uv : TEXCOORD) : COLOR 
{ 
   float4 Color; 
   float2 xy;

   xy.x = uv. x + sin(  ( uv.y + Offset )  *  Period  ) * Amplitude;
   xy.y = uv.y;
   Color= tex2D( input , xy ); 

   return Color; 
}

単純なのでソースの解説はなしで。

5.コーディングが終了したら F5 をクリックしてコンパイルします。エラーが発生した場合は右下の部分にエラーの内容と場所が表示されます。 コンパイルに成功したらpsファイルが作成されます。psファイルが出力されるフォルダは、「Tools」メニューの「Explore Compiled Shaders (*.ps)」をクリックすると表示されます。 ファイル名はfxファイル名と同じになります。このpsファイルを使用してSilverlight上でピクセルシェーダーを実行します。

6.次にSilverlight側の開発手順を説明します。まずプロジェクトを作成します。プロジェクト名はSilverlightSampleです。
ソリューションエクスプローラー
back.jpgファイルとピクセルシェーダーをコンパイルして作成されたRasterScroll.psファイルをインポートします。

7.次にRasterScroll.csファイルを作成します。このファイルにShazzamで自動生成されたマネージドコードをコピペします。 このソースコードは基本そのまま使用できますが、RasterScroll.psファイルをロードするときに使用する相対パスを次のように修正します。


//pixelShader.UriSource = new Uri("/Shazzam.Shaders;component/RasterScroll.ps", UriKind.Relative);
pixelShader.UriSource = new Uri("/SilverlightSample;component/Resource/RasterScroll.ps", UriKind.Relative);

RasterScroll.csファイル内の名前空間はShazzam.Shadersとなっていてプロジェクト全体の名前空間(SilverlightSample)と異なります。 そのためパスを"/Resource/RasterScroll.ps"とするとファイルを取得できません。この場合は上記のように名前空間を指定するようにします。

8.MainPage.xamlを修正し、RasterScroll.psをロードするコントロールを指定します。

---MainPage.xaml---


<UserControl x:Class="SilverlightSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:shader="clr-namespace:Shazzam.Shaders"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
  <Grid x:Name="LayoutRoot" Loaded="StartTimer">
    <Image Source="Resource/back.jpg" Canvas.Left="0" Canvas.Top="0" >
      <Image.Effect>
        <shader:RasterScrollEffect Period="5.47" Amplitude="0.24" Offset="0" x:Name="Shader" />
      </Image.Effect>
    </Image>
  </Grid>
</UserControl>

9.MainPage.csを修正します。

---MainPage.cs---


using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SilverlightSample
{
    public partial class MainPage : UserControl
    {
        double Offset = 0.0;

        public MainPage()
        {
            InitializeComponent();
        }
        // タイマーの実装
        public void StartTimer(object o, RoutedEventArgs sender)
        {
            System.Windows.Threading.DispatcherTimer myDispatcherTimer = new System.Windows.Threading.DispatcherTimer();
            myDispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 1000 / 60); // 1000 / 60 ミリ秒ごとにイベントを発生させるようにする
            myDispatcherTimer.Tick += new EventHandler(Each_Tick);      // タイマーのイベントハンドラーを設定
            myDispatcherTimer.Start();                                  // タイマー開始
        }

        // タイマーイベント処理
        public void Each_Tick(object o, EventArgs sender)
        {
            Offset += 0.01;
            if (Offset >= 3.14 * 2 / Shader.Amplitude)
                Offset -= 3.14 * 2 / Shader.Amplitude;

            Shader.Offset = Offset;
        }
    }
}

コンパイルすれば、波の形状にゆがんだ背景画像がスクロールするアニメーションが表示されると思います。

さて、今回でSilverlightネタはいったん終了します。ですが、Silverlightには他にも色々機能があります。Silverlight 4 もリリースしたしね。まあ面白い機能が見つかったら再開するかもしれませんが、ひとまずこれにて。


Prev  Top  Next
inserted by FC2 system