Houdini 20.0 VEX

シェーダコール

On this page

Houdini12.5から、VEXシェーダ関数が他のシェーダ関数をコールすることができます。 このテクニックによって、膨大なシェーダに対してVEXコンパイラとオプティマイザーパフォーマンスを最適化することができます。 なぜなら、シェーダ内または他のシェーダで何度も呼び出されるコードを一度でビルドして、余計なランタイムのオーバーヘッドがなく何度も使うことができるからです。

importキーワード

importキーワードは、他のシェーダ関数を名前で現行シェーダに取り込みます。 取り込むシェーダがコンパイルで成功するためには、そのシェーダがHoudiniパスでアクセス可能になっている必要があります。シェーダが見つからない場合、 シェーダのコンパイルは失敗します。そのため、他のシェーダをコールするシェーダを構築する時、依存性の順番(コールされるシェーダの次にコールするシェーダ)でシェーダをビルドする必要があります。 循環コールは可能ですが、1番目のコールするシェーダをビルドした後にコールされるシェーダにimportキーワードを追加する必要があります。

plasticシェーダのインポートの例:

import plastic;

シェーダを再帰的にコールすることができます。この場合、importキーワードは必要ありません。

シェーダの呼び出し

シェーダを名前で呼び出して、キーワードの引数(呼び出したシェーダへ渡す引数またはそのシェーダから受け取る引数を識別する文字列/値のペア)を渡します。 コールされたシェーダが、バインドされていないパラメータに対してそのデフォルト値を使用する場合は、いくつかのパラメータのみをバインドすることができます。 さらに、コールされたシェーダからエクスポートのサブセットのみをバインドする必要があります。 この場合、VEXオプティマイザーは不要なエクスポートを計算する不要コードを取り除いて、パフォーマンスを良くします。

例えば、以下のコードはCfエクスポートの要求とdiff入力を用意するplasticシェーダを呼び出します:

import plastic;

surface caller(vector diff = {1,0.5,0})
{
    plastic("diff", diff, "Cf", Cf);
}

vccは、コールされるシェーダに渡す可変長引数をすべてチェックし、それらの引数がコールされるシェーダのパラメータリストに存在する引数またはエクスポートに一致しているかどうか確認します。 そのタイプやアクセスモードが一致しなかった場合、エラーが報告されます。

コールされるシェーダのコンテキスト

現在のところ、シェーダは一致するコンテキストタイプを持つシェーダのみをコールすることができます。 グローバル変数を持つコンテキストに対して、明示的にキーワード引数としてシェーダに用意されていない任意のグローバル変数は、コールするシェーダからコールされるシェーダにそのままコピーされます。 追加した不透明状態の情報を伝えるコンテキスト(例えば、当たったサーフェスに関する状態を保持するサーフェスコンテキスト)に対して、この情報もコールされるシェーダに保持されるので、getraylevel()の ようなコールメソッドは、コールするシェーダとコールされるシェーダで同じ結果になります。

サンプル

コールされるシェーダ:

cvex callee(export int mval = 0;
        int rval = 0;
        export int wval = 0;
        float castval = 0)
{
    mval *= 2;
    wval = rval;
}

コールするシェーダ:

import callee;

cvex caller()
{
    int mval = 1;
    int rval = 2;
    int wval = 1;
    callee("mval", mval, "rval", rval, "wval", wval, "castval",
            1);
    printf("%d %d %d\n", mval, rval, wval);
}

再帰シェーダ:

cvex fib(int i = 0; export int rval = 0)
{
    if (i >= 2)
    {
        int v1, v2;
        fib("i", i-1, "rval", v1);
        fib("i", i-2, "rval", v2);
        rval = v1 + v2;
    }
    else
        rval = i;
    printf("%d: %d\n", i, rval);
}

VEX

言語

次のステップ

リファレンス