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); }