On this page |
なぜOpenCLなのか? ¶
VEXは、ほとんどの計算で必要とされるものに最適です。 しかし一部の類のアルゴリズムでは、高速なGPUでの実行に適した構造になっているものがあります。 VEXはGPU上で実行できないため、別の言語でアルゴリズムを記述する必要があります。
OpenCLは、GPUとCPUの両方の実装をサポートしている標準のカーネル言語です。 GPUを搭載していないマシンでもアルゴリズムを実行でき、2つのバージョンを維持する必要はありません。
GPUの恩恵を受けるための主な要件は、データをGPUに保持することです。 OpenCLでないノードがジオメトリを処理する場合には、そのデータはCPUに戻され、それによってパフォーマンス上の利点が失われることがよくあります。 SOPでは、各SOPがクック完了後にジオメトリを戻してローカルキャッシュに保存しなければならないことに注意してください。 これは、OpenCLノードチェーンをコンパイルブロック内に入れることで回避することができます。
なぜOpenCLではだめなのか? ¶
OpenCLは、VEXに比べるとかなり扱いにくい言語ですが、VEXの経験があれば、その多くは理解しやすいでしょう。 ポインタを使用するため、安全でないコードを記述してしまいやすく、それによってビデオカードドライバやHoudiniをクラッシュさせてしまう可能性があることに注意してください。 開発中、コンパイル時にすべてのカーネルでエラーが発生するなど、ひどい状態に陥る可能性もあります。 Houdiniを再起動して、ドライバを復元する必要が生じるかもしれません。 稀にマシンの再起動が必要になる場合もあります。
GPUは仮想メモリを持たないため、通常は割り当てるデータ量が多すぎるとスワップや速度低下が生じますが、OpenCLを使用した場合だと、割り当ての失敗やエラーが発生します。
構文と言語 ¶
OpenCLは、VEXと同様にC言語に似ています。どちらも見た目は同じで、各行はセミコロンで終了する必要があり、中括弧を使用してブロックを囲みます。
OpenCL自体はC99規格に準拠しているため、C99規格のオンラインリソースも参照することができます。
OpenCLにforeach()はありません。
関数のパラメータには、各パラメータの型が必要で、セミコロン(;
)ではなくカンマ(,
)で区切ります。
Vex:
int foo(float a; int b, c) { return a + b + c; }
OpenCL:
int foo(float a, int b, int c) { return a + b + c; }
OpenCLのパラメータは、常に“値渡し”です。 つまり、関数内でパラメータを変更しても、渡された値には影響しません。 しかし、OpenCLにはポインタがあるため、ポイントで指されているものを変更すると、元の値にも影響します。
VEXでは、関数内部で関数を宣言することができますが、OpenCLでは不可能です。
カーネル ¶
VEXとOpenCLは、どちらもカーネル言語です。 多くのアルゴリズムでよく見受けられる外側ループを回避するというのが、カーネル言語の考え方です。 各ポイントに何か追加したい場合、従来の言語では以下のようになります:
for (int i = 0; i < number_of_points; i++) { process_point(i); }
しかし、明示的な外側ループによって、最適化が非常に困難になります。 というのも、process_pointが以前のコールに依存しているかもしれないからです。 代わりにprocess_pointのみを記述することで、よりシンプルながらも、簡単に並列で実行できるコードになります。 これを利用することで、VEXは数百万ものポイントを迅速に処理し、OpenCLはGPUが効率的にそのプログラムを実行できるようにします。
通常のVEX Wrangle SOPでは、process_point()関数は非表示になっています。 process_point()内にコードを記述するには、以下のようなスニペットを使用します:
@P += 1;
シーンの背後では、Wrangleノードは以下のようなカーネルのラッパー関数を構築します:
void process_point(vector _bound_P) { _bound_P += 1; } cvex dowrangle(export vector P) { process_point(P); }
このdowrangle
カーネルは、VEXランタイムに渡されて、すべてのポイントで実行されます。
OpenCLノードには、それと同じ自動ラッパーはありません。
代わりに、dowrangle
と同等のものをカーネル関数として記述する必要があります。
同等のOpenCLコードは以下のようになります:
kernel void dowrangle( int P_length, global float * restrict P ) { int idx = get_global_id(0); if (idx >= P_length) return; float3 pos = vload3(idx, P); pos += 1; vstore3(pos, idx, P); }
OpenCLノードでは、P
Pointアトリビュートを書き出せるようにするには、そのアトリビュートのバインドを明示的に設定する必要があります。
定型文を最小限にして、vload
やvstore
を使用することなくアトリビュートへ直接アクセスできるようにするために、OpenCLノードには @-Binding モードも用意されています。
このモードが有効な時、 @KERNEL を使用してカーネルを指定することができ、それに適切な定型文が挿入されます。このコードは以下のようになります:
#bind point &P float3 @KERNEL { float3 pos = @P; pos += 1; @P.set(pos); }
Run Over ¶
VEX Wrangleの重要なコンポーネントは、Run Over
パラメータです。
これは、カーネルが実行されるエレメントを制御します。
例えば、Run Over
をポイントに設定すると、カーネルはポイント毎に1回実行されます。
Volume Wrangleはその性質上、ボリュームとVDBでのRun Overに暗黙的に設定されているため、ボクセル毎にカーネルが実行されます。
OpenCLでは、カーネルのプライマリターゲットまでも指定する必要があります。 これは、書き込み先である必要はなくて、単にGPUに渡されるワークアイテムの数を定義するだけです。
最も単純な実行モードはFirst-Writableモードです。 これらは、最初の書き込み可能なアトリビュート、ボリューム、VDBを見つけ、それを実行のテンプレートとして使用します。
Run OverをDetailにして直列での実行を強制された場合でさえも何とか処理するVEXとは異なり、GPUは直列による実行をうまく処理できず、常に多くのエレメントをターゲットにします。
VEX WrangleのRun OverのNumberに相当するものが Detail Attribute of Worksets です。 ただし固定の数ではなく、入力ジオメトリ上のDetail配列アトリビュートのペアを受け取って、ワークフローアイテムを作成します。 これにより、複雑さはかなり増しますが、GPUの実行を非常に正確に制御することができます。
ドット演算子 ¶
VEXでは、ドット演算子(.
)を使用してベクトルのコンポーネントにアクセスすることができます。
x、y、z、wや、r、g、b、a、さらにはu、vも使用することができます。
これらを組み合わせて、ベクトルをSwizzle(コンポーネントの並べ替え)することができ、例えばv.zyx
は逆順の3次元ベクトルを作成します。
OpenCLには、それに似た表記方法があります。
また、ベクトル型の下位半分と上位半分を抽出する.lo
と.hi
や、奇数番目と偶数番目を引き出す.odd
と.even
もあります。
ベクトル型は最大でfloat16
(16個のfloat)まで対応し、.s
表記もあります。
.s0
は.x
と同じで、.s01
は.xy
と同じです。
.s
表記に9を超える数を使用する場合は、aからfまたはAからFを10から15に使用できます。
Note
OpenCLはVEXの.u
または.v
の亜種をサポートしていません。
組み込み関数 ¶
VEXと異なり、OpenCLの組み込み関数のセットは非常に少ないです。 VEXでは様々な演算が可能で、誤差関数の計算からジオメトリ上のポイントの照会まで、何でも行なうことができます。 OpenCLの内部関数は、大部分が純粋に数学的なものです。
残念なことに、組み込みマトリックスはほとんどサポートされていません。 matrix.hが用意され(およびデフォルトでスニペットに含まれ)、いくつかの方法でマトリックスの乗算を行なうことができます。
Note
mat3
のサイズは、実際は12個のfloatです。
Note
select
はOpenCLとVEXの両方にありますが、残念なことに引数の順序が異なります。
VEXでは条件が最初、OpenCLでは条件が最後にきます。
matrix関数 ¶
注目すべきmatrix.h関数は以下の通りです:
関数 |
説明 |
---|---|
mat2 transpose2(const mat2 a) |
転置された |
mat3 transpose3(const mat3 a) |
転置された |
mat2 mat2mul(const mat2 a, const mat2 b) |
|
fpreal2 mat2vecmul(const mat2 a, const fpreal2 b) |
|
fpreal squaredNorm2(const mat2 a) |
2×2マトリックスのL2ノルムの2乗を返します。 |
fpreal squaredNorm3(const mat3 a) |
3×3マトリックスのL2ノルムの2乗を返します。 |
void mat3add(const mat3 a, const mat3 b, mat3 c) |
|
void mat3sub(const mat3 a, const mat3 b, mat3 c) |
|
mat3zero(mat3 a) |
|
mat3identity(mat3 a) |
|
mat3copy(const mat3 a, mat3 b) |
|
mat3load(size_t idx, const global float *a, mat3 m) |
|
mat3store(mat3 in, size_t idx, const global float *data) |
9個のfloatを行優先で、順に |
void mat3fromcols(const fpreal3 c0, const fpreal3 c1, const fpreal3 c2, mat3 m) |
指定したベクトルの列で3×3マトリックスを作成します。 |
mat3 mat3mul(const mat3 a, const mat3 b) |
|
fpreal3 mat3vecmul(const mat3 a, const fpreal3 b) |
|
fpreal3 mat3Tvecmul(const mat3 a, const fpreal3 b) |
|
fpreal2 mat3vecmul(const mat3 a, const fpreal3 b) |
|
fpreal2 mat3Tvecmul(const mat3 a, const fpreal3 b) |
|
void outerprod3(const fpreal3 a, const fpreal3 b, mat3 c) |
cをaとbの外積に設定します。 |
void mat3lcombine(const fpreal s, const mat3 a, const fpreal t, const mat3 b, mat3 c) |
|
fpreal det3(const mat3 a) |
|
fpreal3 diag3(const mat3 a) |
|
fpreal2 mat4vec2mul(const mat4 a, const fpreal2 b) |
|
fpreal3 mat43vec3mul(const mat4 a, const fpreal3 b) |
b * Aを返します(bの4番目のコンポーネントは0であると仮定)。 |
fpreal3 mat4vec3mul(const mat4 a, const fpreal3 b) |
b * Aを返します(bの4番目のコンポーネントは1であると仮定)。 |
fpreal4 mat4vecmul(const mat4 a, const fpreal4 b) |
b * Aを返します。 |
int mat4invert(fpreal16 *m) |
|
fpreal mat2det(const mat2 m) |
|
fpreal mat2inv(const mat2 m, mat2 *minvvout) |
minvoutをmの逆行列に設定します。行列式を返します。 |
fpreal mat3inv(const mat3 m, mat3 minvout) |
minvoutをmの逆行列に設定します。行列式を返します。 |
void mat3scale(mat3 mout, const mat3 m, fpreal scale) |
|
void mat3lincomb2(mat3 mout, const mat3 m1, fpreal scale1, const mat3 m2, fpreal scale2) |
|
精度 ¶
VEXは、全体で単精度で実行されます。
float
は、32Bitモードでは32ビット、64 Bitモードでは64ビットです。したがって、double
とfloat
の区別はありません。
OpenCLの精度は固定されています。 しかし、32ビットの方が計算がかなり高速であり、一方で、何かしらの問題で64ビットが必要になることもあるので、必要に応じて精度を切り替えるコードを記述したい場合がよくあります。
組み込みのOpenCLの型には固有の精度があります。
fpreal
およびexint
という2つの新しい型が追加され、これらの精度はノードや入力ジオメトリに依存します。
そのため、コードを1回記述するだけで、複数の精度でそのコードを動作させることができます。
名前 |
精度 |
型 |
---|---|---|
half |
16 |
Float |
float |
32 |
Float |
double |
64 |
Float |
fpreal |
可変 |
Float |
short |
16 |
Integer |
int |
32 |
Integer |
long |
64 |
Integer |
exint |
可変 |
Integer |
型 ¶
OpenCLとVEXは、基本の型は似ていますが、名前が異なります。
mat2/3/4
型は、matrix.hで定義されています。
以下のfloat
は、任意の浮動小数点精度(half
、float
、double
、fpreal
)に置き換えることができます(int
でも可能)。
VEX |
OpenCL |
型 |
---|---|---|
int |
int |
Integer値 |
|
int2/3/4/8/16 |
指定された数のコンポーネントのIntegerベクトル |
float |
float |
Float値 |
vector2 |
float2 |
2つのコンポーネントを持つベクトル |
vector |
float3 |
3つのコンポーネントを持つベクトル。OpenCLでは、これは4個のfloatによってメモリ内に配置されるため、構造t体で使用する場合は注意する必要があります。 |
vector4 |
float4 |
4つのコンポーネントを持つベクトル。 |
|
float8/16 |
OpenCLには、ネイティブの8および16のコンポーネントを持つベクトルもあります。 |
matrix2 |
float4, mat2 |
float4はmatrix2と同じサイズですが、より分かりやすくし、いくつかのユーティリティ関数を提供するために、mat2を定義しました。 |
matrix3 |
mat3 |
ネイティブの9個のエレメントを持つ型はありません。定義されているmat3は実際は12個のエレメントを持つ型なので、メモリに出し入れする際には注意する必要があります。 |
matrix |
float16, mat4 |
float16はmatrixと同じサイズですが、より分かりやすくし、いくつかのユーティリティ関数を提供するために、mat4を定義しました。 |
string |
|
OpenCLではprintf()などで文字列リテラルを定義できますが、GPUで実行され、特異な点が多くあるため、他のC言語で想定するような |
dict |
|
OpenCLでは、辞書はサポートされていません。 |
|
|
VEXでは、動的に拡大および縮小することができ配列の型がサポートされています。 OpenCLでは、よく似た効果にポインタを使用することができますが、動的に変更することはできません。 |
バインドとプロトタイプ ¶
VEX Wrangleおよびスニペットは、@構文を使用してアトリビュートを参照する時、アトリビュートを自動的にバインド(紐付け)します。 複雑なスニペットでは、使用する前にバインドを明示的に宣言することを必須にする Enforce Prototypes をオンにすると良いでしょう。
この自動バインドのために、VEXの@構文には、型が暗黙的に指定されない場合のその型を指定するための接頭辞があります。
OpenCLには、そのような自動バインドや型の接頭辞もありません。
代わりに、すべての@バインドは、ノードの Bindings タブのパラメータ、または、スニペット内の#bind
命令のいずれかで明示的に指定する必要があります。
#bind
命令では、簡潔な行で、Bindingsパラメータと同じ情報を指定することができます。
同じ@バインドが#bind
およびBindingsパラメータの両方で制御されている場合、Bindingsパラメータが使用されます。
#bind
命令の基本的な形式は以下の通りです。
// タイプ 名前 フラグ... #bind parm foobar read write
このタイプは、バインド先です。 この名前は、このバインドを参照する@ステートメントで使用されるトークンです。 デフォルトではアトリビュート名とマッチしますが、フラグを使用して異なるアトリビュートを選択することもできます(これは、同じ名前の2つのアトリビュートをバインドする場合に必要で、@を明確にするために異なる名前が必要になります)。
フラグは、スペースで区切ったフラグのリストです。
バインド名のデコレーション ¶
名前はデコレーションすることができます。 デコレーションは、名前の前または後に追加することができます。
デコレーション |
暗黙的に設定されるフラグ |
---|---|
|
write |
|
opt |
|
noread |
バインドタイプ ¶
以下は、有効なバインドワードのリストです。マルチパラメータ内の対応するバインドで、これらの仕組みについての詳細を確認できます。
バインド |
タイプ |
---|---|
parm |
整数、浮動小数点、浮動小数点ベクトルスタイルのバインドとマッチします。
|
point/prim/primitive/global/detail/vertex |
このクラスのジオメトリアトリビュートをバインドします。 |
ramp |
ランプをバインドします。スカラーランプまたはベクトルランプの場合、 |
volume |
ジオメトリ内のボリュームプリミティブをバインドします。 |
vdb |
ジオメトリ内のVDBプリミティブをバインドします。 |
option |
DOP内のDOP Optionをバインドします。 |
sfield/vfield/mfield/scalarfield/vectorfield/matrixfield |
指定されたタイプのDOPフィールドにバインドします。 |
型フラグ ¶
フラグで指定する1個の型は、float
やfloat2
といったOpenCLの型をフラグとして使用することができます。
ここには、バインドのベクトルのサイズや精度などを指定します。
float[]
は、配列アトリビュートへのバインドを指定するのに使用することができます。
また、float?
やint?
を使用すると、任意のサイズのアトリビュートにバインドすることができます。
tuplesize
メソッドを使用すると、実際のバインドサイズを確認することができます。
アクセスフラグ ¶
アクセスフラグは、ソースアトリビュートがカーネルにバインドされる方法を制御します。
フラグ |
意味 |
---|---|
read / noread |
デフォルトはreadです。 バインドが読み込み可能な場合、そのOpenCLバッファは元の値から初期化されます。 バインドを読み込み可能としてマークしなかった場合には、値を上書きすることが重要になります。 上書きしなかった場合、任意のデータが存在することになります。 |
write / nowrite |
デフォルトはnowriteです。 書き込み可能としてマークされていないバインドは、変更なしとみなされるため、CPUには書き出されません。 無理に行おうとすれば、書き出すことも可能ですが、未定義の挙動が発生します。 |
opt / noopt |
デフォルトはnooptです。 オプションのバインドは、元のジオメトリに存在する必要はありません。 バインドが存在する場合はマクロdefine HAS_nameが定義され、異なるコードパスを持つことができます。 または、defフラグが存在する場合、欠けているバインドが単一のデフォルト値に置き換えられます。 |
def / nodef |
デフォルトはdefです。 オプションのバインドが存在しない場合、代わりに同じ場所でパラメータがバインドされます。
例えば、オプションでPointアトリビュート |
ターゲットフラグ ¶
ターゲットフラグをバインドすることで、バインドのソースに何を使用するのか厳密に制御することができます。 @に使用する名前は常にバインド名であり、バインドされるもののデフォルトになることが多いですが、これによってより詳細な制御が可能になります。
フラグ |
意味 |
---|---|
val=# |
デフォルトは0です。 パラメータ、ボリューム、VDBにデフォルト値を設定します。
ベクトルバインドで単一スカラーが指定されている場合、それが繰り返されるため、ベクトル上 |
name=SSS |
デフォルトはバインド名です。 バインド先のアトリビュート、ボリューム、VDBの名前。 |
input=# |
デフォルトは0です。 SOPでは、バインド先の入力です。1番目の入力のみ書き出すことができます。 |
geo=SSS |
デフォルトはジオメトリです。 DOPでは、現在のシミュレーションオブジェクトのルートを基準とした、バインド先のシミュレーションジオメトリです。 |
機能フラグ ¶
さらに一般的な機能フラグもあり、それらはほとんどの場合、特定のバインドタイプに固有です。 これらは、バインドで特定のメソッドを有効にするために必要となることもあります。 これらは、OpenCL SOPまたはDOPのいずれかのBindingsマルチパラメータのトグルに相当するため、詳細についてはそちらも参照してください。
フラグ |
意味 |
---|---|
fieldoffsets / nofieldoffsets |
デフォルトはfieldoffsetsです。 DOPのField Bindingsで、このフィールドのオフセットパラメータを有効にします。 |
forcealign / noforcealign |
デフォルトはforcealignです。 すべてのフィールドまたはボリュームが同じ解像度である必要があります。 これにより、コードがシンプルになるうえ、サンプルが揃っていると想定することが可能になります。 最初の書き込み可能なフィールドまたはボリューム(イテレートが行なわれるもの)はforcealignedであるべきではないので、デフォルトはnoforcealignです。 |
resolution / noresolution |
デフォルトはnoresolutionです。 フィールドまたはボリュームの解像度を含めます。 これは境界チェックに必要ですが、その他が揃っている場合は、通常最初のボリュームのみに必要です。 最初の書き込み可能なボリュームでは、デフォルトはresolutionです。 |
voxelsize / novoxelsize |
デフォルトはnovoxelsizeです。 ボリュームのボクセルのサイズを含めます。 |
xformtoworld / noxformtoworld |
デフォルトはnoxformtoworldです。 インデックス空間からジオメトリ(SOP)空間へのトランスフォームを含めます。 |
xformtovoxel / noxformtovoxel |
デフォルトはnoxformtovoxelです。 ジオメトリ(SOP)空間からインデックス空間へのトランスフォームを含めます。 |
Spareパラメータの作成 ¶
VEXでは、コード内に直接ch("myparm")
を含めることで、関数をインストルメント化(Spareパラメータから関数の値を編集できるように)することができます。
その後、パラメータ生成ボタンを押すと、VEXコードが実行時に読み込むmyparm
Spareパラメータが作成されます。
GPU上で実行されるOpenCLでは、すべてを明示的にバインドする必要があるため、ch("myparm")
と同等の機能を持つことができません。
そのため、似たことをする場合には、#bind parm myparm float
などの#bind
命令を追加することになります。
バインドされた値を実際に制御するには、Bindingsタブでバインドとしてmyparm
を手動で追加します。
それをFloatタイプに設定することで、Float値をそこでアニメーションさせて、OpenCLに渡される値を制御することができます。
作業を楽にするために、OpenCLノードのパラメータ生成ボタンがすべての#bind
命令を解析して、Bindingsページでそれらに呼応したエントリを作成しますが、マルチパラメータ値を駆動するコードの隣にSpareパラメータも作成します。
結果のSpareパラメータはOpenCLコードによって直接読み込まれないことに注意してください。
マルチパラメータの値を駆動し、その後そのマルチパラメータは実行前にカーネルにバインドされます。
トポロジーとグループバインド名 ¶
VEXにはバインド処理に影響を与えるいくつかのマジック名(便利機能を備えた予約済みの名前)があります。
例えば、@group_foo
はfoo
グループにバインドし、@opinput1_P
は2番目の入力のP
にバインドします。
OpenCLにもよく似たオプションがあります。
group:foo
アトリビュートへのバインドでは、foo
グループにバインドします。
バインドはInteger型である必要があります。
topo:
接頭辞を使用して、いくつかのトポロジーアトリビュートもサポートされています。
これらは、適切なクラスおよび型にバインドする必要があります。これらはすべて読み込み専用です。可能な限り、これらは呼応するVEX関数にほぼ一致します。
トポロジー名 |
クラス |
型 |
意味 |
---|---|---|---|
topo:primpoints |
prim |
|
プリミティブ番号によってインデックス化され、そのプリミティブに属するすべてのポイントインデックスを格納します。 |
topo:primvertices |
prim |
|
プリミティブ番号によってインデックス化され、そのプリミティブに属するすべての頂点インデックスを格納します。 |
topo:primvertexcount |
prim |
|
プリミティブ番号によってインデックス化され、そのプリミティブ上の頂点の数を格納します。 |
topo:pointprims |
point |
|
ポイント番号によってインデックス化され、そのポイントを参照するプリミティブインデックスを格納します。 |
topo:pointvertices |
point |
|
ポイント番号によってインデックス化され、そのポイントを参照する頂点インデックスを格納します。 |
topo:pointneighbours |
point |
|
ポイント番号によってインデックス化され、 |
topo:vertexpoint |
vertex |
|
頂点番号によってインデックス化され、頂点の参照先のポイントインデックスを格納します。 |
topo:vertexprim |
vertex |
|
頂点番号によってインデックス化され、頂点を所有しているプリミティブインデックスを格納します。 |
topo:vertexprimindex |
vertex |
|
頂点番号によってインデックス化され、この頂点が属するプリミティブ内の場所を格納します。 |
グローバルバインド ¶
VEXには、様々なデフォルトのバインドがあり、多くのWrangleに用意されています。 同様にOpenCLにもいくつかありますが、VEXはコード内にこれらが出現するとJust-In-Timeでバインドすることが多いのに対し、OpenCLではほとんどの場合、バインドを有効にするためには、ノード上で明示的に機能フラグを設定する必要があります。
バインド |
型 |
有効性 |
意味 |
---|---|---|---|
|
|
ボリューム、VDB、フィールドのいずれかに対して実行します。 |
現行の処理済みのボクセルの整数インデックス。 |
|
|
ボリューム、アトリビュート、VDBいずれかに対して実行します。フィールドが整列している場合、フィールドに対して実行します。 |
現行の処理済みのエレメントを表す整数インデックス。 VDBの場合、これはトポロジーによって異なることに注意してください。 |
|
|
フィールドに対して実行します。 |
処理済みのボクセルの現行のDOP/モデル空間。 |
|
|
ノードで指定されたTimeを含めます。 |
現行時間(秒)。ノードが時間依存になります。 |
|
|
ノードで指定されたTimestepを含みます。 |
現行のタイムステップ(通常はSOPで |
|
|
ノードで指定されたSimulation Frameを含めます。 |
現行のシミュレーションフレーム、 |
@-Bindingメソッド ¶
VEXでは、@バインドは実際の値です。
@Pは現行位置のベクトルであり、型はベクトルです。現行位置への書き出しは、単に@Pに割り当てるだけです。
現行ポイント以外のポイントの位置を使用する場合は、point
およびsetpointattrib
関数を使用します。
VEXでは、@バインドは実質的にローカル変数です。その変数への書き出しまたは読み込みは他の変数と同じです。 OpenCLでは、@バインドは計算量の増加につながるため、広範囲で使用する場合、通常はそれをローカル変数にコピーすると役立つことが多いです。
OpenCLでは、すべてのデータが明示的にバインドされている必要があるため、point
やsetpointattrib
関数で行なわれるような任意のアトリビュートへの書き出しや読み込みは不可能です。
しかしこれは、ポジションアトリビュートが@Pにバインドされている場合、すべての位置データが読み込み可能であることも意味します。
全データへのアクセスは、様々なメソッドを@バインドに追加することで実現します。
例えば、@P.getAt(53)
はインデックス53のポイントを読み込みます。これらのメソッドには範囲外アクセスチェックが含まれ、point
およびsetpointattrib
と同様に、プログラミングエラーによってカーネルが破滅的に失敗しないようになっています。
VEXのsetpointattrib
関数は、スレッドセーフになるように設計され、常に同じように作用します。それに呼応するOpenCLのsetAt
にはそのような保証はありません。2つのワークアイテムを同じポイントに書き出さないよう注意することが重要です。
利用可能なメソッドは、バインドのタイプ、バインド先のデータの型、データが読み込み可能なのか書き込み可能なのか、データが現行ワークアイテムに揃っているかどうかによって異なります。
特に、最後に加えておきたいのは、ポジションアトリビュートまたはマッチするアトリビュートに対して実行される場合のみ、@P
をRaw値とみなせることです。
そうでない場合、どのポイントにするのか指定する必要があります。
パラメータバインドメソッド ¶
parm
バインドは、それ自体が単なる値です。したがって、@name
は実際の値を参照するため、メソッドはありません。
ランプバインドメソッド ¶
OpenCLのランプは、常にfloatの1D配列で、ランプ値を取得するために補間されます。 ランプのサイズはバインド内で指定します。 ただし、用意されているメソッドのおかげで、データレイアウトの微妙な差異を気にする必要はありません。
メソッド |
意味 |
---|---|
|
実際のランプデータのfloat配列。 |
|
ランプのサイズ。 |
|
要求した0..1の位置でランプの値を調べ、サンプル間を補間します。 |
フィールドバインドメソッド ¶
ベクトルおよびマトリックスフィールドには、様々なコンポーネントを参照するための_x
および_xx
接尾辞があります。
そのため、バインド名がname
の場合、ベクトルフィールドには、ベクトルフィールドのx
フィールドのy
ストライド向けに@name.stride_x_y
があります。
実行されるフィールドと解像度およびトランスフォームが一致する場合、フィールドが揃えられます。
メソッド |
意味 |
---|---|
|
フィールドのそのままのfloatデータ。 |
|
データのX、Y、Z軸のステップのストライド。オフセットは、データから0,0,0ボクセルへのオフセットです。 |
|
フィールドのX、Y、Zの解像度。 |
|
現行の処理済みの値。揃っている場合、有効です。 |
|
インデックス位置X、Y、Zにおけるボクセル。 |
|
現行の処理済みのボクセルをvalに設定します。揃っている場合、有効です。 |
|
(x, y, z)におけるボクセルをvalに設定します。 |
|
|
アトリビュートバインドメソッド ¶
アトリビュートがジオメトリアトリビュート(ポイント、プリミティブ、頂点、ディテールなど)にバインドされます。
これらにはgroup:
接頭辞を持つグループと、topo:
接頭辞を持つトポロジーが含まれます。
アトリビュートのインデックスがマッチするのは、カーネルがアトリビュートに対して実行され、そのアトリビュートが実行を適用されているアトリビュートと同じクラスおよびサイズである場合です。
メソッド |
意味 |
---|---|
|
そのままのアトリビュートデータ。すべてのエレメントデータが、穴やページのない単一の配列に平坦化されます。配列アトリビュートでは、配列データは連続的に格納されます。 通常、これに直接アクセスすることはなく、境界チェックメソッドを提供する他のメソッドが使用されます。 |
|
アトリビュートの長さ。これは、アトリビュートが持つポイント、プリミティブ、頂点の数です。 |
|
現行インデックスのアトリビュート値。 読み込み可能な場合、有効です。配列でない場合、有効です。マッチするインデックスの場合、有効です。 |
|
特定のインデックスでアトリビュートを取得します。 読み込み可能な場合、有効です。配列でない場合、有効です。 |
|
現行インデックスでアトリビュート値を設定します。 書き込み可能な場合、有効です。配列でない場合、有効です。マッチするインデックスの場合、有効です。 |
|
指定したインデックスにおけるアトリビュートを値に設定します。 書き込み可能な場合、有効です。配列でない場合、有効です。 |
|
アトリビュートの各エレメントのサイズ。float型のアトリビュートのサイズは |
|
現行の処理済みのアイテムの配列へのポインタ。OpenCLのネイティブの型にマッピングしないアトリビュートサイズを使用する場合、これが便利ですエレメントにアクセスするには、 マッチするインデックスの場合、有効です。 |
|
インデックス |
|
アトリビュートがバインドされるかどうか。オプションのアトリビュートでは、バインドされる場合は1、されない場合は0にします。オプションでないアトリビュートは常にバインドされます。存在しない場合はカーネルが実行されないためです。 |
|
配列アトリビュートでは、現行インデックスのデータの特定のコンポーネントを抽出します。 配列の場合、有効です。マッチするインデックスの場合、有効です。 |
|
現行インデックスの配列の長さ。 配列の場合、有効です。マッチするインデックスの場合、有効です。 |
|
配列アトリビュートでは、特定のインデックスのデータの特定のコンポーネントを抽出します。 配列の場合、有効です。 |
|
インデックス 配列の場合、有効です。 |
ボリュームバインドメソッド ¶
ジオメトリ上のボリュームをバインドすることができます。
カーネルがボリュームに対して実行され、バインドされたボリュームがその解像度およびトランスフォームとマッチする場合、ボリュームのインデックスがマッチします。
ボリュームには、メソッドによって読み込み可能なバインド追加データを追加するためのフラグが多数あります。 特にボリュームが実行を適用されるボリュームと揃っていない場合、一部のメソッドでは追加のフラグが必要になることがあります。
メソッド |
意味 |
---|---|
|
ボリュームのそのままのデータ。 |
|
X、Y、Z軸のステップサイズと、 |
|
ボリュームの解像度。パディングされることが多いため、インデックスにストライドを使用する必要があることに注意してください。 |
|
各軸に沿った0,0,0ボクセルのサイズ。
|
|
ボクセルインデックスをモデル/SOP空間にマッピングする
|
|
モデル/SOP空間をインデックス空間にマッピングする
|
|
現行ボクセルインデックスにおけるボリュームの値。 読み込み可能な場合、有効です。マッチするインデックスの場合、有効です。 |
|
ボクセルのx、y、zがボリュームの境界内にある場合はTrueです。 |
|
ボクセル(x, y, z)での値を返します。ボリュームの範囲外の場合、インデックスはボリュームの範囲にクランプされます。 読み込み可能な場合、有効です。 |
|
現行の処理済みのボクセルを 書き込み可能な場合、有効です。マッチするインデックスの場合、有効です。 |
|
(x, y, z)におけるボクセルを 書き込み可能な場合、有効です。 |
|
インデックス空間 読み込み可能な場合、有効です。 |
|
インデックス空間 読み込み可能な場合、有効です。 |
VDBバインドメソッド ¶
ジオメトリ上のVDBをバインドすることができます。 OpenCLの世界のVDBは、NanoVDBレイアウトにトランスフォームされています。 CNanoVDBおよび類似のヘッダを使用してそれらに直接アクセスできますが、用意されているメソッドはアクセスパターンを簡略化するため、こちらの方が望ましいです。
VDBに対して実行され、VDBにマッチするトランスフォームがある場合、VDBのインデックスはマッチします。
VDBへの書き込みは可能ですが、書き込みを行なってもトポロジーは変更できません。 OpenCLの外部で既にアクティブ化されているボクセルにのみ書き込むことができます。
VDBには、メソッドによって読み込み可能なバインド追加データを追加するためのフラグが多数あります。 特にVDBが実行を適用されるVDBと揃っていない場合、一部のメソッドでは追加のフラグが必要になることがあります。
VDBは通常、float
またはfloat3
タグを使用して、タイプに明示的にバインドされます。タグが指定されていない場合、any
としてバインドされ、利用可能なメソッドが少なくなります。
メソッド |
意味 |
---|---|
|
そのままのNanoVDBデータ。 |
|
X、Y、Z軸でのVDB(0,0,0)ボクセルのサイズ。
|
|
インデックス空間からモデル/SOP空間への
|
|
モデル/SOP空間からインデックス空間への
|
|
現行の処理済みのインデックスでの値を返します。 読み込み可能な場合、有効です。マッチするインデックスの場合、有効です。 |
|
現行の処理済みインデックスのモデル/SOP位置を返します。 マッチするインデックスの場合、有効です。 |
|
現行の処理済みVDBインデックスがこのVDB上でアクティブかどうか。
|
|
指定されたX、Y、Zインデックス座標がアクティブかどうか。
|
|
指定されたX、Y、Zインデックス座標がアクティブかどうか。
|
|
インデックス(x, y, z)での値を返します。VDBは、非アクティブな領域に背景値を所有しているため、任意のインデックス上で実行することができます。
|
|
現行の処理済みのボクセルを値
|
|
インデックス(x, y, z)におけるボクセルを値
|
|
指定されたインデックス空間の位置において、VDBにトリリニア補間を行ないます。
|
|
指定されたモデル/SOP空間の位置において、VDBにトリリニア補間を行ないます。
|
|
指定されたモデル/SOP空間におけるVDBの勾配を計算し、モデル/SOP空間で勾配を返します。
|
オプションバインドメソッド ¶
シミュレーションデータのオプションは、DOP OpenCLノードによってバインドすることができます。
バインド先のデータは、geo
フラグによって制御します。どのオプションかは、name
フラグによって制御します。
メソッド |
意味 |
---|---|
|
指定したデータのオプションの値。 |