日別アーカイブ: 2007年8月4日

Direct3D 10 シェーダー4.0サンプルプログラム

Direct3D 10 の ShaderModel4.0 は非常に自由度が高く、かなりいろいろな
ことができます。3.0 以前の制約の中で結構がんばってコードを書いた経験が
あるなら、この柔軟性にはちょっとした感動を覚えるかもしれません。

特にマニュアルを読んでいて衝撃を受けたのがこれ

Using the Input-Assembler Stage without Buffers (Direct3D 10)

マニュアルの下記の場所にあります。
+ DirectX Graphics
 + Direct3D 10
  + Programming Guide
   + Pipeline Stages
    + Input-Assembler Stage
     + Getting Started with the Input-Assembler Stage
      + Using the Input-Assembler Stage without Buffers (Direct3D 10)

SV_VertexID を元に VertexShader の中で頂点を選択して描画しています。
つまり、VertexBuffer も IndexBuffer も無く、InputLayout も設定せずに
ポリゴンが描画できてしまうのです。

このシンプルさに惚れました。

自分でも同じように、頂点バッファ無しにポリゴン描画できるシェーダーを
作ってみました。fx を読み込んで描画するだけで、一切リソースを作らなくても
こんな感じの Cube を表示することができます。

形状を生成しているのは下記の部分です。
ついにシェーダーでこんなトリッキーなコードが走るようになりました。

float3 VS_Main( uint id : SV_VertexID, uint sid : SV_InstanceID ) : POSITION
{
 uint _map[]= {
  101733320,
  104889305,
  56280874,
  125360034,
 };
 id= _map[id&3]>>(((id&60)>>2)*3);
 float3 pos;
 pos.x= id & 1 ? 1 : -1;
 pos.y= id & 2 ? -1 : 1;
 pos.z= id & 4 ? 1 : -1;
 float2 ss;
 sincos( sid * 0.5236f, ss.x, ss.y );
 pos.xy+= ss * 5;
 return mul( float4( pos, 1 ), WorldToView ).xyz;
}

シェーダー全部でもこれだけです。
 ・cube.fx

描画している C++ 側はこんな感じです。

g_iEffect->GetTechniqueByIndex( 0 )->GetPassByIndex( 0 )->Apply( 0 );
g_iDevice->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
g_iDevice->DrawInstanced( 36, 12, 0, 0 );

g_iSwapChain->Present( 0, 0 );

ソースリストと実行ファイルは
 ・「HYPERでんち」 オリジナルサンプルプログラム
に掲載しましたので、興味ある方がいましたらどうぞお試しください。