エフェクトのコンパイル (Direct3D 10)
エフェクトがオーサリングされた後の最初の手順は、コードをコンパイルして、構文上の問題を確認することです。これは、いずれかのコンパイル API (D3DX10CompileEffectFromFile、D3DX10CompileEffectFromResource、D3DX10CompileEffectFromMemory など) を呼び出すことによって実行されます。これらの API によって、HLSL コードのコンパイルに使用されるコンパイラーであるエフェクト コンパイラー fxc.exe が起動されます。これが、エフェクト内のコードの構文が HLSL コードとよく似ている理由です (いくつか例外がありますが、これについては後で説明します)。必要な場合に、シェーダー (またはエフェクト) をオフラインでコンパイルできるように、エフェクト コンパイラー (hlsl コンパイラー) fxc.exe が、ユーティリティ フォルダーの SDK に用意されています。コマンド ラインからのコンパイラーの実行については、ドキュメントを参照してください。
- include
- マクロ
- HLSL シェーダー フラグ
- FX フラグ
- エラーのチェック
次に、(BasicHLSL10 サンプルからの) エフェクト ファイルのコンパイルの例を示します。
WCHAR str[MAX_PATH]; DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"BasicHLSL10.fx" ); hr = D3DX10CompileEffectFromFile( str, NULL, NULL, "fx_4_0", D3D10_SHADER_ENABLE_STRICTNESS, 0, pd3dDevice, NULL, NULL, &l_pBlob_Effect, &l_pBlob_Errors, NULL );
include
パラメーターは、include インターフェイスです。include ファイルを読み取るときにカスタマイズした動作を含めるには、いずれかの include インターフェイスを生成します。このカスタム動作は、(include ポインターを使用する) エフェクトが作成されるたびに、または (include ポインターを使用する) エフェクトがコンパイルされるときに実行されます。カスタマイズした include 動作を実装するには、対象の include インターフェイスからクラスを派生します。これによってクラスで次の 2 つのメソッドを使用できるようになります。Open と Close。Open メソッドと Close メソッドでカスタム動作を実装します。
マクロ
エフェクトのコンパイルでは、他の場所で定義されたマクロへのポインターを取得することもできます。たとえば、次の 2 つのマクロを使用するよう BasicHLSL10 でエフェクトを変更するとします。zero と one。この 2 つのマクロを使用するエフェクト コードを次に示します。
if( bAnimate ) vAnimatedPos += float4(vNormal, zero) * (sin(g_fTime+5.5)+0.5)*5; Output.Diffuse.a = one;
次に、この 2 つのマクロの宣言を示します。
D3D10_SHADER_MACRO Shader_Macros[3] = { "zero", "0", "one", "1.0f", NULL, NULL };
マクロは、NULL で終わるマクロ配列になります。ここでは、各マクロは D3D10_SHADER_MACRO 構造体を使用して定義されます。
最後に、マクロへのポインターを取得するようにコンパイル エフェクトの呼び出しを変更します。
D3DX10CreateEffectFromFile( str, Shader_Macros, NULL, D3D10_SHADER_ENABLE_STRICTNESS, 0, pd3dDevice, NULL, NULL, &g_pEffect10, NULL );
HLSL シェーダー フラグ
シェーダー フラグは、HLSL コンパイラーに対するシェーダー制約を指定します。これらのフラグは、次のように、シェーダー コンパイラーによって生成されるコードに影響を与えます。
- サイズ制約 :コードの最適化
- デバッグに関する考慮事項 :デバッグ情報の追加、フロー制御の防止
- ハードウェアに関する考慮事項 :コンパイラー ターゲット、シェーダーを従来のハードウェアで実行できるかどうか
通常、これらのフラグは、2 つの競合する特徴が指定されていないことを前提として、論理的に結合できます。フラグの一覧については、「エフェクト定数 (Direct3D 10)」を参照してください。
FX フラグ
これらのフラグは、エフェクトの作成時にコンパイル動作または実行時のエフェクト動作の定義に使用されます。フラグの一覧については、「エフェクト定数 (Direct3D 10)」を参照してください。
エラーのチェック
コンパイル時にエラーが発生した場合、エフェクト コンパイラーから返されたエラーが含まれるインターフェイスが API から返されます。このインターフェイスは、ID3D10Blob と呼ばれます。これを直接読み取ることはできませんが、データ (文字列) を含むバッファーへのポインターを返すことによって、コンパイル エラーを確認できます。
次の例では、最初の変数宣言が 2 回コピーされることによって、BasicHLSL.fx エフェクトにエラーが発生しました。
//------------------------------------------------------------------- // Global variables //------------------------------------------------------------------- float4 g_MaterialAmbientColor; // Material's ambient color // Declare the same variable twice float4 g_MaterialAmbientColor; // Material's ambient color
これによって、コンパイラーからエラーが返され、Visual Studio のウォッチ ウィンドウに次のように表示されます。
このエラーは LPVOID ポインターで返されるため、ウォッチ ウィンドウで文字列にキャストします。
次に、失敗したコンパイルからエラーを返すときに使用されるコードを示します。
// Read the D3DX effect file WCHAR str[MAX_PATH]; ID3D10Blob* l_pBlob_Effect = NULL; ID3D10Blob* l_pBlob_Errors = NULL; hr = DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"BasicHLSL10.fx" ); hr = D3DX10CompileEffectFromFile( str, NULL, NULL, D3D10_SHADER_ENABLE_STRICTNESS, 0, NULL, &l_pBlob_Effect, &l_pBlob_Errors ); LPVOID l_pError = NULL; if( l_pBlob_Errors ) { l_pError = l_pBlob_Errors->GetBufferPointer(); // then cast to a char* to see it in the locals window }