<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>ひにけにXNA : シェーダーモデル 3.0</title><link>http://blogs.msdn.com/ito/archive/tags/_B730A730FC30C030FC30E230C730EB30_+3.0/default.aspx</link><description>Tags: シェーダーモデル 3.0</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>頂点テクスチャでスキンアニメーション</title><link>http://blogs.msdn.com/ito/archive/2009/05/07/more-bones-07.aspx</link><pubDate>Fri, 08 May 2009 05:48:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9595632</guid><dc:creator>Yuichi Ito</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/ito/comments/9595632.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ito/commentrss.aspx?PostID=9595632</wfw:commentRss><description>&lt;p&gt;2009/06/25 追記: XNA GS 3.1用のサンプルを &lt;a href="http://higeneko.net/hinikeni/sample/xna31/TexSkinningSample.zip"&gt;http://higeneko.net/hinikeni/sample/xna31/TexSkinningSample.zip&lt;/a&gt;にアップしました。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;頂点テクスチャでスキンアニメーション、その2:頂点テクスチャでスキンアニメーション&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;今回は頂点テクスチャを使ったスキンアニメーションの実装方法を紹介します。&lt;/p&gt;  &lt;p&gt;XNA Game Studio 3.0で動作するサンプルを用意しました。基本的に&lt;a href="http://creators.xna.com/en-US/sample/skinnedmodel" target="_blank"&gt;Skinned Model&lt;/a&gt;サンプルと同じ使い方です。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://higeneko.net/hinikeni/sample/TexSkinningSample.zip" mce_href="http://higeneko.net/hinikeni/sample/TexSkinningSample.zip"&gt;http://higeneko.net/hinikeni/sample/TexSkinningSample.zip&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;今回のサンプルは前々回の&lt;a href="http://blogs.msdn.com/ito/archive/2009/05/05/more-bones-05.aspx" target="_blank"&gt;「クォータニオンでスキンアニメーション」&lt;/a&gt;のサンプルプログラムに以下の変更を加えたものです。&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;AnimationPlayerの変更 &lt;/li&gt;    &lt;li&gt;頂点テクスチャの生成 &lt;/li&gt;    &lt;li&gt;シェーダーの変更 &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;頂点テクスチャフォーマットを決める&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;まずは、頂点テクスチャにどのようにボーンデータを格納するか決めます。ボーンの回転部分のクォータニオンはVector4と同じフォーマットなのでSurfaceFormat.Vector4が使えます。平行移動にはVector3を使っていますが、頂点テクスチャのフォーマットにはVector3が無いのでちょっともったいないですがSurfaceFormat.Vector4を使用します。&lt;/p&gt;  &lt;p&gt;今回のサンプルでは、回転部分と平行移動部分を2つの頂点テクスチャに別々に格納しています。ひとつのテクセルにひとつのボーン情報を格納しているので、頂点テクスチャのサイズは横がボーン数、縦が1となっています。 &lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="tex-bone" border="0" alt="tex-bone" src="http://blogs.msdn.com/blogfiles/ito/WindowsLiveWriter/morebones07_F45C/tex-bone_3.png" width="600" height="160" mce_src="http://blogs.msdn.com/blogfiles/ito/WindowsLiveWriter/morebones07_F45C/tex-bone_3.png" /&gt;&lt;/p&gt;  &lt;p&gt;頂点テクスチャのサンプラーは4つしかないので、2つの頂点テクスチャを使うのが厳しい場合は以下のように、2つのテクセルにひとつのボーン情報をまとめて格納するといいでしょう。この場合、頂点テクスチャのサイズは横がボーン数×2、縦が1となります。&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="tex-bone-02" border="0" alt="tex-bone-02" src="http://blogs.msdn.com/blogfiles/ito/WindowsLiveWriter/morebones07_F45C/tex-bone-02_3.png" width="600" height="67" mce_src="http://blogs.msdn.com/blogfiles/ito/WindowsLiveWriter/morebones07_F45C/tex-bone-02_3.png" /&gt;&lt;/p&gt;  &lt;p&gt;頂点テクスチャが使うメモリサイズを節約するという観点では前者の回転部分と平行移動部分を別々の頂点テクスチャで持つほうが有利です。これはクォータニオンの4要素の値の範囲は-1～+1なので、SurfaceFormat.Vector4の代わりにSurfaceFormat.HalfVector4やSurfaceFormat.NormalizedShort4を使うことでメモリ使用量を半分にすることができるからです。また、通常のキャラクターアニメーションでは平行移動部分も大きな値を使用しないのでSurfaceFormat.HalfVector4を使って更にメモリ使用量を減らすこともできるでしょう。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;AnimationPlayerの変更 &lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;機能的には前々回のサンプルとまったく同じなのですが、頂点テクスチャへの格納フォーマットがVector4に変わったので、それに合わせてSkinTranslationsの型もVector3[]からVector4[]に変更します。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;頂点テクスチャの生成&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;まずは、使用する頂点テクスチャ(ボーン用の頂点テクスチャなので、ボーンテクスチャと呼びます)の宣言をします。フレーム毎にボーン情報をボーンテクスチャへ書き込むわけですが、&lt;a href="http://blogs.msdn.com/ito/archive/2009/03/25/how-gpus-works-01.aspx" target="_blank"&gt;「GPUはいつ描画するのか？」&lt;/a&gt;で解説したように、同じテクスチャに続けて書き込むとGPUの処理とバッティングしてしまうということに注意が必要です。&lt;/p&gt;  &lt;p&gt;そこで、それぞれ複数の頂点テクスチャを生成して切り替えながら使う必要があります。この実装は非常に単純でTexture2Dの配列と、現在使用するテクスチャのインデックスを用意するだけでいいのですが、使用する頂点テクスチャが増えてくると余計な変数が増えてきて、コードの可読性が低くなり、ミスも起きやすくなってしまいます。そういった理由から、ここでは複数のテクスチャを切り替える機能をもったFlipTexture2Dというクラスを作ります。&lt;/p&gt;  &lt;p&gt;FlipTexture2DクラスはTexture2Dと同様のコンストラクタを持ち、内部で複数のテクスチャを作り、Flipメソッドで使うテクスチャを切り替え、Textureプロパティで現在のテクスチャを返すようになっています。&lt;/p&gt;  &lt;pre class="code"&gt;    &lt;span style="color: green"&gt;// ボーン情報を格納するテクスチャ
    &lt;/span&gt;&lt;span style="color: #2b91af"&gt;FlipTexture2D &lt;/span&gt;rotationTexture;      &lt;span style="color: green"&gt;// ボーンの回転部分を格納するテクスチャ
    &lt;/span&gt;&lt;span style="color: #2b91af"&gt;FlipTexture2D &lt;/span&gt;translationTexture;   &lt;span style="color: green"&gt;// ボーンの平行移動部分を格納するテクスチャ

&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;ボーンテクスチャの生成は前述のように、横がボーン数、縦が1のサイズのテクスチャを作ります。ここでTextureUsageを&lt;strong&gt;TextureUsage.Linear&lt;/strong&gt;を指定していることに注意してください。通常のテクスチャはピクセルシェーダー内でフェッチされることを前提としており、その用途に適しているTextureUsage.Tilingを使用するようになっています。TextureUsage.Noneを設定しても、テクスチャサイズがタイリングに適している場合は自動的にタイリングを使うようになっています。&lt;/p&gt;

&lt;p&gt;通常のレンダリング時には極力タイリングを使うべきですが、SetDataを呼び出したときに通常のフォーマットからタイリングフォーマットへの変換がCPUによって行われます。&lt;/p&gt;

&lt;p&gt;今回はボーンテクスチャとして使用するので、タイリングを使う必要がないこと、SetData時にタイリングフォーマット変換に掛かる時間を節約したいという二点の理由から、TextureUsage.Linearを指定します。 &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;// 頂点テクスチャの生成
&lt;/span&gt;&lt;span style="color: blue"&gt;int &lt;/span&gt;width = animationPlayer.GetSkinRotations().Length;
&lt;span style="color: blue"&gt;int &lt;/span&gt;height = 1;

rotationTexture = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;FlipTexture2D&lt;/span&gt;( GraphicsDevice, width, height, 1,
                        &lt;span style="color: #2b91af"&gt;TextureUsage&lt;/span&gt;.Linear, &lt;span style="color: #2b91af"&gt;SurfaceFormat&lt;/span&gt;.Vector4 );

translationTexture = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;FlipTexture2D&lt;/span&gt;( GraphicsDevice, width, height, 1,
                        &lt;span style="color: #2b91af"&gt;TextureUsage&lt;/span&gt;.Linear, &lt;span style="color: #2b91af"&gt;SurfaceFormat&lt;/span&gt;.Vector4 );&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;こうして作ったボーンテクスチャにanimationPlayerで生成したSkinRotationsとSkinTranslationsをSetData&amp;lt;T&amp;gt;を使って書き込みます。ここではFlipTexture2D.Flipメソッドを呼び出すことで書き込むテクスチャを切り替えてから書き出します。&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;// ボーンのクォータニオンと平行移動部分を取得し頂点テクスチャに書き込み
&lt;/span&gt;rotationTexture.Flip();
translationTexture.Flip();

rotationTexture.Texture.SetData&amp;lt;&lt;span style="color: #2b91af"&gt;Quaternion&lt;/span&gt;&amp;gt;( animationPlayer.GetSkinRotations() );
translationTexture.Texture.SetData&amp;lt;&lt;span style="color: #2b91af"&gt;Vector4&lt;/span&gt;&amp;gt;( animationPlayer.GetSkinTraslations() );&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;頂点シェーダー内で頂点テクスチャをフェッチする場合に指定するのはテクスチャ座標なので、ボーン番号からテクスチャ座標に変換するために必要な&lt;strong&gt;textureSize&lt;/strong&gt;を設定します。&lt;/p&gt;

&lt;p&gt;実際の描画コードは以下のようになっています、通常の描画コードにrotationTexture、traslationTexture、そしてtextureSizeを設定するコードが追加しただけです。&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #2b91af"&gt;Vector2 &lt;/span&gt;textureSize = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Vector2&lt;/span&gt;( rotationTexture.Texture.Width,
                                    rotationTexture.Texture.Height );

&lt;span style="color: blue"&gt;foreach &lt;/span&gt;( &lt;span style="color: #2b91af"&gt;ModelMesh &lt;/span&gt;mesh &lt;span style="color: blue"&gt;in &lt;/span&gt;currentModel.Meshes )
{
    &lt;span style="color: blue"&gt;foreach &lt;/span&gt;( &lt;span style="color: #2b91af"&gt;Effect &lt;/span&gt;effect &lt;span style="color: blue"&gt;in &lt;/span&gt;mesh.Effects )
    {
        effect.Parameters[&lt;span style="color: #a31515"&gt;&amp;quot;BoneRotationTexture&amp;quot;&lt;/span&gt;].SetValue(
                                            rotationTexture.Texture );
        effect.Parameters[&lt;span style="color: #a31515"&gt;&amp;quot;BoneTranslationTexture&amp;quot;&lt;/span&gt;].SetValue(
                                            translationTexture.Texture );

        effect.Parameters[&lt;span style="color: #a31515"&gt;&amp;quot;BoneTextureSize&amp;quot;&lt;/span&gt;].SetValue( textureSize );
        effect.Parameters[&lt;span style="color: #a31515"&gt;&amp;quot;World&amp;quot;&lt;/span&gt;].SetValue( world );
        effect.Parameters[&lt;span style="color: #a31515"&gt;&amp;quot;View&amp;quot;&lt;/span&gt;].SetValue( view );
        effect.Parameters[&lt;span style="color: #a31515"&gt;&amp;quot;Projection&amp;quot;&lt;/span&gt;].SetValue( projection );
    }

    mesh.Draw();
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&lt;strong&gt;シェーダーの変更&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;シェーダー内での頂点テクスチャの宣言は通常のテクスチャと殆ど変わりありませんが、殆どのGPUでは浮動小数点テクスチャのバイリニアフィルタリングが利かないのと、正しいフィルター設定しないとフェッチができないものが多いので、ここではポイントサンプリング、ミップマップなし、テクスチャのアドレッシングをクランプに設定しています。&lt;/p&gt;

&lt;p&gt;また、このコードでは&lt;strong&gt;register(vs, s0)&lt;/strong&gt;というレジスタ宣言をして明示的に頂点テクスチャを任意のサンプラーに割り当てています。この宣言は必ずしも必要はありませんが、複数のエフェクトで同じ定数を共有したい場合にsharedを指定すると、コンパイラはサンプラーが通常のテクスチャなのか頂点テクスチャなのかを判断することができなってしまうので、registerを使って指定する必要があります。 &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;//-----------------------------------------------------------------------------
// 頂点テクスチャ用の定数レジスタ宣言
//=============================================================================
&lt;/span&gt;&lt;span style="color: blue"&gt;float2 &lt;/span&gt;BoneTextureSize;    &lt;span style="color: green"&gt;// ボーン用頂点テクスチャのサイズ

// ボーン用頂点テクスチャサンプラー宣言
&lt;/span&gt;&lt;span style="color: blue"&gt;texture &lt;/span&gt;BoneRotationTexture;

&lt;span style="color: blue"&gt;sampler &lt;/span&gt;BoneRotationSampler : &lt;span style="color: blue"&gt;register&lt;/span&gt;(vs,s0) = &lt;span style="color: blue"&gt;sampler_state
&lt;/span&gt;{
    &lt;span style="color: blue"&gt;Texture &lt;/span&gt;= (BoneRotationTexture);
    &lt;span style="color: green"&gt;// 殆どのGPUでは以下のようなステート設定にしないと
    // 頂点テクスチャのフェッチがうまくいかない
    &lt;/span&gt;&lt;span style="color: blue"&gt;MinFilter &lt;/span&gt;= Point;
    &lt;span style="color: blue"&gt;MagFilter &lt;/span&gt;= Point;
    &lt;span style="color: blue"&gt;MipFilter &lt;/span&gt;= &lt;span style="color: navy"&gt;None&lt;/span&gt;;
    &lt;span style="color: blue"&gt;AddressU &lt;/span&gt;= Clamp;
    &lt;span style="color: blue"&gt;AddressV &lt;/span&gt;= Clamp;
};

&lt;span style="color: blue"&gt;texture &lt;/span&gt;BoneTranslationTexture;

&lt;span style="color: blue"&gt;sampler &lt;/span&gt;BoneTranslationSampler : &lt;span style="color: blue"&gt;register&lt;/span&gt;(vs,s1) = &lt;span style="color: blue"&gt;sampler_state
&lt;/span&gt;{
    &lt;span style="color: blue"&gt;Texture &lt;/span&gt;= (BoneTranslationTexture);
    &lt;span style="color: green"&gt;// 殆どのGPUでは以下のようなステート設定にしないと
    // 頂点テクスチャのフェッチがうまくいかない
    &lt;/span&gt;&lt;span style="color: blue"&gt;MinFilter &lt;/span&gt;= Point;
    &lt;span style="color: blue"&gt;MagFilter &lt;/span&gt;= Point;
    &lt;span style="color: blue"&gt;MipFilter &lt;/span&gt;= &lt;span style="color: navy"&gt;None&lt;/span&gt;;
    &lt;span style="color: blue"&gt;AddressU &lt;/span&gt;= Clamp;
    &lt;span style="color: blue"&gt;AddressV &lt;/span&gt;= Clamp;
};&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;続いてボーン情報をボーンテクスチャからフェッチします。頂点テクスチャのフェッチには&lt;strong&gt;tex2Dlod&lt;/strong&gt;を使います。tex2Dlodにはfloat4値を渡し、x,y,zにはテクスチャ座標のu,v,wを、wにはミップマップレベルを指定します。ピクセルシェーダー内でおなじみのtex2Dが頂点シェーダー内で使えない理由はピクセルシェーダー内ではハードウェアが自動的にミップマップレベルを計算してくれますが、頂点シェーダー内ではミップマップレベルを自動的に計算することができないからです。ですから、tex2Dlodを使用してミップマップレベルを指定する必要があります。&lt;/p&gt;

&lt;p&gt;4つのボーンインデックスから計算したテクスチャ座標を使ってそれぞれのボーン情報をフェッチして、&lt;a href="http://blogs.msdn.com/ito/archive/2009/05/05/more-bones-05.aspx" target="_blank"&gt;前々回のサンプル&lt;/a&gt;で作ったCreateTransformFromQuaternionTransformsメソッドを使ってskinTransformを計算します。&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;//-----------------------------------------------------------------------------
// 頂点テクスチャからボーン情報のフェッチ
//=============================================================================
&lt;/span&gt;&lt;span style="color: blue"&gt;float4x4 &lt;/span&gt;CreateTransformFromBoneTexture( &lt;span style="color: blue"&gt;float4 &lt;/span&gt;boneIndices, &lt;span style="color: blue"&gt;float4 &lt;/span&gt;boneWeights )
{
    &lt;span style="color: blue"&gt;float2 &lt;/span&gt;uv = 1.0f / BoneTextureSize;
    uv.y *= 0.5f;
    &lt;span style="color: blue"&gt;float4 &lt;/span&gt;texCoord0 = &lt;span style="color: blue"&gt;float4&lt;/span&gt;( ( 0.5f + boneIndices.x ) * uv.x, uv.y, 0, 1 );
    &lt;span style="color: blue"&gt;float4 &lt;/span&gt;texCoord1 = &lt;span style="color: blue"&gt;float4&lt;/span&gt;( ( 0.5f + boneIndices.y ) * uv.x, uv.y, 0, 1 );
    &lt;span style="color: blue"&gt;float4 &lt;/span&gt;texCoord2 = &lt;span style="color: blue"&gt;float4&lt;/span&gt;( ( 0.5f + boneIndices.z ) * uv.x, uv.y, 0, 1 );
    &lt;span style="color: blue"&gt;float4 &lt;/span&gt;texCoord3 = &lt;span style="color: blue"&gt;float4&lt;/span&gt;( ( 0.5f + boneIndices.w ) * uv.x, uv.y, 0, 1 );

    &lt;span style="color: green"&gt;// 回転部分のフェッチ
    &lt;/span&gt;&lt;span style="color: blue"&gt;float4 &lt;/span&gt;q1 = &lt;span style="color: blue"&gt;tex2Dlod&lt;/span&gt;( BoneRotationSampler, texCoord0 );
    &lt;span style="color: blue"&gt;float4 &lt;/span&gt;q2 = &lt;span style="color: blue"&gt;tex2Dlod&lt;/span&gt;( BoneRotationSampler, texCoord1 );
    &lt;span style="color: blue"&gt;float4 &lt;/span&gt;q3 = &lt;span style="color: blue"&gt;tex2Dlod&lt;/span&gt;( BoneRotationSampler, texCoord2 );
    &lt;span style="color: blue"&gt;float4 &lt;/span&gt;q4 = &lt;span style="color: blue"&gt;tex2Dlod&lt;/span&gt;( BoneRotationSampler, texCoord3 );

    &lt;span style="color: green"&gt;// 平行移動部分のフェッチ
    &lt;/span&gt;&lt;span style="color: blue"&gt;float4 &lt;/span&gt;t1 = &lt;span style="color: blue"&gt;tex2Dlod&lt;/span&gt;( BoneTranslationSampler, texCoord0 );
    &lt;span style="color: blue"&gt;float4 &lt;/span&gt;t2 = &lt;span style="color: blue"&gt;tex2Dlod&lt;/span&gt;( BoneTranslationSampler, texCoord1 );
    &lt;span style="color: blue"&gt;float4 &lt;/span&gt;t3 = &lt;span style="color: blue"&gt;tex2Dlod&lt;/span&gt;( BoneTranslationSampler, texCoord2 );
    &lt;span style="color: blue"&gt;float4 &lt;/span&gt;t4 = &lt;span style="color: blue"&gt;tex2Dlod&lt;/span&gt;( BoneTranslationSampler, texCoord3 );
    
    &lt;span style="color: blue"&gt;return &lt;/span&gt;CreateTransformFromQuaternionTransforms(
                    q1, t1,
                    q2, t2,
                    q3, t3,
                    q4, t4,
                    boneWeights );
}&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;頂点シェーダー本体のコードは以下のようになります。前々回のサンプルではCreateTransformFromQuaternionTransformsを呼んでいた部分がCreateTransformFromBoneTextureに変わっただけです。&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;//-----------------------------------------------------------------------------
// 頂点シェーダー
//=============================================================================
&lt;/span&gt;&lt;span style="color: blue"&gt;VS_OUTPUT &lt;/span&gt;&lt;span style="color: maroon"&gt;VertexShader&lt;/span&gt;(&lt;span style="color: blue"&gt;VS_INPUT &lt;/span&gt;input)
{
    &lt;span style="color: blue"&gt;VS_OUTPUT &lt;/span&gt;output;
    
    &lt;span style="color: green"&gt;// スキン変換行列の取得
    &lt;/span&gt;&lt;span style="color: blue"&gt;float4x4 &lt;/span&gt;skinTransform =
                CreateTransformFromBoneTexture( input.BoneIndices, input.BoneWeights );
            
    skinTransform = &lt;span style="color: blue"&gt;mul&lt;/span&gt;( skinTransform, World );
  
    &lt;span style="color: green"&gt;// 頂点変換
    &lt;/span&gt;&lt;span style="color: blue"&gt;float4 &lt;/span&gt;position = &lt;span style="color: blue"&gt;mul&lt;/span&gt;(input.Position, skinTransform);
    output.Position = &lt;span style="color: blue"&gt;mul&lt;/span&gt;(&lt;span style="color: blue"&gt;mul&lt;/span&gt;(position, View), Projection);

    &lt;span style="color: green"&gt;// 法線変換
    &lt;/span&gt;&lt;span style="color: blue"&gt;float3 &lt;/span&gt;normal = &lt;span style="color: blue"&gt;normalize&lt;/span&gt;( &lt;span style="color: blue"&gt;mul&lt;/span&gt;( input.Normal, skinTransform));
    
    &lt;span style="color: blue"&gt;float3 &lt;/span&gt;light1 = &lt;span style="color: blue"&gt;max&lt;/span&gt;(&lt;span style="color: blue"&gt;dot&lt;/span&gt;(normal, Light1Direction), 0) * Light1Color;
    &lt;span style="color: blue"&gt;float3 &lt;/span&gt;light2 = &lt;span style="color: blue"&gt;max&lt;/span&gt;(&lt;span style="color: blue"&gt;dot&lt;/span&gt;(normal, Light2Direction), 0) * Light2Color;

    output.Lighting = light1 + light2 + AmbientColor;

    output.TexCoord = input.TexCoord;
    
    &lt;span style="color: blue"&gt;return &lt;/span&gt;output;
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;定数レジスタがいらなくなった&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ボーン情報を頂点テクスチャから読み込んでいるので、定数レジスタの数制限からくるボーン数制限がなくなりました。ただし、XNAフレームワークのコンテント・パイプラインで変換されるボーンインデックスは最大256個までとなっているので、最大ボーン数は256個になります。もちろん、コンテント・パイプラインを拡張して出力するボーンインデックスのフォーマットを変更すれば更に多くのボーンを使うこともできますが、256個以上のボーンが必要になるケースというのはあるのでしょうか？&lt;/p&gt;

&lt;p&gt;これでオリジナルのサンプルでは59個から4倍以上のボーン数を使えるようになりました。定数レジスタを必要としないので、余った定数レジスタは他の用途に使うことができます。&lt;/p&gt;

&lt;p&gt;PC上ではシェーダーモデル3.0以上のビデオカードが必要になりますが、Xbox 360上では問題なく動くし、この手法を活用できる場面(近日中の記事で紹介予定)も多いので、魅力的な手法ではないでしょうか？&lt;/p&gt;

&lt;p&gt;今回の手法で使えるボーン数が上限にまで達しましたが、次回はXbox 360専用の機能であるvFetchを使った手法を紹介したいと思います。&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9595632" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ito/archive/tags/XNA+_D530EC30FC30E030EF30FC30AF30_/default.aspx">XNA フレームワーク</category><category domain="http://blogs.msdn.com/ito/archive/tags/_B030E930D530A330AF30B930_/default.aspx">グラフィクス</category><category domain="http://blogs.msdn.com/ito/archive/tags/_B730A730FC30C030FC30E230C730EB30_+3.0/default.aspx">シェーダーモデル 3.0</category></item><item><title>頂点テクスチャってなに？</title><link>http://blogs.msdn.com/ito/archive/2009/05/06/more-bones-06.aspx</link><pubDate>Thu, 07 May 2009 05:01:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9592570</guid><dc:creator>Yuichi Ito</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/ito/comments/9592570.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ito/commentrss.aspx?PostID=9592570</wfw:commentRss><description>&lt;P&gt;&lt;STRONG&gt;頂点テクスチャでスキンアニメーション、その1:頂点テクスチャってなに？&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;前回紹介したクォータニオンを使ったスキンアニメーションの実装方法はシェーダーモデル2.0では最も多くのボーン数を使うことができる手法です。この手法を使うことでオリジナルのスキンアニメーションサンプルでは59個だった最大ボーン数が、二倍近い117個になりました。&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;もっと多くのボーン数を使える手法はないのでしょうか？&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;残念ながら、シェーダーモデル2.0ではここが限界ですが、シェーダーモデル3.0から追加された機能を使うことで更に多くのボーンを使うことができます。&lt;/P&gt;
&lt;P&gt;使う機能とは以下の二つです。&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;頂点テクスチャ &lt;/LI&gt;
&lt;LI&gt;浮動小数点テクスチャ &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;頂点テクスチャは、その名のとおり頂点シェーダー内でテクスチャデータをフェッチ(読み込み)できる機能です。&lt;A href="http://developer.nvidia.com/object/using_vertex_textures.html" target=_blank mce_href="http://developer.nvidia.com/object/using_vertex_textures.html"&gt;発表当時(2004年)のデモ&lt;/A&gt;では波のシミュレーションをピクセルシェーダーで行い、その結果を頂点テクスチャとして使うことで、立体的な波を表現していました。&lt;/P&gt;
&lt;P align=center&gt;&lt;A href="http://blogs.msdn.com/blogfiles/ito/WindowsLiveWriter/2a8b1dc41502_E060/itoxe1-29_4.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/ito/WindowsLiveWriter/2a8b1dc41502_E060/itoxe1-29_4.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title="XNA Field" border=0 alt="XNA Field" src="http://blogs.msdn.com/blogfiles/ito/WindowsLiveWriter/2a8b1dc41502_E060/itoxe1-29_thumb_1.png" width=244 height=139 mce_src="http://blogs.msdn.com/blogfiles/ito/WindowsLiveWriter/2a8b1dc41502_E060/itoxe1-29_thumb_1.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;また、XNA GSE 1.0のXNA Fieldデモではマルチスレッドでリアルタイムにフラクタル生成した結果を頂点テクスチャとして使用して地形モデルを表示していました。&lt;/P&gt;
&lt;P&gt;実際のゲームでも、&lt;A href="http://game.watch.impress.co.jp/docs/20061025/3dvf5.htm" target=_blank mce_href="http://game.watch.impress.co.jp/docs/20061025/3dvf5.htm"&gt;バーチャファイター5&lt;/A&gt;では水面と雪原、フォグなどの表現で頂点テクスチャは使われています。&lt;/P&gt;
&lt;P&gt;頂点テクスチャの特徴としては&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;頂点シェーダー内で最大4種類のテクスチャをフェッチできる &lt;/LI&gt;
&lt;LI&gt;任意のテクスチャ座標から複数回の読み込みができる &lt;/LI&gt;
&lt;LI&gt;浮動小数点テクスチャと組み合わせることでさまざまなデータを扱うことができる &lt;/LI&gt;
&lt;LI&gt;定数レジスタに比べて大量のデータを扱うことができる &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;が、あります。&lt;/P&gt;
&lt;P&gt;普段、テクスチャというと色情報が入った画像を使いますが、0-255の範囲の数値として扱うことで色以外の情報を格納するのにも使えます。これに加えてシェーダーモデル3.0から採用された浮動小数点テクスチャを使うことで、色以外の情報を格納するのが更に容易になりました。&lt;/P&gt;
&lt;P&gt;また、頂点テクスチャの読み込みはピクセルシェーダー内でのテクスチャの読み込みと同様に自由にテクスチャ座標を指定することができ、複数回読み込むことができます。&lt;/P&gt;
&lt;P&gt;これらの特徴を利用して、画像情報以外のデータを入れたテクスチャから自由にデータを読み込むことで頂点テクスチャを定数レジスタの変わりとして使うことができます。定数レジスタ数が256だったのに対して、頂点テクスチャでは大量のデータを格納することができます。例えば2,048x2,048のテクスチャは定数レジスタ数に換算すると400万という膨大な数のデータを格納することができます。&lt;/P&gt;
&lt;P&gt;このように頂点テクスチャは非常に魅力的な機能ですが、弱点もあります。&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;対応しているGPUはまだ少ない、対応していても動作が遅いものが少なくない&lt;/LI&gt;
&lt;LI&gt;浮動小数点テクスチャではフィルタリングが使えないものが殆ど &lt;/LI&gt;
&lt;LI&gt;テクスチャに格納できる要素数が1,2,4と限定されている &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;頂点テクスチャは最近のGPUでは当たり前のようについている機能ですが、まだ対応していないGPUの数も多く、ピクセルシェーダー内でテクスチャフェッチをするのに比べて速度的に劣る場合が多いです。&lt;/P&gt;
&lt;P&gt;また、頂点テクスチャで使用されるテクスチャはその性質上、浮動小数点テクスチャを使うことが多いのですが、Direct X 9.0世代の殆どのGPUでは浮動小数点テクスチャに対してのバイリニアなどのフィルタリングができないものが殆どです。しかも、できないだけなら良いのですが、テクスチャフィルタを設定した状態でフェッチするとでたらめな数値を返してきたりするので、正しいフィルタリング設定をせずに頂点テクスチャを使ってしまい、自分のプログラムが正しく動作しているかどうかを時間を掛けて調べたあげく、見つけた原因が単純にフィルタリング設定のミスだったなんてことがあります。&lt;/P&gt;
&lt;P&gt;頂点バッファで使われる代表的な型といえばVector3ですが、残念ながら頂点テクスチャではVector3は使えません。浮動小数点型で使えるのはSingle、Vector2、そしてVector4だけです。これはテクスチャのテクセルサイズには16ビット、32ビット、64ビット、そして128ビットの組み合わせしか指定できないのが原因です。&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;頂点テクスチャを使おう&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;以上のように、頂点テクスチャは魅力的な機能なのですが、使えるGPUの少なさから今まではおまけ的な機能として使われることが殆どでした。ですが、最近では使えるGPUの数も増えてきたので有効活用するケースも増えてきました。特にXbox 360やPS3はどちらも頂点テクスチャをサポートしていて、使っていると思われるタイトルも見かけるようになりました。&lt;/P&gt;
&lt;P&gt;次回は、この頂点テクスチャを使ったスキンアニメーションの実装例を紹介します。&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9592570" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ito/archive/tags/_B030E930D530A330AF30B930_/default.aspx">グラフィクス</category><category domain="http://blogs.msdn.com/ito/archive/tags/_B730A730FC30C030FC30E230C730EB30_+3.0/default.aspx">シェーダーモデル 3.0</category></item><item><title>Gamefest Japan 2008 デモプログラム</title><link>http://blogs.msdn.com/ito/archive/2008/12/12/gamefest-japan-2008-demo.aspx</link><pubDate>Fri, 12 Dec 2008 15:20:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9201966</guid><dc:creator>Yuichi Ito</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.msdn.com/ito/comments/9201966.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ito/commentrss.aspx?PostID=9201966</wfw:commentRss><description>&lt;p&gt;2009/06/25 追記: XNA GS 3.1用のサンプルを &lt;a href="http://higeneko.net/hinikeni/sample/xna31/GamefestJapan2008Demo.zip"&gt;http://higeneko.net/hinikeni/sample/xna31/GamefestJapan2008Demo.zip&lt;/a&gt;にアップしました&lt;/p&gt;  &lt;p&gt;2008/12/26 追記: デモプログラムの更新、キーボード入力で操作できるようになりました。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;やっと終わりました&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;今年の９月に行われたGamefest Japan 2008のプレゼンテーション資料が先月公開されました。&lt;/p&gt;  &lt;p&gt;&lt;a title="http://msdn.microsoft.com/ja-jp/xna/cc723908.aspx" href="http://msdn.microsoft.com/ja-jp/xna/cc723908.aspx" target="_blank" mce_href="http://msdn.microsoft.com/ja-jp/xna/cc723908.aspx"&gt;http://msdn.microsoft.com/ja-jp/xna/cc723908.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;私も僭越ながら２つのセッションを担当させて頂き、そのプレゼンテーション資料も公開されています。XNA Game Studioでのゲーム開発においてのパフォーマンス改善について戦略的手法と実践的な手法、主にシステムレベルでの最適化の効果の程を紹介させていただきました。&lt;/p&gt;  &lt;p&gt;&lt;a title="http://download.microsoft.com/download/0/4/2/04291420-033b-4f46-b87d-de64a2dc6bac/X5.zip" href="http://download.microsoft.com/download/0/4/2/04291420-033b-4f46-b87d-de64a2dc6bac/X5.zip" mce_href="http://download.microsoft.com/download/0/4/2/04291420-033b-4f46-b87d-de64a2dc6bac/X5.zip"&gt;http://download.microsoft.com/download/0/4/2/04291420-033b-4f46-b87d-de64a2dc6bac/X5.zip&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;本当はプレゼン時にサンプルプログラムの配布したかったのですが、本業の方のXNA Framework作業の方が佳境の最中で、その合間に書いたコードだったので非常に汚いコードであったのと、先月のXNA Game Studio 3.0のリリースまでその忙しさが続いたので、なかなか公開することができませんでした。っていうか、コメントを追加するのは当然として、他にも3.0対応にしたり、再利用可能なコンポーネントを使いやすく書き換えたりして、発表時のコードよりも4,000行近く増えてしまったのも、今まで時間が掛かった原因でした。&lt;/p&gt;  &lt;p&gt;ともかく、なんとか人に見せられる程度の体裁は整えたので、デモプログラムを公開します。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://higeneko.net/hinikeni/sample/GamefestJapan2008Demo.zip" mce_href="http://higeneko.net/hinikeni/sample/GamefestJapan2008Demo.zip"&gt;http://higeneko.net/hinikeni/sample/GamefestJapan2008Demo.zip&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;解凍したフォルダの中には以下の３つのソリューションファイルがあるので、好きなソリューションファイルを使ってください。いずれのプロジェクトを開くのにもXNA Game Studio 3.0が必要です。また、Windowsで実行するにはシェーダーモデル2.0以上のビデオカードが必須になります。&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;DemoWin.sln      &lt;ul&gt;       &lt;li&gt;Windows用のソリューションファイル &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;DemoXbox.sln      &lt;ul&gt;       &lt;li&gt;Xbox 360用のソリューションファイル &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;Demo.sln      &lt;ul&gt;       &lt;li&gt;Windows/Xbox 360の両方のプロジェクトが入ったソリューションファイル &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;フォントは私がプログラムする時に使っている等幅フォントのConsolasを使用しています。Consolasフォントが無い場合はビルドエラーになるので、以下のURLからConsolasフォントをダウンロードするか、フォント名を変更するようにしてください。&lt;/p&gt;  &lt;p&gt;&lt;a title="https://www.microsoft.com/downloads/details.aspx?familyid=22e69ae4-7e40-4807-8a86-b3d36fab68d3&amp;amp;displaylang=en" href="https://www.microsoft.com/downloads/details.aspx?familyid=22e69ae4-7e40-4807-8a86-b3d36fab68d3&amp;amp;displaylang=en" target="_blank" mce_href="https://www.microsoft.com/downloads/details.aspx?familyid=22e69ae4-7e40-4807-8a86-b3d36fab68d3&amp;amp;displaylang=en"&gt;https://www.microsoft.com/downloads/details.aspx?familyid=22e69ae4-7e40-4807-8a86-b3d36fab68d3&amp;amp;displaylang=en&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;このサンプルプロジェクトのコード、アセットは非商用、商用に関わらず、自由に使ってかまいません。ただし、一部のコードはクリエータークラブオンラインのMesh Instancingのコードを流用、または変更しているので、それらのコードのライセンスについては付属されるMicrosoft Permissive License.rtfに沿います。&lt;/p&gt;  &lt;p&gt;&lt;a title="http://creators.xna.com/en-US/sample/meshinstancing" href="http://creators.xna.com/en-US/sample/meshinstancing" target="_blank" mce_href="http://creators.xna.com/en-US/sample/meshinstancing"&gt;http://creators.xna.com/en-US/sample/meshinstancing&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;で、お約束ですが、このサンプルコードやアセットを使用したことで発生したいかなる問題にも当方は責任を負いません。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;デモの内容&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;デモを起動すると、おなじみのCornflowerBlueが表示されます。ここでコントローラーのスタートボタンで４種類のデモの切り替えをし、Aボタンで手法の切り替えをします。また、デモによっては左右のトリガで表示オブジェクト数の増減ができます。以下に紹介する測定結果は全てXbox 360上で測定したものです。パフォーマンス測定をする時にはビルド設定をリリースにし、デバッグにアタッチしていない状態(Ctrl+F5)で実行することを忘れないでください。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;操作方法&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;デモの切り替え      &lt;ul&gt;       &lt;li&gt;スタートボタン、またはEnterキー &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;手法の切り替え      &lt;ul&gt;       &lt;li&gt;Aボタン、またはスペースキー &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;オブジェクト数の増減      &lt;ul&gt;       &lt;li&gt;左右のトリガ、またはUp/Downキー &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;デモの終了      &lt;ul&gt;       &lt;li&gt;Backボタン、またはEscapeキー &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;配列デモ&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;.Netには様々な配列のタイプがあり、慣れていないとどれを使ったら良いのか悩むと思います。このデモでは、様々な配列を使って5,000個のスプライトの移動させるときに掛かる時間を測定しています。画面左下にある青いバーが更新時間に掛かった時間でログ表示中の&amp;quot;Update&amp;quot;です。&lt;/p&gt;  &lt;p align="center"&gt;&lt;a href="http://blogs.msdn.com/blogfiles/ito/WindowsLiveWriter/GamefestJapan2008Demo_3C3A/itoxe-2_2.png" target="_blank" mce_href="http://blogs.msdn.com/blogfiles/ito/WindowsLiveWriter/GamefestJapan2008Demo_3C3A/itoxe-2_2.png"&gt;&lt;img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="itoxe-2" src="http://blogs.msdn.com/blogfiles/ito/WindowsLiveWriter/GamefestJapan2008Demo_3C3A/itoxe-2_thumb.png" width="644" height="364" mce_src="http://blogs.msdn.com/blogfiles/ito/WindowsLiveWriter/GamefestJapan2008Demo_3C3A/itoxe-2_thumb.png" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;この配列デモの結果を見るとArrayListを使うのは避けるべきで、それ以外の手法による速度差は30~40%程度なので、後に続くデモの効果に比べると少ないものなので、用途に合わせて使いやすい配列を使いましょうということになります。&lt;/p&gt;  &lt;p&gt;このデモのソースコードは&lt;strong&gt;Demo/ArrayDemo&lt;/strong&gt;フォルダの中にあります。&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;strong&gt;動的頂点バッファデモ&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;動的頂点バッファの扱いはXNA GSでは簡単になっているものの、CPUの書き込みとGPUの読み込みがどんなタイミングで衝突するのかを理解して正しく使わないと思わぬパフォーマンス低下の原因になります。また、2Dゲームのパフォーマンス問題として頂点変換をはじめとするシェーダーでするべき仕事もCPUでしてしまい、CPU速度の遅いXbox 360では速度が出ないという問題があります。&lt;/p&gt;  &lt;p&gt;このデモでは、動的頂点バッファの使い方と、シェーダーを使った場合の効果を紹介しています。スケール、回転といった基本的なパラメーターを持ったパーティクルを3,000個描画したときに掛かる時間を測定しています。&lt;/p&gt;  &lt;p align="center"&gt;&lt;a href="http://blogs.msdn.com/blogfiles/ito/WindowsLiveWriter/GamefestJapan2008Demo_3C3A/itoxe-3_2.png" target="_blank" mce_href="http://blogs.msdn.com/blogfiles/ito/WindowsLiveWriter/GamefestJapan2008Demo_3C3A/itoxe-3_2.png"&gt;&lt;img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="itoxe-3" src="http://blogs.msdn.com/blogfiles/ito/WindowsLiveWriter/GamefestJapan2008Demo_3C3A/itoxe-3_thumb.png" width="644" height="364" mce_src="http://blogs.msdn.com/blogfiles/ito/WindowsLiveWriter/GamefestJapan2008Demo_3C3A/itoxe-3_thumb.png" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;CPUで頂点変換処理をした時に比べて、単純なシェーダー処理をするだけで8.5倍、vfetchを活用すると30倍、更にDirectMappingを使うと142倍という桁違いな速度アップになります。ただし、比較対象のCPUで頂点変換するコードは全く最適化されていないので、実際にはそこまで大きな数字は出なくとも0.09ミリ秒で3,000個のパーティクルの描画命令を発行できるというのは大きいと思います。&lt;/p&gt;  &lt;p&gt;世の中ではマルチコア、マルチスレッドが騒がれているので、どうしてもマルチスレッドプログラミングに手を出したくなってしまいますが、Xbox 360上でXNA GSが使えるHWスレッド数は４つまでなので、どんなにうまくプログラムしたとしても元の４倍以下の速度にしかならないことを考えるとシェーダーの活用がいかに効果的な手法なのかが判ると思います。&lt;/p&gt;  &lt;p&gt;このデモのソースコードは&lt;strong&gt;Demo/GameVertex&lt;/strong&gt;フォルダの中にあり、シェーダーコードは&lt;strong&gt;Demo/Content/GameVertex&lt;/strong&gt;の中にあります。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;インスタンスモデルデモ&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Xbox 360上で数万ポリゴンのモデルが数十個描画できるなら、数百ポリゴンのモデルを数千個描画できるはずと思って試してみると、数百個も描画すると処理落ちしてしまうという問題を何度か聞いたことがあります。これは、XNA GSというより、Direct X、というよりも昨今のGPUで共通の問題で、この問題を解決する為の手法がインスタンス(Instancing)です。Xbox 360はもちろん、Windowsでも非常に効果的な手法の一つです。&lt;/p&gt;  &lt;p&gt;インスタンスモデルのサンプルはクリエータークラブオンラインにもありますが、このデモではWindowsで使えるHWインスタンスをXbox 360でvfetchを使って実装していて、InstancedModelクラスを介してWindowsとXbox 360の両方で全く同じゲームコードを記述することができるようになっています。ただし、シェーダーコードのフェッチ部分はXbox 360用のコードが必要になりますが、フェッチ部分のみなので他のシェーダー処理部分は共通で使えます。&lt;/p&gt;  &lt;p&gt;このデモでは、３つのスペキュラ付き平行光源処理をした、12ポリゴン、24頂点のモデルを500個描画したときの時間を測定しています。&lt;/p&gt;  &lt;p align="center"&gt;&lt;a href="http://blogs.msdn.com/blogfiles/ito/WindowsLiveWriter/GamefestJapan2008Demo_3C3A/itoxe-4_2.png" target="_blank" mce_href="http://blogs.msdn.com/blogfiles/ito/WindowsLiveWriter/GamefestJapan2008Demo_3C3A/itoxe-4_2.png"&gt;&lt;img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="itoxe-4" src="http://blogs.msdn.com/blogfiles/ito/WindowsLiveWriter/GamefestJapan2008Demo_3C3A/itoxe-4_thumb.png" width="644" height="364" mce_src="http://blogs.msdn.com/blogfiles/ito/WindowsLiveWriter/GamefestJapan2008Demo_3C3A/itoxe-4_thumb.png" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;最適化されていない状態とHWインスタンスを使った場合で50倍、DirectMappingを使うと115倍の速度になっています。このデモでは3万６千個のボックスを描画した時点で60fpsを切りますが、これはボックスを移動する更新部分がネックになりGPUにはまだ余裕があります。そこで、試しに1,245ポリゴンのモデルを表示してみたのですが、その場合は最大3,440個のモデルが表示できました。これは１フレームあたり428万ポリゴン、秒間で２億5千万ポリゴンを描画できることになります。&lt;/p&gt;  &lt;p&gt;このデモのソースコードは&lt;strong&gt;Demo/GameModel&lt;/strong&gt;フォルダの中にあり、インスタンスモデルクラスの実装はDemoTypesフォルダの中にあり、シェーダーコードは&lt;strong&gt;Demo/Content/GameModel&lt;/strong&gt;の中にあります。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;インスタンスモデルアニメーションデモ&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;シェーダーモデル 3.0の機能として浮動小数点テクスチャと頂点シェーダーからテクスチャを読み込む頂点テクスチャがあります。このデモでは、アニメーションデータを浮動小数点テクスチャに格納し、アニメーション処理をCPUではなくGPUでしています。CPU側の処理としてはオブジェクトの移動と、アニメーションフレームの更新です。それぞれのオブジェクトのアニメーションスピードはランダムです。&lt;/p&gt;  &lt;p&gt;このデモでは、３つのスペキュラ付き平行光源処理をした、84ポリゴン、186頂点のモデルを500個描画したときの時間を測定しています。&lt;/p&gt;  &lt;p align="center"&gt;&lt;a href="http://blogs.msdn.com/blogfiles/ito/WindowsLiveWriter/GamefestJapan2008Demo_3C3A/itoxe-6_2.png" target="_blank" mce_href="http://blogs.msdn.com/blogfiles/ito/WindowsLiveWriter/GamefestJapan2008Demo_3C3A/itoxe-6_2.png"&gt;&lt;img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="itoxe-6" src="http://blogs.msdn.com/blogfiles/ito/WindowsLiveWriter/GamefestJapan2008Demo_3C3A/itoxe-6_thumb.png" width="644" height="364" mce_src="http://blogs.msdn.com/blogfiles/ito/WindowsLiveWriter/GamefestJapan2008Demo_3C3A/itoxe-6_thumb.png" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Xbox 360上では大体16,000個のオブジェクトを描画することができます。&lt;/p&gt;  &lt;p&gt;ソースコードは&lt;strong&gt;Demo/GameAnime&lt;/strong&gt;フォルダの中にあり、シェーダーコードは&lt;strong&gt;Demo/Content/GameAnime&lt;/strong&gt;の中にあります。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;他にも役に立ちそうなもの&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;４種類のデモの紹介をしましたが、このデモコードの中には他にも役立ちそうなものがあります。&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;TimeRuler (Demo/GameDebug/TimeRuler.cs) &lt;/li&gt;    &lt;li&gt;Fpsカウンター (Demo/GameDebug/FpsCounter.cs) &lt;/li&gt;    &lt;li&gt;デバッグコマンド (Demo/GameDebug/DebugCommandUI.cs) &lt;/li&gt;    &lt;li&gt;Layout (Demo/Utils/Layout.cs) &lt;/li&gt;    &lt;li&gt;StringBuilder拡張メソッド (Demo/Utils/StringBuilderExtensions.cs) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;これらについては追々紹介していきます。&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9201966" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ito/archive/tags/XNA+_D530EC30FC30E030EF30FC30AF30_/default.aspx">XNA フレームワーク</category><category domain="http://blogs.msdn.com/ito/archive/tags/_B330F330C630F330C830FB30D130A430D730E930A430F330_/default.aspx">コンテント・パイプライン</category><category domain="http://blogs.msdn.com/ito/archive/tags/_B230FC30E0308B957A76_/default.aspx">ゲーム開発</category><category domain="http://blogs.msdn.com/ito/archive/tags/_B030E930D530A330AF30B930_/default.aspx">グラフィクス</category><category domain="http://blogs.msdn.com/ito/archive/tags/_B730A730FC30C030FC30E230C730EB30_+3.0/default.aspx">シェーダーモデル 3.0</category></item></channel></rss>