Top > ComputerGraphics > HLSL > Common > CodeDivide
Last-modified: Tue, 02 Oct 2012 07:09:04 JST
Counter:3815 Today:1 Yesterday:0 Online:8
このエントリーをはてなブックマークに追加

HLSLのコードを分割して記述する

About

 シェーダファイル(.Fx)を作製していると、沢山関数を作るようになって、変数も沢山になって、記述量が増えていってしまう事はよくある。regionコードなど書ければまだ1つのファイルに収める気にもなるのだけれど、残念ながら利用できない。所がHLSLはCに近い文法をとることから「include文」を利用してコードを分割して記述する事ができる。

※サンプルがXNAベースですがDirectXなどでも共通の話題です。

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種類あって、それぞれの詳細については公式の方で確認されたい。