HLSLのコードを分割して記述する
About
シェーダファイル(.Fx)を作製していると、沢山関数を作るようになって、変数も沢山になって、記述量が増えていってしまう事はよくある。regionコードなど書ければまだ1つのファイルに収める気にもなるのだけれど、残念ながら利用できない。所がHLSLはCに近い文法をとることから「include文」を利用してコードを分割して記述する事ができる。
※サンプルがXNAベースですがDirectXなどでも共通の話題です。
WindowsGame1_CodeDivide.zip
- VisualStudio2010
- XNA4.0
How to
なにも難しいことはなくて、C言語と同様に、記述する順序にだけ気をつけてinclude文を使うことだけで分割記述することができる。ここのサンプルでは簡単に次の様にしている。単純に、新規追加した際に標準で用意されている関数とパラメータを分割し、実際にEffectとして読み込むファイルにはTechniqueのみ記述される様にしてみた。
【EffectFunctions.h】
単純に標準で用意される関数とパラメータを分割して記述。「.h(ヘッダー)ファイル」としている点に注意。後述する。
float4x4 World; float4x4 View; float4x4 Projection; struct VertexShaderInput { float4 Position : POSITION0; }; ///省略/// VertexShaderOutput VertexShaderFunction(VertexShaderInput input) { ///省略/// } float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0 { return float4(1, 0, 0, 1); }
【Effect.fx】
Techniqueのみを記述している。ここではサンプルのため、二つTechniqueを記述した。先頭行でincludeしている。
#include "EffectFunctions.h" technique Technique0 { pass Pass1 { PixelShader = compile ps_2_0 PixelShaderFunction(); } } technique Technique1 { pass Pass1 { VertexShader = compile vs_2_0 VertexShaderFunction(); PixelShader = compile ps_2_0 PixelShaderFunction(); } }
エラー「ID3DXEffectCompiler: There were no techniques」
「technique」として扱うことのできる関数の存在しない「.fx」(Effect)ファイルをincludeしようとするとエラーが起こる。例えばグローバル変数や基本的な関数を、別のファイルまとめて扱うでなどする時にこのエラーが起こり易い。そういう場合は「.h」(ヘッダー)ファイルとしてincludeするとエラーを回避する事ができる。
ただしこの場合は警告が返る。「Project item 'xxx.h' was not built with the XNA Framework Content Pipeline.」
- XNAプロジェクトで次のエラーが起きる場合には、「プロパティ」から「インポーター」を「エフェクトファイル」にすることで解決することができます。
エラー"xxx.h" に使用するインポーターを自動検出できません。このファイル形式を処理するインポーターがありません。プロジェクトでこのファイル形式を処理するインポーターを指定してください。
Others
基本的にはC言語と同様の挙動をとるので、includeを変な位置に書いて、関数が定義されていないなんてコンパイルエラーを起こさない様に注意すること(後は多重にincludeして重複する変数がでる、など)。includeの文法については2種類あって、それぞれの詳細については公式の方で確認されたい。