ADOBE® PIXEL BENDER LANGUAGE 1.0
チュートリアル・リファレンス
© 2008 Adobe Systems Inc.
Adobe, the Adobe logo, After Effects, Flash, and Pixel Bender are either registered trademarks or trademarks of Adobe Systems Inc. in the United States and/or other countries. All other trademarks are the property of their respective owners.
The information in this document is furnished for informational use only, is subject to change without notice, and should not be construed as a commitment by Adobe Systems Inc. Adobe Systems Inc. assumes no responsibility or liability for any errors or inaccuracies that may appear in this document. The software described in this document is furnished under license and may only be used or copied in accordance with the terms of such license.
Adobe Systems Inc., 345 Park Avenue, San Jose, California 95110, USA.
Pixel Benderは、画像処理アルゴリズムのハードウェアから独立した記述のために設計されたプログラミング言語です。それは、GPUとCPUのために能率的にマルチコアとマルチプロセッサシステムを含むバックエンドをコンパイルするように設計されています。最新の高性能ハードウェアの効果的な実行が並列処理を必要とするので、Pixel Benderプログラミングモデルははっきりとparallelです。
この文書は、Pixel Benderのためのチュートリアルと完全な参照です。言語は進化します;この文書の特徴は、Adobeが将来のバージョンで支持する最小のサブセットを組み立てます。
Flashプレイヤーソフトウェアが多種多様なハードウェアで動かなければならないので、Pixel BenderのサブセットだけはFlashプレイヤーのために利用できます。Flashプレイヤーでは入手不可能な特集は、この文書で示されて、終わりにまとめられます。
Pixel Benderは、画像処理のための拡張によるCのような言語です。(Pixel Benderは、GLSLに基づきます。そして、それは順番にCに基づきます。もしあなたがOpenGL/GLSLを知っているなら、あなたはPixel Benderプログラムがところどころ類似していると認めるかもしれません。幾何学またはvertex shadingの概念が、Pixel Benderにありません。)
Pixel Benderの基本的な構文は、どんなCプログラマーにでもなじみがなければなりません。この部門は、短くPixel Benderプログラミングの独特の特徴を導入します。それの後に、完全な言語参照が続きます。
Pixel Benderの画像処理の基本的な単位は、カーネルです。各々のPixel Benderプログラムは、1つのカーネルを定めます。複雑な画像処理しているアルゴリズムは、異なるカーネルを使用している複数のパスを必要とするかもしれません;これは、Pixel Bender Graph Language Referenceで記述されます。
おそらく異なる入力イメージから、カーネルは1つの出力ピクセルの結果を任意の数の入力ピクセルの関数と定義する物です。それはすべての望ましい出力ピクセルの上に並列(parallel)に実行されます。そして、出力イメージを出します。この並列したモデルが言いたいのは、カーネル関数の個々の呼び出し(invocation)の間の相互作用が出力ピクセルごとにないということです;ステートは、ピクセルで分配されることができません。これは、厳しい収縮モデル(strict"gather" model)として知られています:カーネルは、一つのピクセル出力を生じるために、複数の入力ピクセルの値を集めます。
最も単純なPixel Benderプログラムは、至る所にsolid colorを返すカーネルから成ります:
<languageVersion : 1.0;>
kernel FillWithBlack
{
output pixel4 result;
void evaluatePixel()
{
result = pixel4(0,0,0,0);
}
}
メンバ変数と関数で、カーネルはC++でクラスのように定められます。あらゆるカーネルは、少なくともタイプ [pixel] の [evaluatePixel] 関数と少なくとも1つの出力パラメータを提供しなければなりません。上記のカーネルは4つのチャンネル(例えば赤、緑、青、アルファ)とともに1つの出力イメージを生じます。そして、宣言 [output pixel4 result] によって定義されます。カーネルが出力イメージのすべてのピクセルのために実行されるので、各々のピクセル出力パラメータは全イメージを定めます。
我々は、fill colorを定めるために、パラメータをカーネルに加えることができます:
<languageVersion : 1.0;>
kernel FillWithColor
{
parameter pixel4 color;
output pixel4 result;
void evaluatePixel()
{
result = color;
}
}
カーネルは、任意のタイプの多くのパラメータをとることができます。パラメータはPixel Bender実行時システムに通過されます、そして、彼らの値はすべてのピクセル(3D shading languageで使われる「均一な」変数のような)の上に一定の状態に保たれます。カーネルが動作しているアプリケーションは、パラメータをカーネルに設定する若干の手段を提供します。
すべてのPixel Benderプログラムは、彼らが [languageVersion] 声明(statement)を使用して手紙を書かれるPixel Benderのバージョンを指定しなければなりません。
上記したように、正確に各々のピクセルのための同じパラメータの値で、カーネルは出力イメージのすべてのピクセルの上に平行(parallel)に実行されます。各々のピクセルで変わる唯一のものは現在の出力座標です。そして、[outCoord] 関数によってアクセスできます。この関数は、 [evaluatePixel] 関数の現在の呼び出し(invocation)によって評価されている出力ピクセルの中心の(x,y)座標を与えているタイプ[float2](2つのfloatのベクトル)の値を返します。現在の出力座標はイメージのピクセルの向こうで異なるが、どんな特定の呼び出しの有効期間の間でも、不変です。x軸が右まで増加するように、座標系はセットアップされます、そして、y軸は下に増加します。
ピクセルが、必ずしも四角いというわけではありません;多くのビデオアプリケーションは、四角でないピクセルを使います。どんな入力でもまたは出力イメージのためのピクセルの寸法は、[pixelSize]関数を使用しているのを発見されることができます。
我々は出力イメージ(例えばこのカーネル)でパターンを生じるカーネルを定めるために[outCoord]を使うことができます。そして、それは、指定された色と半径で、(非アンチエイリアスされた)満たされた円を原点をみたすようにします:
<languageVersion : 1.0;>
kernel RenderFilledCircle
{
parameter float radius;
parameter pixel4 color;
output pixel4 result;
void evaluatePixel()
{
float2 coord_for_this_pixel = outCoord();
float cur_radius = length(coord_for_this_pixel);
if (cur_radius < radius)
result = color;
else
result = pixel4(0,0,0,0);
}
}
このカーネルも、ベクトルタイプ [float2] とベクトル関数[length]の使用を示します。Pixel Benderは、ベクトルタイプと活動(operation)の豊かなセットを含めます;詳細は、16ページの上で「Pixel Bender reference」を見てください。
我々が出力イメージのサイズにリファレンスをつけなかったことに注意すべきです。Pixel Benderモデルにおいて、イメージは出力も入力も「サイズ」を持ちません。その代わりに、各イメージは別々のピクセル座標の無限平面上に定義されると考えられます。カーネルを呼び出す実行時機械(run-time machinery)は、作用されるピクセルが保存される実際のバッファサイズを測定します。「サイズ」のこの不足には、フィルタデザインへの含みがあります。たとえば、センターが未定義であるので、その「センター」のまわりでイメージを表すPixel Benderカーネルを記述することは可能でありません。その代わりに、カーネルは原点のまわりで反射(reflect)しなければなりません、あるいは、反射の線はカーネルパラメータとしてそれを通過することによってはっきりと意味されなければなりません。
対応して、Pixel Benderは世界的な座標系(global coordinate system)だけを持っています。座標系は四角くて均一です(等方性で、デカルトで、直角の)、そして、すべての入力と出力はそれに整列します。
我々のイメージがピクセルから成り立つので、我々はこれらのピクセルがどのように世界的な座標系で配置されるかわかっている必要があります。各々のイメージは、世界的な座標の各々のピクセルの寸法を定める関連するピクセルサイズを持ちます。これは非四角いピクセルを考慮に入れます、そして、影響はdownsamplingするのを好みます。与えられた入力または出力イメージのためのピクセルサイズは、[pixelSize]関数で得られることができます。便利な最適化として、所定のイメージのためにピクセル高さによって分けられるピクセル幅を返す[pixelAspectRatio]と呼ばれているメソッドが、あります。
座標変化は可能でありません;イメージは、出力格子にはっきりと再サンプリングされることによって変わります。この規制は厳しいようかもしれません、しかし、それは原子画像処理している活動が実際には実行しなければならない方法と一致します。カーネル実行の前に、座標系についてのより高度な推理(連結と追加注文すること(concatenation and redordering)のように連続した変換のような)は、より高いレベルで実行されなければなりません。
ここまで定められるカーネルには、イメージ入力がありません。そのようなカーネルは、sourceまたはgeneratorと呼ばれます。generatorの実際的な例は、手続き的なテクスチャールーチンです;しかし、大部分のカーネルは、一つ以上のイメージに入力を持っていきます。
適当なイメージのパラメータがタイプして、カーネルへの入力イメージは宣言されます。座標とともに、入力ピクセル値は、それから、いくつかのサンプリング関数のうちの1つにイメージパラメータを通過することによってアクセスされます。最も単純な考えられる、one-input/one-output カーネルは、イメージを不変のままにします:
<languageVersion : 1.0;>
kernel Identity
{
input image4 source;
output pixel4 result;
void evaluatePixel()
{
result = sampleNearest( source, outCoord() );
}
}
[sampleNearest]関数は所定の入力イメージにアクセスします。そして、指定された座標で、イメージパラメータによって意味されます。上記したように、すべての入力イメージは同じ座標系です。そして、それはまた、出力の座標系です;したがって、[outCoord]で入力イメージを試してみることは、現在の出力ピクセル(または「下に」)と一致しているピクセルの値を返します。
[outCoord]関数は世界的な座標系でコーディネートを返します、そして、サンプリング関数は世界的な座標系でコーディネートを受け入れます。隣接したピクセルを選ぶために、(プログラムの)著者は入力イメージのピクセルサイズを使わなければなりません。我々は、その近い左右の隣人(以下の通り)と平均で各々のピクセルであるカーネルを実装することができます:
<languageVersion : 1.0;>
kernel HorizontalAverage
{
input image4 source;
output pixel4 result;
void evaluatePixel()
{
float2 coord = outCoord();
float2 hOffset = float2(pixelSize(source).x, 0.0);
pixel4 left = sampleNearest(source, coord - hOffset);
pixel4 center= sampleNearest(source, coord);
pixel4 right = sampleNearest(source, coord + hOffset);
result = (left + center + right)/3.0;
}
}
[sampleNearest]が常に中間が所定の座標に最も近いピクセルの値を返す間、[sampleLinear]関数(それは、また、サンプルと呼ばれているかもしれません)は所定の座標に隣接して4ピクセルの間で二本の線の展開を実行します。言語が進化して、我々はより洗練されたフィルタリングの要請を加えると思っています。
カーネルは多くの入力画像を撮ることができます。そして、それぞれには異なる数のチャンネルがあることができます。以下のカーネルは、1チャンネルのマットによって4-チャンネルイメージを増やします:
<languageVersion : 1.0;>
kernel MatteRGBA
{
input image4 source;
input image1 matte;
output pixel4 result;
void evaluatePixel()
{
pixel4 in_pixel = sampleNearest( source, outCoord() );
pixel1 matte_value = sampleNearest( matte, outCoord() );
result = in_pixel * matte_value;
}
}
この例がデモをして、すべてのいろいろなサンプル関数は通過されたイメージと同じ正確にチャンネルの数のピクセル値を返します。
通常、Pixel Benderプログラムのすべての距離値は、世界的な座標系で測られます。これらは[outCoord]を含みます。そして、座標がサンプリング関数に通り過ぎられます、そして、regionがregion reasoningにおいて使われます。また、距離(例えばぼけの半径)を計るフィルタへのどんな入力でも、世界的な座標になければなりません。
Pixel Bender著者は、何に気づいているにちがいありませんか?
[pixelSize]と[pixelAspectRatio]関数は、Flashプレイヤーで利用できます;しかし、Flashプレイヤーは、常に1×1ピクセルを使います。
Pixel BenderがFlashプレイヤーで使われるとき、region関数は利用できません。
理論的には、Pixel Benderは無限のイメージに作用します;実際は、各々のイメージには有限次元があります(domain of definition, DODとして知られる)。そして、それの外で、それは未定義です。明確さの領域さえ、実は処理されているイメージより非常に大きいかもしれません;たとえば、非常により大きな文書の1枚のタイルを提出するならば。カーネルの任意のシーケンスを通して、実際的で効果的な画像処理を支持するために、実行時システムは、どのピクセルが実際にされた計算に参加するかについてわかっていなければなりません。これは、Pixel Benderカーネルの範囲内でregion関数の仕様を通してされます。
region関数はオプションです。何も供給されないならば、実行時システムがカーネルとみなすPixel Benderは、それが各々の入力から1つの入力ピクセルだけにアクセスすることを意味して、直接現在の出力ピクセルの下のpointwiseです。多くのカーネルは、先のセクションと[MatteRGBA]カーネルで示される発電機を含むpointwiseです。Pixel Bender実行時システムへの含みは、入力必要が望ましい出力と同じくらい正確に大きいだけであるということです。(望ましい出力サイズは無限のイメージ平面のサブセットです。そして、アプリケーション(カーネルライターでない)で測定されます。それは、domain of definition(「全部の」イメージ)または一つのタイルまたは他の部分区域と一致するかもしれません。)
多くの役に立つ画像処理している活動は、pointwiseでありません;たとえば、[HorizontalAverage]カーネルは、上記を定めました。このカーネルは、現在の出力ピクセルの右側に、左と1ピクセルまで1ピクセルにアクセスします。正しくピクセルの所定の出力長方形を計算することは、両側で、望ましい出力より正確に1ピクセル広い入力イメージを必要とします。Pixel Bender実行時システムがこれを知らないならば、それは画像データの余分の列を供給しません、そして、出力regionの左右の端のピクセルは誤って評価されます。この問題を解決するために、我々はどれくらいの入力ピクセルが所定の出力regionを計算することを要求されるかについて、Pixel Benderに話す[needed]関数を供給しなければなりません。
[needed]関数は、不透明な[region]タイプの対象を返します:
<languageVersion : 1.0;>
kernel HorizontalAverage
{
input image4 source;
output pixel4 result;
void evaluatePixel()
{
float2 coord = outCoord();
float2 hOffset = float2(pixelSize(source).x, 0.0);
pixel4 left = sampleNearest(source, coord - hOffset);
pixel4 center= sampleNearest(source, coord);
pixel4 right = sampleNearest(source, coord + hOffset);
result = ( left + center + right ) / 3.0;
}
region needed(
region output_region,
imageRef input_ref )
{
region result = output_region;
result = outset( result, float2(pixelSize(source).x, 0) );
return result;
}
}
[region]タイプに作用するために、[outset]関数の使用に注意してください。regionは普通の方向で算術式に参加することができません、しかし、カスタム関数のセットは彼らを扱うために提供されます。
[needed]関数は、常に[region]を返して、以下の引数をします:
出力region(別名「望ましい」か「要請された」region)は、計算されることになっている出力イメージの無限の平面の部分です;つまり、ピクセル値がカーネル関数を呼ぶことによって評価される平面の部分。言い換えると、出力regionは、実際に計算される出力イメージの「サイズ」です。この出力regionのすべてのピクセルを計算するためにアクセスされなければならない各々の入力から、[needed]関数の目的は、ピクセルのセットを決定することになっています。Pixel Bender実行時システムにより、それから、確実にすべてのこれらのピクセルが対応する[image]オブジェクトを通して評価されてアクセスに利用できることになります。このregionも、region of interest,ROIとして知られています。
カーネルには任意に多くの入力があることができます。そして、それぞれは同じ出力regionの計算のために異なる[needed]regionにアクセスすることができます。たとえば、カーネルは違って各々の入力を変換することができます。この理由から、[needed]関数は、ROIが計算されることになっている入力を示している参照を渡されます。[HorizontalAverage]には1つの入力だけがあるので、参照は常に「源(source)」という名のイメージに言及して、ここで無視されます。
各々の入力の明確さの領域も、region計算の間、利用できます。[needed]関数はどんなregionでも返すかもしれません、しかし、明確さの領域の内側のピクセルだけは実際に計算されます;言い換えると、ROIは明確さの領域に、常にとめられます。明確さの領域についての知識は、特定のoptimizationsにつながることができます。たとえば、マスクに対するカーネルマット1源ならば、明確さのマスク領域の内側の源のその部分だけが必要で、その逆です。我々は、上で伝えられる[MatteRGBA]カーネルのために[needed]関数を記述するために、この考えを使うことができます:
<languageVersion : 1.0;>
kernel MatteRGBA
{
input image4 source;
input image1 matte;
output pixel4 result;
region needed(
region output_region,
imageRef input_ref )
{
region result = output_region;
// clip to source
result = intersect( result, dod( source ) );
// and to mask
result = intersect( result, dod( matte ) );
return result;
}
void evaluatePixel()
{
pixel4 in_pixel = sampleNearest( source, outCoord() );
pixel1 matte_value = sampleNearest( matte, outCoord() );
result = in_pixel * matte_value;
}
}
組み込み関数[dod]はイメージかimageRefを供給されます、そして、それは世界的な座標系でそのイメージの明確さの領域を返します。[MatteRGBA]がpointwiseで、[needed]関数はカーネルの正しい活動のために必要でありません:それは、入力ごとに現在の入力ピクセルだけにアクセスします。しかし、[needed]関数を加えることは、実行時システムが単に離れて覆い隠される各々の入力から余分のピクセルを除くのを許可します。
最後に、非常に会員関数が囲んでいるクラスのメンバ変数にアクセスすることができて、[needed]関数は彼らに言及することによって簡単に他のカーネルパラメータにアクセスすることができます。関心のregionがカーネルパラメータ(例えば可変的なサイズconvolution)に基づいて異なる所で、これは役に立ちます:
<languageVersion : 1.0;>
kernel VariableHorizontalAverage
{
parameter int radius; // Measured in pixels
input image4 source;
output pixel4 result;
void evaluatePixel()
{
result = pixel4(0,0,0,0);
float2 hOffset = float2(pixelSize(source).x, 0.0);
for (int i=-radius; i<=radius; i++)
result += sampleNearest( source, outCoord()+ float(i) * hOffset );
result /= float( radius*2 + 1 );
}
region needed(
region output_region,
imageRef input_index )
{
region result = output_region;
result = outset( result, float2( radius * pixelSize( source ).x, 0 ) );
return result;
}
}
ある意味では、[changed]関数は、[needed]関数の逆です。入力region、入力DODとカーネルパラメータがあれば、[changed]は指定された入力regionのピクセルが変わるならば、影響を受けるかもしれないピクセルのセットを計算しなければなりません。たとえば、これはキャッシュ無効のために重要な重要性です。より明らかに、でなく、この関数も、DODのイメージの領域を計算するのに用いられます。[VariableHorizontalAverage]のためのこの[changed]関数の場合のように、[changed]関数の量は、しばしば類似しているか、[needed]関数とさえ同一です:
region changed(
region input_region,
imageRef input_index )
{
region result = input_region;
result = outset( result, float2( radius * pixelSize( source ).x, 0 ) );
return result;
}
しかし、これは必ずしも本当でありません。通常、非対称のカーネルは、[needed]と[changed]の間の反射を必要とします。イメージの幾何学的な変化を実行するカーネルは、これらの2つの関数の間で変換の感覚を逆にする必要があります。
[changed]関数が供給されないならば、変化はpointwiseファッションで伝播されるとされます。[needed]関数が正しい活動に供給されなければならないならば、これはたいていエラーです。例外があります、例えば、[MatteRGBA]カーネルは上で引数されるが、一般に[needed]と[changed]は一組として供給されなければなりません。
もう一つの関数は、一般的なケースのために必要です。一組のカーネルパラメータがあれば、[generated]関数は、たとえすべてのイメージ入力が完全に空であるとしても、ゼロ以外のピクセルが生産される出力のregionを説明します。この[RenderFilledCircle]generator カーネルの場合のように、カーネルが出力に何かを「与える」ときはいつでも、それは正しい活動のために必要です:
<languageVersion : 1.0;>
kernel RenderFilledCircle
{
parameter float radius;
parameter pixel4 color;
output pixel4 result;
void evaluatePixel()
{
float2 coord_for_this_pixel = outCoord();
float cur_radius = length(coord_for_this_pixel);
if (cur_radius < radius)
result = color;
else
result = pixel4(0,0,0,0);
}
region generated()
{
float r = ceil(radius);
return region(float4(-r, -r, r, r));
}
}
[generated]関数は必須の引数をしなくて、通常、その結果を計算するために若干のカーネルパラメータにアクセスする必要があります。出力のために制限用長方形を決定することは[radius]パラメータを使います。そして、それはそれから、(leftX、topY、rightX、bottomY)形の[region]オブジェクトを初期化するのに用いられます。
[RenderFilledCircle]が入力画像を撮らないが、[generated]は一つ以上の入力を処理するカーネルのためにさえ、必要とするかもしれません。通常、カーネルが入力について手続的に提出された物を合成するとき、これは起こります;例えば、ペンキ脳卒中またはレンズフレア。[generated]関数は、提出された物を含むregionを返さなければなりません;さもなければ、実行時システムは、それが入力イメージの境界の外で広がる全オブジェクトを含むために出力バッファを拡大するために知りません。
理論的には全ての無限の平面(ある種の手続き的なテクスチャー生成のような)の上に出力を生じるカーネルは、everywhere()に戻らなければいけない。
region関数は、すべてのケースのために正確な、ピクセル完全な境界を返すことになっていません。しばしば、正確な境界は難しいか、計算するのが不可能です。むしろ、返されたregionは、conservative boundsでなければなりません:彼らは、ピクセルの理想的な最小のセットを完全に含まなければなりません。境界をあまりに大きくする影響は、潜在的に無駄になる保管と計算です。境界がはなはだしく誇張されるならば、これは非常に悪くありえます、しかし、境界をあまりに小さくする影響はより悪いです:誤った計算。
結果の本当の境界が画像データに依存するケースが、あります;ここでさえ、境界は保守的でなければなりません。これの古典的な例は置換マップ効果です。そして、それは入力マップのピクセル値に基づくイメージを変えます。Pixel Benderでこの影響を表すために最大の可能な置換制限はセットされなければなりません(ユーザー制御可能なパラメータによれば、言ってください)、そして、この制限が境界計算の保守的な半径として使われます。
Pixel BenderがFlashプレイヤーで使われるとき、従属する値は利用できません。
ピクセル重量の手続的に発生するルックアップ表で、convolution活動を考慮してください:
<languageVersion : 1.0;>
kernel GaussianBlur
{
input image4 source;
output pixel4 result;
void evaluatePixel()
{
const float sigma = 2.0;
float weight0;
float weight1;
float weight2;
float weight3;
float weight4;
weight0 = exp( 0.0 );
weight1 = exp( -( 1.0 * 1.0 ) / sigma * sigma );
weight2 = exp( -( 2.0 * 2.0 ) / sigma * sigma );
weight3 = exp( -( 3.0 * 3.0 ) / sigma * sigma );
weight4 = exp( -( 4.0 * 4.0 ) / sigma * sigma );
// Use weights here
}
}
このコードには問題があります:ルックアップ表は、あらゆるピクセルで再生します。それは、ルックアップ表の点を否定します。我々はかつてこの配列を事前計算したくて、そしてそれをすべてのピクセルに適用します。我々はカーネルパラメータとして配列を渡すことができました、だが、我々はそれを計算するためにコードをどこかほかで必要とします。Pixel Benderは[dependent]メンバ変数と[evaluateDependents]関数を用いることによりこの問題を解決します。[dependent]として宣言される値は[evaluateDependents]の体の範囲内で初期化されます。そして、それは一度動きます;その後、[evaluatePixel]が適用されて、これらの値はリードオンリーであると思われて、すべてのピクセルの上に一定の状態に保たれます。上記のカーネルは、この方法(以下の通り)を走らせるために修正されることができます:
<languageVersion : 1.0;>
kernel GaussianBlur
< namespace : "AIF test";
vendor : "Adobe";
version : 1;
>
{
dependent float weights[ 5 ];
input image4 source;
output pixel4 result;
void evaluateDependents()
{
const float sigma = 2.0;
weights[ 0 ] = exp( 0.0 );
weights[ 1 ] = exp( -( 1.0 * 1.0 ) / sigma * sigma );
weights[ 2 ] = exp( -( 2.0 * 2.0 ) / sigma * sigma );
weights[ 3 ] = exp( -( 3.0 * 3.0 ) / sigma * sigma );
weights[ 4 ] = exp( -( 4.0 * 4.0 ) / sigma * sigma );
}
void evaluatePixel()
{
// use weights here as read-only data
}
}
Pixel Bender1.0は、いくつかの規制を従属する配列に押しつけます。最初に、フロートの配列だけは、支持されます。また、すべての配列サイズは、定数でなければなりません。Pixel Benderの将来のバージョンは配列がカーネルパラメータに基づくサイズで宣言されるのを許します。そして、それはパラメータに依存するルックアップ表サイズを可能にします。
Pixel BenderがFlashプレイヤーで使われるとき、支持関数は利用できません。
カーネルは、[evaluatePixel]または[evaluateDependents]から呼ばれる支持関数を含むことができます。
Pixel BenderがFlashプレイヤーで使われるとき、関数ライブラリは利用できません。
コード再利用を許すために、Pixel Benderは関数のライブラリの定義を支持します:
<languageVersion : 1.0;>
library Math
{
// Finds the real roots of a quadratic equation
// Returns the number of real roots
int quadratic(
float a,float b,float c,
out float root1,out float root2 )
{
int nRoots = 0;
float b2 = b * b;
float t = 4.0 * a * c;
if( b2 > t )
{
// Two roots
nRoots = 2;
float t1 = sqrt( b2 - t );
root1 = (-b + t1) / ( 2.0 * a );
root2 = (-b - t1) / ( 2.0 * a );
}
else if( b2 == t )
{
// One root
nRoots = 1;
root1 = -b / ( 2.0 * a );
}
return nRoots;
}
}
ライブラリ関数は少しのパラメータまたはdependentとのも直接の接触をしません、しかし、彼らは引数として渡されることができます。
カーネルまたはライブラリは、それを輸入して、それから捜し出された関数呼び出し構文を使っているその関数を呼ぶことによって、ライブラリを使うことができます:
<languageVersion : 1.0;>
kernel SmearedBlur
{
import Math;
input image4 src;
output pixel4 dst;
void evaluatePixel()
{
float a, b, c, root1, root2;
// Do something to set up a, b and c here
int nRoots = Math::quadratic( a, b, c, root1, root2 );
// Do something useful with the results here
}
}
ライブラリは、他のライブラリをインポートすることもできます;しかし、ライブラリの再帰的に重要であることは、許されません。
カーネルの様に、ライブラリは彼らが[languageVersion]statementを使用して手紙を書かれるPixel Benderのバージョンを指定しなければなりません。
[RotateAndComposite]は、1つの入力を変換して、もう一つの上でそれを合成するカーネルです。予め計算された変化マトリックス(違って扱われる複数の入力)を持つことはdependentの利用を示します、そして、より複雑なregionは関数します。マトリックスは、コラム主な順序に保管されます;より多くの詳細のために、16ページの上で「Pixel Bender参照」を見てください。
<languageVersion : 1.0;>
kernel RotateAndComposite
{
parameter float theta; // rotation angle
parameter float2 center; // rotation center
dependent float3x3 back_xform;// rotation matrix (from dest->src)
dependent float3x3 fwd_xform; // and inverse
input image4 foreground;
input image4 background;
output pixel4 result;
// Compute the transform matrix and its inverse
void evaluateDependents()
{
// translate center to origin
float3x3 translate = float3x3(
1, 0, 0,
0, 1, 0,
-center.x, -center.y, 1 );
// rotate by theta
float3x3 rotate = float3x3(
cos(theta), sin(theta), 0,
-sin(theta), cos(theta), 0, 0, 0, 1 );
// compose to get complete fwd transform
fwd_xform = -translate*rotate*translate;
// get inverse rotation (by negating sin terms)
rotate[0][1] = -rotate[0][1];
rotate[1][0] = -rotate[1][0];
// compose to get complete back transform
back_xform = translate*rotate*-translate;
}
// Main function transforms outCoord to find foreground pixel
void evaluatePixel()
{
// background coordinate is just destination coordinate
float2 bg_coord = outCoord();
// foreground coordinate is transformed outCoord
// note up-conversion to float3, then we drop w with a swizzle
float2 fg_coord =
(back_xform*float3(bg_coord.x, bg_coord.y, 1)).xy;
// alpha blend foreground over background
pixel4 bg_pixel = sampleNearest(background, bg_coord);
pixel4 fg_pixel = sampleLinear(foreground, fg_coord);
result = mix(bg_pixel, fg_pixel, fg_pixel.a);
}
// needed function is different depending on which input region needed(
region output_region,
imageRef input_index )
{
region result;
if( input_index == background )
{
// background is untransformed, so just pass through
result = output_region;
}
else
{
// transform output region into foreground space
result = transform( back_xform, output_region );
}
return result;
}
// changed function is like needed function but with different
// transform sense
region changed(
region input_region,
imageRef input_index )
{
region result;
if( input_index == background )
{
result = input_region;
}
else
{
result = transform( fwd_xform, input_region );
}
return result;
}
}
このセクションは、Pixel Bender 1.0言語のための完全な参照です。それは、クライアントとメーカーのためのマスター仕様を意図します。通常、Pixel Bender構文はGLSLに続きます。そして、それは順番にCに基づきます。
各々のPixel Benderプログラムは1文字列によって指定されます。そして、[languageVersion]statementと1つのカーネルを含みます。
[languageVersion]statementは、以下の形のメタデータの一つの部分です:
< languageVersion :value; >
値が浮動小数点である所で、このプログラムが記述されるPixel Benderのバージョンと一致することを評価してください。
A kernel contains:
正式に、カーネルはこの構文で指定されます:
kernelname
[kernel_metadata]
{
kernel_members
}
[kernel_metadata]はオプションです。指定されるならば、それは曲げられたブレースに入れられる一連の名前-値組から成ります:
parametertypename
<
name1 :value1;
name2 :value2;
...
>;
名前は、埋め込まれたスペースのないテキスト文字列です。値は定数で、二重の引用符によって区切られる整数またはstringでなければなりません;他のいかなるタイプも、値に対してサポートされません。
kernel Sample
<
namespace : "Adobe Image Foundation";
vendor : "Adobe";
version : 1;
description: "My Filter";
>
{
void evaluatePixel()
}
[kernel_member]は、以下の通りに定められます。詳細は、次のregionにあります。
[import_statement] | [kernel_parameter] | [kernel_dependent] |
[kernel_constant] | [input_image] | [output_pixel] |evaluatePixel_function | [evaluateDependents_function] | [needed_function] | [changed_function] | [generated_function] | [other_functions]
[evaluatePixel]関数だけは必要です。
Cプリプロセッサ指令[#define]、[#undef]、[#ifdef]と[#if]は、条件つきの編集を支持するために提供されます。我々は、[const]値を一定の定義に推薦します。
[import_statement]には、この構文があります:
importlibrary_name;
所定のライブラリに含まれるすべての関数は、捜し出された関数呼び出し構文を使って呼ばれるために、それから利用できます。
[kernel_parameter]または[kernel_dependent]には、この構文があります:
qualifier type name;
[qualifier]は、変数がどのようにセットされて、使われるかについて指定します。それは必要です、そして、それは以下のうちの1つでなければなりません:
[kernel_parameter]は、メタデータをそれに付けておくことができます。このメタデータは編集の後、利用できるようにされて、クライアントプログラムがパラメータが何のためにあるか、そして、それにどんな相応な値がかかることができるか理解するのを助けることができます。
指定されるならば、メタデータはすぐに変数の名前に続いて、曲げられたブレースに入れられる一連の名前-値の組から成ります:
parametertype name
<
name1 :value1;
name2 :value2;
...
>;
[name]は、stringです。値は、どんな有効なPixel Benderタイプ([int]、[float]と[bool]のために、タイプは自動的に演繹されます、なぜならば、他のタイプは正しいタイプ(例えば[float2( 1.0、-1.0 )] )の定数を指定します)の定数または二重の引用符によって区切られるストリングでもあります;たとえば:
parameter int angle
<
minValue : 0;
maxValue : 360;
defaultValue : 30;
description : "measured in degrees";
>;
カーネル定数には、この構文があります:
consttype name =compile_time_expression;
定数の値は、コンパイル時で測定されます。
入力イメージには、この構文があります:
inputtype name;
[type]は、[image1]、[image2]、[image3]または[image4]でなければなりません。
出力ピクセルは、以下の通りに定められます:
outputtype name;
[type]は、[pixel1]、[pixel2]、[pixel3]または[pixel4]でなければなりません。
[evaluatePixel]カーネル関数は、各々のピクセルで、平行で、実行される処理を定めます。[evaluatePixel]カーネル関数(そして、それが呼ぶすべての関数)は、すべてのparameterとdependentへの読出し専用アクセスをし、すべての入力イメージへの接近を読んで、すべての出力ピクセルにアクセスを書きます。[evaluatePixel]は、以下の通りであると宣言されます:
void evaluatePixel()
{
statements
}
[evaluateDependents]関数も引数をしません。[dependent]変数は[evaluateDependents]関数の処刑だけの間、または、その実行の間、[evaluateDependents]によって呼ばれる関数だけで書かれることができます。[evaluateDependents]は以下の通りであると宣言されます:
void evaluateDependents()
{
statements
}
[needed]関数は、regionを返します。関数は、2つの一定の引数をします。すべてのregion関数は、パラメータとdependentを読み込むことができます、しかし、彼らはイメージ入力(彼らがdodがイメージに基づいて働くと叫ぶことができるが)を経験してみることができなくて、regionを返さなければなりません。必要とします以下の通りに宣言します:
region needed( regionname, // requested output region
imageRefname) // reference to an image
{
statements
}
[changed]関数は類似しています:
region changed(
regionname, // changed input region
imageRefname ) // reference to an image
{
statements
}
generated関数は、引数(region戻り値だけ)をしません:
region generated()
{
statements
}
任意の数のさらなるカーネル関数は、定められることができます。これらの全ては、彼らの訪問している親(すなわち、[evaluateDependents]から呼ばれる関数だけは、[dependent]変数まで書くことができます)から、アクセス規制をとります。構文は以下の通りです:
return_typename([arguments])
{
statements
}
引数があるところ
[in|out|inout]type name
[out]予選は引数が基本的に戻り値であることを示します。そして、関数に入場と同時に初期化されていません。inout予選は類似しているが、入場に関して発信者の値まで初期化されます;基本的に、それはパス-副参照メカニズムです。両方とも、呼び出しサイトで値を供給されなければなりません。さもなければ、すべての引数は、値によってされます。デフォルト予選通過者は[in]です。
すべての関数は負担をかけられすぎます;それはそうです。そして、名前と同様に引数タイプによってマッチされます。C++とは異なり、合うことが関数にオーバーロードしたとき、潜在的な型変換は実行されません。すべての関数は、訪問する前に定められなければなりません;前の宣言がありません。Pixel Benderは、再帰的な関数呼び出しを支持しません。関数は、普通のCの表記規則によって挙げられることができます。アンダーライン(_)から始めるすべての関数名が、予約済で、使われることができるというわけではありません。
FlashPlayerでPixel Benderが[if]または[else]に使われたときのみflow-control statementsは利用できる。
普通のC構文で、以下のフロー制御構造物は、Pixel Benderでサポートされます:
if (scalar_expression)true_statement
if (scalar_expression)true_statement elsefalse_statement
for (initializer;condition;incremental)statement
while (condition)statement
dostatement while (condition);
break;
continue;
returnexpression;
[evaluatePixel]から呼ばれる[evaluatePixel]と関数では、Pixel Benderが条件文またはループの量の中に復帰声明を支持しない点に注意してください。
声明も、表現でありえます:
expression
または可変的な宣言(初期化される):
type name;
[const]type name =expression;
変数は関数の中にどこでも宣言されることができて、ブレースの囲んでいるセット内部に、範囲を持つことができます。C++のように、変数も中をイニシャライザを宣言されることができます、ループまたは条件文は試験しますループ条件つきのテストの範囲内で以外、でない?の声明。変数は、同じ名前の他の変数をより外の範囲に隠すことができます。表現がコンパイル時定数である場合だけ、const予選は適用されることができます。変数は、普通のCの表記規則によって名をつけられることができます。アンダーライン(_)から始めているすべての変数名が、予約済で、使われることができるというわけではありません。
Cの場合のように、ブレースの中に、声明も上記のタイプの一連の声明でありえます:
{
statement
[statement...]
}
Pixel Benderは、強く入力されます。浮動小数点ベクトルとマトリックスタイプの構築の間の肝要な昇進の一つの例外でも、自動転換が、タイプの間にありません。タイプのいくつかの種類があります。そして、各々がオペレーターと組み込み関数の特定のセットに関して定められます。
Pixel Benderは、基本タイプとしてbool、intと変動相場制をサポートします。
intタイプは少なくとも16ビットの精度(サインを含まない)を持たなければなりません、しかし、実施は16ビット以上を使うことができます。実施は、それに作用するために、intをフロートに変えることができます。int活動(フロートから転換を含む)の結果がintとして描写されることができないとき、ふるまいは未定義です。
フロートタイプは、精度とダイナミックレンジでIEEE単精度浮動小数点定義に匹敵します。内部の処理の精度は浮動小数点演算でIEEE浮動小数点仕様に匹敵することを要求されません、しかし、精度のためのガイドラインはOpenGLによって1.4の仕様が満たされなければならないと確認しました。
1ピクセルのタイプも供給されます。そして、イメージの1つのチャンネルの値を意味するのに用いられます:
pixel1
単に、曖昧さを避けるために、ピクセルとは対照的に、一つの要素ピクセルタイプがpixel1と呼ばれていることに注意すべきです:複数のチャンネルを含んで、一つの「ピクセル」は通常考えられます。すべてのbool、フロート、intとピクセルタイプは、算術演算に参加することができます;しかし、ピクセルタイプがいくぶん抽象的であるので、ピクセル算数は特別です。編集オプションに従い、ピクセルチャンネルは、8ビットの整数、16ビット整数または32ビット浮動小数点値であるかもしれません。算数規則は、これらのフォーマットの各々で変化します;たとえば、8ビットのケースでは、2ピクセルのタイプの掛け算は、255だけ潜在的な分割を含みます。
bool、フロートとintは次から次へと変わることができます。そして、以下のキャスト構文で、普通のCスタイルの打ちきりと昇進規則を使います:
type(expression)
例:
int a = int(myfloat)
ピクセルタイプは、(あるいは、から)フロートだけに変わることができます。整数ピクセルタイプからの転換は、範囲でフロートを生産します[0…1]、フロートから整数ピクセルタイプへの転換が暗黙のうちにまわりを回られて、とまられるのに対して、[0…255]、あるいは、[0…32768]。下にあるピクセル算数根は、基本的にそうです編集しますオプション、そして、カーネルメーカーに利用できません。
26ページの上で「演算子」で記述されて、すべての普通の算術演算子はスカラータイプについて定められます。セクション。
Pixel Benderは、以下のスカラータイプの2-、3-と4-要素ベクトルを供給します:
float2 bool2 int2 pixel2
float3 bool3 int3 pixel3
float4 bool4 int4 pixel4
ベクトルタイプ(ピクセルを含む)は、以下の建造者構文を使って初期化されることができます:
vector_type(element1 [, element2…])
例:
float3(0.5, 0.6, 0.7)
この表現は挙げられたタイプの値に終わります。そして、それが変数に割り当てられることができるか、無名の結果として直接使われることができます。
ベクトル要素アクセスは、下に書かれた演算子を通してされます:
vector_value[integral_index]
またはこれらのシーケンスの挙げられた要素として:
これらの名前の各々は、ゼロから3までインデックスと一致します。
vector_value.r|g|b|a|x|y|z|w|s|t|p|q
Pixel Benderも、「がぶ飲みする」ことにベクトル要素を選んで、再び整理させておきます。n要素によるベクトル値のために、(r,g,b,a,x,y,z,w,s,t,p,q)缶からのnインデックスまで、点演算子の後で指定されてください。ベクトル値の対応する要素は、インデックス指示子と同じくらい多くの要素で新しいベクトル結果を作るために連結されます。この構文は、要素を再び整理するか、取り外すか、繰り返すのに用いられることができます;たとえば:
float4 vec4;
float3 no_alpha = vec4.rgb; // 最後の構成要素を下げる
float3 no_r = vec4.gba; // 最初の構成要素を下げる
float4 reversed = vec4.abgr; // 逆の命令
float4 all_red = vec4.rrrr; // 要素を繰り返す
float4 all_x = vec4.xxxx; // all_redとして同じである
別々のシーケンスからのインデックスは、結合されることができません:
float4 vec4;
float3 no_alpha = vec4.rgz; // エラー
インデックス指示子も、任務の左側で、変数に適用されることができます。この場合、インデックスは繰り返されることができません。この関数は、write-maskingすることをインプリメントするのに用いられます。要素の正しい数は、右側で供給されなければなりません。
float3 vec3;
float2 vec2;
vec3.xy = vec2; //vec3[0]とvec3へのvec2の要素を割り当てる[1]
vec3.xz = vec2; //vec3[0]とvec3へのvec2の要素を割り当てる[2]
がぶ飲みして、write-maskingすることは、表現の両側で同時に使われることができます:
vec3.xz = vec4.wy;
がぶ飲みすることと割当て活動の間の潜在的に厄介な相互作用が、あります。以下の表現を考慮してください:
g.yz *= g.yy;
これの単純な拡大は、以下のように見えます:
g.y *= g.y;
g.z *= g.y;
これに関する問題は、第2の表現において使われるg.yの値が修正されたということです。最初の声明の正しい拡大は、以下の通りです:
float2 temp = g.yz * g.yy;
g.yz = temp;
つまり、g.yの最初の値が、両方の重複のために使われます;両方の重複がされるまで、g.yは更新されません。
ベクトルの寸法が等しいならば、ベクトルタイプの間の転換は上述のスカラー構文を使って可能です:
float3 fvec3;
int3 ivec3;
fvec3 = float3(ivec3);
大部分のスカラー算術演算子は、構成要素-賢者に手術を施しながら、ベクトルについて定められます。詳細は、26ページの上で「オペレーター」に会ってください。
以下のマトリックスタイプは利用できます:
float2x2
float3x3
float4x4
マトリックス値は、コラム値を記述しているフロートベクトルまたはコラム-上級聖品の各々の要素またはベクトルとフロートの混成を示しているフロートから建造者構文を使って発生することができます:
float2x2(float2,float2)
float2x2(float,float,
float,float)
float3x3(float3,float3,float3)
float3x3(float,float,float,
float,float,float,
float,float,float)
float4x4(float4,float4,float4,float4)
float4x4(float,float,float,float,
float,float,float,float,
float,float,float,float,
float,float,float,float)
マトリックスも一つのフロートから初期化されることができます。そして、それは主要な斜線で要素を定めます。他の全ての要素は、ゼロに設定されます。
float2x2(float)
float3x3(float)
float4x4(float)
マトリックス要素は二重の添え字を使ってアクセスされます。そして、コラムが最初です:
matrix[column][row]
列添え字が省略されるならば、一つのコラムは選ばれます、そして、結果として生じるタイプは適当な局面のフロートベクトルです:
matrix[ column]
オペレーターがそうであるスカラーの小さなセットはマトリックスのために定義しました。そして、それは構成要素-賢者、マトリックス/マトリックスとマトリックス/ベクトル演算を実行します。詳細は、26ページの上で「オペレーター」に会ってください。
regionタイプは、以下の通りであると宣言されます:
region
長方形のregionは、左で、一番上で、適切で、一番下の境界を表しているfloat4から造られることができます:
region(float4_bounds)
regionのために定められるオペレーターが、いません;その代わりに、regionは一組の専門関数(下記参照)によって操られます。
Pixel Bender1.0は、最高4つのチャンネルのイメージを支えます。
image1 image2
image3
image4
イメージが、表現において造られることができないか、使われることができません;しかし、彼らはユーザー定義の関数に対する引数として追い越されることができるか、dod関数に対する引数で通りました。
imageRefタイプが、必要とされて[changed]関数が彼らが動いている入力イメージを選ぶのを許可するために存在します。imageRef変数の2つの用途だけが、あります:
Pixel BenderがFlashプレイヤーで使われるとき、配列は利用できません。
Pixel Bender1.0は、配列に対する支持を制限しました。以下の配列だけは許されます:
「恒常的なサイズ」は、配列サイズがコンパイル時定数であることを意味します。配列のサイズがカーネルパラメータに依存する方法が、ありません。(Pixel Benderの将来のバージョンは配列がカーネルパラメータに基づくサイズで宣言されるのを許します。そして、それはパラメータに依存するルックアップ表サイズを可能にします。)
配列は、普通のC構文を通して宣言されて、アクセスされます:
type name[ size ];
name[ subscript ]
宣言されたサイズ引く1より0以上未満の添え字で配列にアクセスする結果は、未定義です。
Pixel Bender1.0は、一次元の配列だけを支持します。
値が空所で宣言されなければならないと答えない関数は、活字を返します。空所の他のいかなる法律用途も、Pixel Benderの中でありません。
最も低い優先順位への最高のものの順に、彼らの普通のC意味で、Pixel Benderは、スカラータイプについて以下の算術演算子を定めます:
|
. |
Member selection |
|
++ -- |
Postfix increment / decrement |
|
++ -- |
Prefix increment decrement |
|
- ! |
Unary negation, logical not |
|
* / |
Multiply, divide |
|
+ - |
Add, subtract |
|
< > <= >= |
Relational |
|
== != |
Equality |
|
&& |
Logical and |
|
^^ |
Logical exclusive or |
|
|| |
Logical inclusive or |
|
?: |
Selection |
|
= += -= *= /= |
Assignment |
Pixel BenderがFlashプレイヤーで使われるとき、選択オペレーターは2つの定数または変数の間で選ぶだけのことに慣れていることができます。あなたは、一般的な表現を選択の右側に置くことができません。
括弧は、優先順位を越えるのに用いられることができます。
に関係なく、評価が「論理的である、そして」のために運転中であることを短絡させるかどうかに関係なく、「論理的な含んでいる、あるいは」は未定義です。あなたが要求するならば、存在する(または不在の)評価を短絡させてください、あなたはそれをはっきりとコード化しなければなりません。
標準的な算術演算子(+-*、/)が、また、ベクトル、マトリックスとスカラーの組合せで使われることができます。バイナリのオペレーターが2つのベクトル量に適用されるならば、まるでそれが媒体動物の各々の構成要素に適用されたように、活動はふるまいます;たとえば:
float3 x, y, z;
z = x + y;
is equivalent to:
z[ 0 ] = x[ 0 ] + y[ 0 ];
z[ 1 ] = x[ 1 ] + y[ 1 ];
z[ 2 ] = x[ 2 ] + y[ 2 ];
(2本のベクトルは、同じサイズを持たなければなりません。)
スカラーをベクトルとも結合することは、可能です。例:
float3 x, y;
float w;
x = y * w;
is equivalent to:
x[ 0 ] = y[ 0 ] * w;
x[ 1 ] = y[ 1 ] * w;
x[ 2 ] = y[ 2 ] * w;
この構成要素的な活動に対する重要な例外は、マトリックスの間の重複とマトリックスとベクトルの間の重複です。これらは、標準的な線形代数重複(構成要素的な重複でない)を実行します:
|
float2x2 * float2x2 float3x3 * float3x3 float4x4 * float4x4 |
Linear-algebraic matrix multiplication |
|
float2x2 * float2 float3x3 * float3 float4x4 * float4 |
Column-vector multiplication |
|
float2 * float2x2 float3 * float3x3 float4 * float4x4 |
Row-vector multiplication |
Pixel Benderは、異なるタイプについていろいろな組み込み関数をサポートします。
算術演算子と同様に、数学的な関数はベクトルに印加されることができます、その場合には、彼らは構成要素的なファッションで行動します。さもなければ述べられない限り、すべての角度はラジアンで測定されます。
|
float radians( float degrees ) float2 radians( float2 degrees ) float3 radians( float3 degrees ) float4 radians( float4 degrees ) |
Converts degrees to radians. |
|
float degrees( float radians ) float2 degrees ( float2 radians ) float3 degrees ( float3 radians ) float4 degrees ( float4 radians ) |
Converts radians to degrees. |
|
float sin( float radians ) float2 sin( float2 radians ) float3 sin( float3 radians ) float4 sin( float4 radians ) |
Returns the sine of the input. |
|
float cos( float radians ) float2 cos( float2 radians ) float3 cos( float3 radians ) float4 cos( float4 radians ) |
Returns the cosine of the input. |
|
float tan( float radians ) float2 tan( float2 radians ) float3 tan( float3 radians ) float4 tan( float4 radians ) |
Returns the tangent of the input. |
|
float asin( float x ) float2 asin( float2 x ) float3 asin( float3 x ) float4 asin( float4 x ) |
Returns the arc sine of the input. The result will be in the range [-π/2,π/2] |
|
float acos( float x ) float2 acos( float2 x ) float3 acos( float3 x ) float4 acos( float4 x ) |
Returns the arc cosine of the input. The result will be in the range [0,π]. |
|
float atan( float y_over_x ) float2 atan( float2 y_over_x) float3 atan( float3 y_over_x) float4 atan( float4 y_over_x) |
Returns the arc tangent of the input. The result will be in the range [-π/2,π/2]. |
|
float atan( float y, float x ) float2 atan( float2 y, float2 x ) float3 atan( float3 y, float3 x ) float4 atan( float4 y, float4 x ) |
Returns the arc tangent ofy /x. The result will be in the range [-π,π]. |
|
float pow( float x, float y ) float2 pow ( float2 x, float2 y ) float3 pow ( float3 x, float3 y ) float4 pow ( float4 x, float4 y ) |
Returnsxy. |
|
float exp( float x ) float2 exp( float2 x ) float3 exp( float3 x ) float4 exp( float4 x ) |
Returnsex. |
|
float exp2( float x ) float2 exp2( float2 x ) float3 exp2( float3 x ) float4 exp2( float4 x ) |
Returns2x. |
|
float log( float x ) float2 log( float2 x ) float3 log( float3 x ) float4 log( float4 x ) |
Returns the natural logarithm ofx. |
|
float log2( float x ) float2 log2( float2 x ) float3 log2( float3 x ) float4 log2( float4 x ) |
Returns the base 2 logarithm ofx. |
|
float sqrt( float x ) float2 sqrt( float2 x ) float3 sqrt( float3 x ) float4 sqrt( float4 x ) |
Returns the positive square root ofx. |
|
float inverseSqrt( float x ) float2 inverseSqrt( float2 x ) float3 inverseSqrt( float3 x ) float4 inverseSqrt( float4 x ) |
Returns the reciprocal of the positive square root ofx. |
|
float abs( float x ) float2 abs( float2 x ) float3 abs( float3 x ) float4 abs( float4 x ) |
Ifx >= 0, returnsx, otherwise returns -x. |
|
float sign( float x ) float2 sign( float2 x ) float3 sign( float3 x ) float4 sign( float4 x ) |
Ifx < 0, returns -1 Ifx == 0, returns 0 Ifx > 0, returns 1 |
|
float floor( float x ) float2 floor( float2 x ) float3 floor( float3 x ) float4 floor( float4 x ) |
Returnsy such thaty is the nearest integer wherey <=x. |
|
float ceil( float x ) float2 ceil( float2 x ) float3 ceil( float3 x ) float4 ceil( float4 x ) |
Returnsy such thaty is the nearest integer wherey >=x. |
|
float fract( float x ) float2 fract( float2 x ) float3 fract( float3 x ) float4 fract( float4 x ) |
Returnsx – floor(x). |
|
float mod( float x, float y ) float2 mod( float2 x, float2 y ) float3 mod( float3 x, float3 y ) float4 mod( float4 x, float4 y ) |
Returnsx –y * floor(x/y) |
|
float2 mod( float2 x, float y ) float3 mod( float3 x, float y ) float4 mod( float4 x, float y ) |
Returnsx –y * floor(x/y) |
|
float min( float x, float y ) float2 min( float2 x, float2 y ) float3 min( float3 x, float3 y ) float4 min( float4 x, float4 y ) |
Ifx <y, returnsx, otherwise returnsy. |
|
float2 min( float2 x, float y ) float3 min( float3 x, float y ) float4 min( float4 x, float y ) |
Ifx <y returnsx, otherwise returnsy. |
|
float max( float x, float y ) float2 max( float2 x, float2 y ) float3 max( float3 x, float3 y ) float4 max( float4 x, float4 y ) |
Ifx >y, returnsx, otherwise returnsy. |
|
float2 max( float2 x, float y ) float3 max( float3 x, float y ) float4 max( float4 x, float y ) |
Ifx >y, returnsx, otherwise returnsy. |
|
float step( float x, float y ) float2 step( float2 x, float2 y ) float3 step( float3 x, float3 y ) float4 step( float4 x, float4 y ) |
Ify <=x, returns 0.0, otherwise returns 1.0 |
|
float clamp(float x, float minval, float maxval) float2 clamp(float2 x, float2 minval, float2 maxval) float3 clamp(float3 x, float3 minval, float3 maxval) float4 clamp(float4 x, float4 minval, float4 maxval) |
Ifx<minval, returnsminvalIfx>maxval, returns maxvalotherwise returnsx. |
|
float2 clamp(float2 x, float minval, float maxval) float3 clamp(float3 x, float minval, float maxval) float4 clamp(float4 x, float minval, float maxval) |
Ifx<minval, returnsminvalIfx>maxval, returns maxvalotherwise returnsx. |
|
float mix(float x, float y, float a) float2 mix(float2 x, float2 y, float2 a) float3 mix(float3 x, float3 y, float3 a) float4 mix(float4 x, float4 y, float4 a) |
Returnsx * (1.0 -a) +y *a. (i.e. linear interpolation between x and y) |
|
float2 mix(float2 x, float2 y, float a) float3 mix(float3 x, float3 y, float a) float4 mix(float4 x, float4 y, float a) |
Returnsx * (1.0 -a) +y *a. (i.e. linear interpolation between x and y) |
|
float smoothStep(float edge0, float edge1, float x) float smoothStep(float2 edge0, float2 edge1, float2 x) float smoothStep(float3 edge0, float3 edge1, float3 x) float smoothStep(float4 edge0, float4 edge1, float4 x) |
Ifx <=edge0, returns 0 Ifx >=edge1, returns 1, otherwise performs smooth hermite interpolation. |
これらの関数は、ベクトル(個々に媒体動物の各々の構成要素を扱うことよりむしろ)として、ベクトルに作用します。
|
float length(float x) float length(float2 x) float length(float3 x) float length(float4 x) |
Returns the length of the vectorx |
|
float distance(float x, float y) float distance(float2 x, float2 y) float distance(float3 x, float3 y) float distance(float4 x, float4 y) |
Returns the distance betweenx andy |
|
float dot(float x, float y) float dot(float2 x, float2 y) float dot(float3 x, float3 y) float dot(float4 x, float4 y) |
Returns the dot product ofx andy |
|
float3 cross(vector3 x, vector3 y) |
Returns the cross product ofx andy |
|
float normalize(float x) float2 normalize(float2 x) float3 normalize(float3 x) float4 normalize(float4 x) |
Returns a vector in the same direction asx but with a length of 1 |
Since* performs algebraic matrix multiplication, the following function is provided to perform component-wise multiplication:
matrixCompMult(float2x2 x, float2x2 y)
matrixCompMult(float3x3 x, float3x3 y)
matrixCompMult(float4x4 x, float4x4 y)
The following functions compare vectors component-wise and return a component-wise boolean vector result of the same size:
|
bool2 lessThan(int2 x, int2 y) bool3 lessThan(int3 x, int3 y) bool4 lessThan(int4 x, int4 y) bool2 lessThan(float2 x, float2 y) bool3 lessThan(float3 x, float3 y) bool4 lessThan(float4 x, float4 y) |
Returns the component-wise compare ofx <y |
|
bool2 lessThanEqual(int2 x, int2 y) bool3 lessThanEqual(int3 x, int3 y) bool4 lessThanEqual(int4 x, int4 y) bool2 lessThanEqual(float2 x, float2 y) bool3 lessThanEqual(float3 x, float3 y) bool4 lessThanEqual(float4 x, float4 y |
Returns the component-wise compare ofx <=y |
|
bool2 greaterThan(int2 x, int2 y) bool3 greaterThan(int3 x, int3 y) bool4 greaterThan(int4 x, int4 y) bool2 greaterThan(float2 x, float2 y) bool3 greaterThan(float3 x, float3 y) bool4 greaterThan(float4 x, float4 y) |
Returns the component-wise compare ofx >y |
|
bool2 greaterThanEqual(int2 x, int2 y) bool3 greaterThanEqual(int3 x, int3 y) bool4 greaterThanEqual(int4 x, int4 y) bool2 greaterThanEqual(float2 x, float2 y) bool3 greaterThanEqual(float3 x, float3 y) bool4 greaterThanEqual(float4 x, float4 y) |
Returns the component-wise compare ofx >=y |
|
bool2 equal(int2 x, int2 y) bool3 equal(int3 x, int3 y) bool4 equal(int4 x, int4 y) bool2 equal(float2 x, float2 y) bool3 equal(float3 x, float3 y) bool4 equal(float4 x, float4 y) bool2 equal(bool2 x, bool2 y) bool3 equal(bool3 x, bool3 y) bool4 equal(bool4 x, bool4 y) |
Returns the component-wise compare ofx ==y |
|
bool2 notEqual(int2 x, int2 y) bool3 notEqual(int3 x, int3 y) bool4 notEqual(int4 x, int4 y) bool2 notEqual(float2 x, float2 y) bool3 notEqual(float3 x, float3 y) bool4 notEqual(float4 x, float4 y) bool2 notEqual(bool2 x, bool2 y) bool3 notEqual(bool3 x, bool3 y) bool4 notEqual(bool4 x, bool4 y) |
Returns the component-wise compare ofx !=y |
The following vector functions operate only on vectors of boolean type :
|
bool any(bool2 x) bool any(bool3 x) |