HLSL/Cg では固定長の配列しか使えないので初期化に注意

3DCGのイメージ。

Unity でも同じような問題が起こります。

HLSL や Cg などのシェーダ言語で、配列を初期化しようとして失敗するパターンがあります。例えばコンパイルエラーは次のように出力されます。

error X3058: array dimensions must be literal scalar expressions

配列を初期化する場合は、リテラル(固定値:定数)なスカラ型(通常はint)で行いなさい、というエラーです。 端的に言えば、執筆時時点での多くのシェーダ言語は動的にサイズが変わる配列を利用できません。

したがって、コンパイル時に配列の長さが確定するような実装が必要です。 配列の初期化に失敗するパターンは次のようになっています。

int ArrayCount = 50;//エラーが起きる
static int ArrayCount = 50;//エラーが起きる
const int ArrayCount = 50;//エラーが起きる
uniform int ArrayCount = 50;//エラーが起きる
static const int ArrayCount = 50;//エラーは起きない

float4 PixelShaderFunction() : COLOR0
{
    int array[50];//問題なくコンパイルされる
    int array[ArrayCount];//エラーが起きる場合がある
…
}

「static const」の場合のみコンパイルが通ります。つまり外部参照が不可で、 CPU 側から適宜設定して、実行の度に動的に変更する、といった処理を実装することができない、ということになります。

また引数に(可変の?)配列を指定することもできない点に注意します。引数に指定される配列の長さが保証されないためです。

References