前回は、Pixel Bender 3D カーネルの基本構造と変数の定義をカバーしました。今回は、カーネル関数の定義です。
ちょっと復習ですが、カーネルと、カーネルから生成される PB-ASM プログラムの関係は、以下のようになっています。
- 頂点カーネルから生成
- 頂点位置プログラム:頂点の位置を操作
- マテリアルカーネルから生成
- 頂点マテリアルプログラム:頂点の見た目を操作
- 断片マテリアルプログラム:断片の見た目を操作
そのため、頂点カーネルには 1 つ、マテリアルカーネルには 2 つの関数を定義します。(必要に応じて補助用の関数も定義できます)
その際、関数名は事前に決められたものを使用します。
- 頂点位置プログラム:evaluateVertex()
- 頂点マテリアルプログラム:evaluateVertex()
- 断片マテリアルプログラム:evaluateFragment()
その後、シェーダに変換されるのでした。
- 頂点シェーダ = 頂点位置プログラム + 頂点マテリアルプログラム
- 断片シェーダ = 断片マテリアルプログラム
ということで本題に戻って、頂点カーネルの関数の書き方です。
頂点カーネルの関数定義
頂点カーネルには evaluateVertex() という関数を定義します (必須です)。 関数内には頂点位置プログラムとして実行するロジックを記述します。
下は、そのサンプルです。見てのとおり、AS3 とそれ程違わない感じです。 (少なくとも AGAL と比べれば)
見やすくするため変数の宣言から id を省略しています。 (前回の記事参照)
{ parameter float4x4 objectToClipSpaceTransform; input vertex float4 vertexPosition; output float4 vertexClipPosition; void evaluateVertex() { vertexClipPosition = vertexPosition * objectToClipSpaceTransform; } }
evaluateVertex() は値を返さないため、型は void になります。型は関数名の前に記述します。また、evaluateVertex() は引数をとりません。つまり、同じカーネルのメンバーとして宣言された変数のみ利用できます。
evaluateVertex() 内では必ず output の変数 (上のサンプルでは vertexClipPosition) に値を設定します。今回は、頂点座標 vertexPosition を行列変換した結果、を代入しています。
AGAL と同様、行列計算が 1 つの演算子で書けるのは便利ですね。
ちなみに AGAL で同じ内容を記述すると、こんな感じでした。
m44 op, va0, vc0
タイプの必要な文字数は AGAL の方がずっと少ないですが、Pixel Bender 3D の方がずっと読み易いです。 (よね?)
マテリアルカーネルの定義
続いて、マテリアルカーネルの定義です。まずは変数から。
{ input vertex float4 vertexColor; interpolated float4 interpolatedColor; output float4 finalColor; // 以下関数定義... }
上から順番に、
- 頂点バッファから float x 4 つ分を、頂点の色として vertexColor という名前で使う
- 頂点マテリアルプログラムと断片マテリアルプログラム間の受け渡しに interpolatedColor という変数を使う
- 最終的な断片の色は finalColor という名前の変数に代入する
という宣言になります。
マテリアルカーネルでは以下の 2 つの関数を定義します。evaluateVertex() は頂点マテリアルプログラム、evaluateFragment() は断片マテリアルプログラムに変換されます。
{ void evaluateVertex() { interpolatedColor = vertexColor; } void evaluateFragment() { finalColor = interpolatedColor; } }
ここでは、どちらの関数も、単純に入力された値を次の処理に渡しているだけです。そのため 3 角形の各頂点の色を補間した値が、そのまま断片の色として出力されます。
以下は今回サンプルとして使ったカーネルコードです。
pb3dutil で変換して、AS3 のコードに埋め込めば、シェーダとして使えます。 (この辺りの手順は Pixel Bender 3D プレビュー 3 公開参照)
まず、頂点カーネルは、
<languageVersion: 1.0;> vertex kernel MyKernel < namespace: "Pixel Bender 3D example"; vendor: "MyCompany"; version: 1; > { parameter float4x4 objectToClipSpaceTransform < id : "PB3D_CLIP_TRANSFORM"; >; input vertex float4 vertexPosition < id:"PB3D_POSITION"; >; output float4 vertexClipPosition; void evaluateVertex() { vertexClipPosition = vertexPosition * objectToClipSpaceTransform; } }
次に、マテリアルカーネルは、
<languageVersion: 1.0;> material kernel MyKernel < namespace: "Pixel Bender 3D example"; vendor: "MyCompany"; version: 1; > { input vertex float4 vertexColor; interpolated float4 interpolatedColor; output float4 finalColor; void evaluateVertex() { interpolatedColor = vertexColor; } void evaluateFragment() { finalColor = interpolatedColor; } }
です。
コメントする