エフェクトファイル(.fx)を使う場合、D3DX10CreateEffectFromFile()メソッドと使って
エフェクトを生成するが、ここで指定する .fxファイルに誤りがある場合、メソッドから
エラーが返ってくるだけで、文法上の誤りが特定できないという難点がある。
なので、DirectXのインストールフォルダの中にある fxc.exe を使って
実際にファイルとコンパイルする事でエラーを特定することができる。
使用例
fxc /Tfx_4_0 XXXX.fx
コンパイルに成功すると、アセンブラ生成コードが出力される。
/Fcオプションを付けてアセンブラコードを出力すると便利。
例えば頂点シェーダーの出力などに使う SV_Positionセマンティクス。
これを関数の返り値にする場合は必ず全てのxyzw要素に値が格納されていなければならない
まずはこれを見て欲しい
Struct ScreenPos {
uint x : POS_X;
uint y : POS_Y;
};
float 4 VS( ScreenPos Pos : INPUT_POS ) : SV_POSITION
{
…
}
この場合、生成される入力シグネチャは
Name |
Index |
Mask |
INPUT_POS |
0 |
x |
INPUT_POS |
1 |
x |
となるので、入力レイアウトの定義としては
D3D10_INPUT_ELEMTNT_DESC layout[] =
{ "INPUT_POS", 0, DXGI_FORMAT_R32_UINT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
{ "INPUT_POS", 1, DXGI_FORMAT_R32_UINT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
};
となる。
ここで、頂点シェーダーVS()の引数のセマンティクスを省略して
float 4 VS( ScreenPos Pos ) : SV_POSITION
とすると、生成される入力シグネチャは
Name |
Index |
Mask |
POS_X |
0 |
x |
POS_Y |
0 |
x |
となるので、入力レイアウトの定義としては
D3D10_INPUT_ELEMTNT_DESC layout[] =
{ "POS_X", 0, DXGI_FORMAT_R32_UINT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
{ "POS_Y", 0, DXGI_FORMAT_R32_UINT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
};
となる。
シェーダー内では引数はPos.x, Pos.yという形でアクセスできるが、
アセンブラコード的にはxフィールドを使う2つの変数、という形になっている。
コード中でもxyフィールドとして扱いたいのであれば、
float4 VS( uint2 Pos : INPUT_POS ) : SV_POSITION
とすると、入力シグネチャは
Name |
Index |
Mask |
INPUT_POS |
0 |
xy |
となるので、すっきり。
ちなみに入力レイアウトは
D3D10_INPUT_ELEMTNT_DESC layout[] =
{ "INPUT_POS", 0, DXGI_FORMAT_R32B32_UINT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
};
となる。
…は省略不可。引数部分、もしくは引数となる構造体のメンバに
きちんとセマンティクスを設定しておく必要がある。
尚、エフェクトファイル内で定義するローカル関数に関しては設定の必要はない。
シェーダー側で定義する関数の引数のサイズとアプリケーションで設定する
入力レイアウトのサイズが異なる分にはエラーは発生しない。
例えばシェーダーの引数が
float4
で、アプリケーションの入力レイアウトが
DXGI_FORMAT_R32G32B32_FLOAT
でも問題は発生しない。
ただ、上記の場合、シェーダー側が受け取る引数のwフィールドの値はどうなっているんだろう…
最終更新:2008年10月10日 16:20