TOP

ABOUT

PROGRAM

DIALY







HLSLを使ってみる!

 1.はじめに
 XNAで上位シェーダ言語(HLSL:Hight Level Shader Language)をさわってみます。




 2.HLSLを使ってみる!
 今回は座標変換して,頂点カラーをそのまま出力する単純なプログラムを組んでみます。
 まずは,テンプレートを使ってプロジェクトを作成しましょう。プロジェクトが作成できたら,エフェクトファイル(*.fx)を作ります。
 ソリューションエクスプローラーからContentを右クリックして,わかりやすいようにShaderというフォルダを作成します。(作らなくても全然かまいません)



 次に,作成したShaderフォルダを右クリックして,追加→新しい項目(W)を選択します。



すると次のようなダイアログボックスが出てきます。



Visual Studioにインストールされたテンプレートという項目の中からEffect Fileを選択し,ファイル名を入力して追加ボタンを押します。すると,次のように自動的にエフェクトファイルが作成されます。



あとは作成されたエフェクトファイルを自分の好きなようにいじっていけばいいだけです。


 3.GPUの処理
 作成されたエフェクトファイルを少し追加修正していきます。
 追加するのはVertexShaderInputとVertexShaderOutputにfloat4型のColorという変数を追加します。セマンティクスはCOLOR0にしておきます。
 あとは,VertexShaderFunctionに頂点色をそのままピクセルシェーダ側に送る処理を追加し,PixelShaderFunctionに頂点シェーダ側から送られてきた色をそのまま出力するように処理を変更します。
00001:  float4x4 World;
00002:  float4x4 View;
00003:  float4x4 Projection;
00004:  
00005:  // TODO: add effect parameters here.
00006:  
00007:  struct VertexShaderInput
00008:  {
00009:      float4 Position : POSITION0;
00010:  
00011:      // TODO: add input channels such as texture
00012:      // coordinates and vertex colors here.
00013:      float4 Color : COLOR0;
00014:  };
00015:  
00016:  struct VertexShaderOutput
00017:  {
00018:      float4 Position : POSITION0;
00019:  
00020:      // TODO: add vertex shader outputs such as colors and texture
00021:      // coordinates here. These values will automatically be interpolated
00022:      // over the triangle, and provided as input to your pixel shader.
00023:      float4 Color : COLOR0;
00024:  };
00025:  
00026:  VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
00027:  {
00028:      VertexShaderOutput output;
00029:  
00030:      float4 worldPosition = mul(input.Position, World);
00031:      float4 viewPosition = mul(worldPosition, View);
00032:      output.Position = mul(viewPosition, Projection);
00033:      output.Color = input.Color;
00034:  
00035:      // TODO: add your vertex shader code here.
00036:  
00037:      return output;
00038:  }
00039:  
00040:  float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
00041:  {
00042:      // TODO: add your pixel shader code here.
00043:  
00044:      return input.Color;
00045:  }
00046:  
00047:  technique Render
00048:  {
00049:      pass P0
00050:      {
00051:          // TODO: set renderstates here.
00052:  
00053:          VertexShader = compile vs_2_0 VertexShaderFunction();
00054:          PixelShader = compile ps_2_0 PixelShaderFunction();
00055:      }
00056:  }

 エフェクトファイルの処理は上のようになります。


 4.アプリケーション側の処理
 アプリケーション側の処理の流れはDirectXとほぼ同じです。
 アプリケーション側では,今まで使っていたBasicEffectの代わりにEffectを使用するように変更します。
00032:          // エフェクト
00033:          Effect effect;
 つぎに,InitializeEffect()メソッドを作成し,このメソッド内でエフェクトファイルの読み込みやテクニックのセットなど初期化を行う処理を追加します。
00085:          /// <summary>
00086:          /// エフェクトの初期化
00087:          /// </summary>
00088:          void InitializeEffect()
00089:          {
00090:              // エフェクトファイルの読み込み
00091:              effect = Content.Load<Effect>("Shader/sample");
00092:  
00093:              // テクニックをセット
00094:              effect.CurrentTechnique = effect.Techniques["Render"];
00095:          }
 あとは,エフェクトを開始する前にエフェクト側にパラメータを送ったりします。
00197:          /// <summary>
00198:          /// This is called when the game should draw itself.
00199:          /// </summary>
00200:          /// <param name="gameTime">Provides a snapshot of timing values.</param>
00201:          protected override void Draw(GameTime gameTime)
00202:          {
00203:              graphics.GraphicsDevice.Clear(bgColor);
00204:  
00205:              // TODO: Add your drawing code here
00206:  
00207:              // 頂点・インデックスバッファをセット
00208:              graphics.GraphicsDevice.VertexDeclaration = vertexDeclaration;
00209:              graphics.GraphicsDevice.Indices = indexBuffer;
00210:              graphics.GraphicsDevice.Vertices[0].SetSource(vertexBuffer, 0, VertexPositionColor.SizeInBytes);
00211:  
00212:              // パラメータをセット
00213:              effect.Parameters["Projection"].SetValue(projection);
00214:              effect.Parameters["View"].SetValue(view);
00215:              effect.Parameters["World"].SetValue(world);
00216:  
00217:              // 描画処理
00218:              effect.Begin();
00219:              foreach (EffectPass pass in effect.CurrentTechnique.Passes)
00220:              {
00221:                  pass.Begin();
00222:                  graphics.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, vertices.Length, 0, 12);
00223:                  pass.End();
00224:              }
00225:              effect.End();
00226:  
00227:              base.Draw(gameTime);
00228:          }
00229:      }
 DirectXとほぼ同じですね。これでHLSLもようやく触っていくことができるようになりました。


 Download
本ソースコードおよびプログラムを使用したことによる如何なる損害も製作者は責任を負いません。
本ソースコードおよびプログラムは自己責任でご使用ください。
プログラムの作成にはMicrosoft Visual Studio 2005 SP1 Professional, XNA Game Studio 2.0を用いています。