Silverlight +拡張現実+シェーダー

みなさんこんにちは。



私はSilverlightでの作業が大好きで、最近Silverlightを使用して拡張現実に出会いました。 それについてとHabréについてはすでに書いており、かなり多くのことがブログに書かれていますが、それでも少し繰り返します。 拡張現実のアイデアは非常に興味深いですが、私はそれを何らかの形で使用したかったのです。 そして最近、手はピクセルシェーダーの研究に到達しました。 これをまとめようとするのは面白くなった。



もしそれがどうなったのか興味があるなら、猫へようこそ:





開始するには、 SLARToolkitをダウンロードしてください



ダウンロードしたアーカイブには、必要なライブラリと3つの既製のマーカーが含まれています。 独自のマーカーを作成するにはいくつかの方法がありますが、初心者には十分な既製のマーカーがあります。



次に、新しいSilverlightアプリケーションを作成し、ダウンロードしたアーカイブからSLARTooklit.dllおよびMatrix3DEx.dllへのリンクを追加します。



これが私のブランクのXAMLマークアップです


 <UserControl x:Class = "SilverlightForHabr.MainPage"
     xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
     xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
     mc:無視できる= "d"
     d:DesignHeight = "550" d:DesignWidth = "700">

     <Grid x:Name = "LayoutRoot" Background = "White">
         <StackPanel>
             <TextBlock Text = "シルバーライト+拡張現実+シェーダー" Horizo​​ntalAlignment = "Center" />
             <グリッド幅= "640"高さ= "480">
                 <長方形名= "ビューポート"ストローク= "黒" StrokeThickness = "2" />
                 <キャンバス>
                     <画像名= "ロゴ"ソース= "habr.png"幅= "300"高さ= "300" />
                 </キャンバス>
             </ Grid>
             <ボタンの内容=「始めましょう」パディング=「5」マージン=「5」Horizo​​ntalAlignment = "Center" />
         </ StackPanel>
     </ Grid>
 </ UserControl>




次に、カメラにアクセスし、カメラの画像を画面に表示する必要があります。

これは単純に行われます:



  1. CaptureSourceオブジェクトを作成する
  2. カメラを使用する許可をユーザーに求めます
  3. 写真を表示する




どこも簡単です。



これを行うには、XAMLで、ロード後に呼び出されるメソッドへのリンクとボタンクリックハンドラーへのリンクを追加します。



ロード済み= "UserControl_Loaded">
そして
 <ボタンの内容=「始めましょう」パディング=「5」マージン=「5」Horizo​​ntalAlignment =「中央」クリック=「onStartBtnClick」/>




メソッド自体を記述することは残っています。



 private void UserControl_Loaded(オブジェクト送信者、RoutedEventArgs e)
 {
       captureSource = new CaptureSource(); 
       captureSource.VideoCaptureDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();  //デフォルトでカメラに接続します
 
       var vidBrush = new VideoBrush();
       vidBrush.SetSource(captureSource);  //ブラシの場合、カメラからのビデオをソースとして指定します
       Viewport.Fill = vidBrush;  //長方形にブラシで描画します
 }

 private void onStartBtnClick(オブジェクト送信者、RoutedEventArgs e)
 {
       if(CaptureDeviceConfiguration.RequestDeviceAccess())//カメラで作業できるかどうかをユーザーに尋ねる
       {
           captureSource.Start(); //もしそうなら、行こう!
       }
 }




これで、カメラの画像が画面に表示されます。



拡張現実を使い始める




動作原理はほぼ次のとおりです。



  1. カメラからの着信ビデオのマーカーを検出するCaptureSourceMarkerDetectorクラスのインスタンスを作成します。
  2. 何かを見つけたら、ハンドラーを呼び出します
  3. マーカー自体の投影行列(空間内の位置)を決定します
  4. このマトリックスをマーカーの上にオーバーレイするオブジェクトに適用します




次のコードは、これらすべてのアクションを担当します。



 private void UserControl_Loaded(オブジェクト送信者、RoutedEventArgs e)
 {
       captureSource = new CaptureSource();
       captureSource.VideoCaptureDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();

       var vidBrush = new VideoBrush();
       vidBrush.SetSource(captureSource);
       Viewport.Fill = vidBrush;


       arDetector = new CaptureSourceMarkerDetector();
       var marker = Marker.LoadFromResource( "Marker_L_16x16segments_80width.pat"、16、16、80);
       arDetector.Initialize(captureSource、1、4000、マーカー);

       arDetector.MarkersDetected + =(s、me)=>
       {
           Dispatcher.BeginInvoke(()=>
           {
               var dr = me.DetectionResults;
               if(dr.HasResults)
               {
                   var centerAtOrigin = Matrix3DFactory.CreateTranslation(-Logo.ActualWidth * 0.5、-Logo.ActualHeight * 0.5、0);
                   var scale = Matrix3DFactory.CreateScale(0.5、-0.5、0.5);
                   var world = centerAtOrigin * scale * dr [0] .Transformation;

                    var vp = Matrix3DFactory.CreateViewportTransformation(Viewport.ActualWidth、Viewport.ActualHeight);
                    var m = Matrix3DFactory.CreateViewportProjection(world、Matrix3D.Identity、arDetector.Projection、vp);

                    Logo.Projection = new Matrix3DProjection {ProjectionMatrix = m};
               }
           });
       };
 }




そしてもちろん、マーカーをソリューションに追加します。 この場合、Marker_L_16x16segments_80width.patです。 [ビルドアクション]プロパティで、リソースを指定します。



あとは、選択したマーカーを印刷するだけです。 便宜上、SLARToolkitの開発者はPDFバージョンのマーカーを印刷用に配置しました。



開始すると、Habrのロゴがマーカーの上に重ねて表示されています。



画像



いいね!



シェーダー




一言で言えば、シェーダーはHLSL(高レベルシェーダー言語)で記述されたプログラムであり、すべてのアクションはピクセルの色または位置の変更に帰着します。



HLSLはCに似た言語であるため、それを理解するには最小限の時間が必要です。



Silverlightはピクセルシェーダーで動作します。 これはとても良いです ハードウェアアクセラレーションが有効になっている場合、シェーダーはグラフィックコアで実行されます。



シェーダーの作成を簡素化するプログラムがいくつかあります。 個人的には、Shazzamプログラムが一番好きでした。 結果を複数の画像やビデオですぐに表示でき、多くの例があり、最も重要なことは、1行のコードでシェーダーをプロジェクトに接続できるようにするC#またはVBクラスを生成することです。



だから、 サイトからShazzamをダウンロードしてください。

インストールして実行します。



既製のZoomBlurシェーダーを選んだのは、 必要なすべての入力パラメーター、つまりぼかしの程度とぼかしの基準となるポイントがあります。 この場合、このポイントはマーカーで示されます。



シェーダーコード




 /// <class> ZoomBlurEffect </ class>

 /// <description>入力に放射状のぼかしを適用する効果。</ description>

 // ------------------------------------------------ -----------------------------------------
 //シェーダー定数レジスタマッピング(スカラー-float、double、Point、Color、Point3Dなど)
 // ------------------------------------------------ -----------------------------------------

 /// <summary>ぼかしの中心</ summary>
 /// <minValue> 0 </ minValue>
 /// <maxValue> 0.2 </ maxValue>
 /// <defaultValue> 0.9,0.6 </ defaultValue>
 float2中央:レジスタ(C0);

 /// <summary>ぼかしの量</ summary>
 /// <minValue> 0 </ minValue>
 /// <maxValue> 0.2 </ maxValue>
 /// <defaultValue> 0.1 </ defaultValue>
 float BlurAmount:登録(C1);

 // ------------------------------------------------ --------------------------------------
 //サンプラー入力(ブラシ、ImplicitInputを含む)
 // ------------------------------------------------ --------------------------------------

 sampler2D inputSource:レジスタ(S0);

 // ------------------------------------------------ --------------------------------------
 //ピクセルシェーダー
 // ------------------------------------------------ --------------------------------------

 float4メイン(float2 uv:TEXCOORD):COLOR
 {
	 float4 c = 0;    
	 uv-=中央;

	 for(int i = 0; i <15; i ++)
     {
		 float scale = 1.0 + BlurAmount *(i / 14.0);
		 c + = tex2D(inputSource、uv * scale + Center);
	 }
   
	 c / = 15;
	 return c;
 }





Shazzamの結果はZoomBlur.psおよびZoomBlurEffect.csファイルです。 それらをプロジェクトに追加します。

最初のファイルは既製のシェーダーです。 2つ目は、シェーダーの使用を容易にする自動生成クラスです。



シェーダーを含む別のボタンを追加します。



  <Button Content = "Shaderを有効化" Name = "ShadersBtn" Padding = "5" Horizo​​ntalAlignment = "Center" Click = "SwitchOnShaders" /> 




コードにハンドラーを追加します。



 private void SwitchOnShaders(オブジェクト送信者、RoutedEventArgs e)
 {
     if(Viewport.Effect == zb)
     {
         Viewport.Effect = null;
         ShadersBtn.Content = "シェーダーを有効化";
        帰る
     }

     zb.Center = new Point();
     zb.BlurAmount = 0.2;

     Viewport.Effect = zb;
     ShadersBtn.Content = "シェーダーを無効にする";
            
 }




ここで、マーカーを移動するとぼかしが変わります。



あとがき


これらの技術の美しさは、あなたの想像力によってのみ制限されることですので、それらで遊んでみましょう。



リンク集


ダウンロード元へのリンク

仕組みを見る

SLARToolkit-拡張現実ゲームを開始するためのSDK

Shazzamは、SilverlightおよびWPFのシェーダーを快適に作成するためのアプリケーションです。



All Articles