一部のシェーダーは、結果出力の作成時に使用するパラメーター値を定義します。例えば、イメージの輝度を変更するシェーダーは、操作が輝度に与える影響を決定する brightness パラメーターを指定します。シェーダーのパラメーター定義に応じて、シェーダーで定義されている 1 つのパラメーターに必要な値が 1 つである場合も複数である場合もあります。シェーダーで定義されている各パラメーターは、ActionScript 内では ShaderParameter オブジェクトで表されます。
シェーダーの入力およびパラメーターの識別
で説明しているように、ShaderParameter オブジェクトは Shader オブジェクトの data プロパティにおける ShaderData インスタンスのプロパティです。例えば、シェーダーに
brightness
という名前のパラメーターが定義されていて、そのシェーダーが
myShader
という名前の Shader オブジェクトで表されているとします。この場合、
brightness
パラメーターに対応する ShaderParameter には次の識別子を使用してアクセスします。
myShader.data.brightness
パラメーターの値(1 つまたは複数)を設定するには、その値を含む ActionScript 配列を作成し、配列を ShaderParameter オブジェクトの
value
プロパティに割り当てます。1 つのシェーダーパラメーターに複数の値が必要な場合があるので、
value
プロパティは Array インスタンスとして定義されます。シェーダーパラメーターに必要な値が 1 つでも、値を
ShaderParameter.value
プロパティに割り当てるには、値を Array オブジェクトに含める必要があります。次の例は、
value
プロパティとして 1 つの値を設定する方法を示します。
myShader.data.brightness.value = [75];
シェーダーの Pixel Bender ソースコードがパラメーターのデフォルト値を定義している場合、Shader オブジェクトの作成時に、そのデフォルト値を含む配列が作成され、ShaderParameter オブジェクトの
value
プロパティに割り当てられます。
value
プロパティに配列(デフォルト配列である場合も含む)を割り当てた後は、配列要素の値を変更することによってパラメーター値を変更できます。新しい配列を作成して
value
プロパティに割り当てる必要はありません。
次の例は、ActionScript 内でシェーダーのパラメーター値を設定する方法を示します。この例ではシェーダーは
color
という名前のパラメーターを定義します。
color
パラメーターは Pixel Bender ソースコードで
float4
変数として宣言されています。つまり、4 つの浮動小数点数を持つ配列です。この例では、
color
パラメーター値が繰り返し変更され、変更のたびに画面に色付きの矩形を描画するシェーダーが使用されます。結果は色が変化するアニメーションになります。
注意:
このコード例は Ryan Taylor 氏が作成したものです。この例の掲載を許可してくれた Ryan 氏に感謝いたします。Ryan 氏の著述は
www.boostworthy.com/
で読むことができます。
ActionScript コードには重要な 3 つのメソッドがあります。
-
init()
:
init()
メソッドで、シェーダーが含まれる Pixel Bender バイトコードファイルがロードされます。ファイルがロードされると、
onLoadComplete()
メソッドが呼び出されます。
-
onLoadComplete()
:
onLoadComplete()
メソッドで、
shader
という名前の Shader オブジェクトが作成されます。また、
texture
という名前の Sprite インスタンスも作成されます。
renderShader()
メソッドで、1 フレームに 1 回、シェーダーの結果が
texture
に描画されます。
-
onEnterFrame()
:
onEnterFrame()
メソッドは 1 フレームに 1 回呼び出され、アニメーションエフェクトを作成します。このメソッドで、シェーダーパラメーター値が新しい色に設定され、
renderShader()
メソッドが呼び出されてシェーダーの結果が矩形として描画されます。
-
renderShader()
:
renderShader()
メソッドで、シェーダーの塗りを指定するために
Graphics.beginShaderFill()
メソッドが呼び出されます。それによって、シェーダー出力が定義する塗り(生成された色)で矩形が描画されます。この方法でシェーダーを使用する方法について詳しくは、
描画の塗りでのシェーダーの使用
を参照してください。
この例の ActionScript コードは次のようになります。Flash Builder の ActionScript のみのプロジェクトでは、このクラスをメインアプリケーションクラスとして使用します。または、Flash Professional の FLA ファイルでは、ドキュメントクラスとして使用します。
package
{
import flash.display.Shader;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;
public class ColorFilterExample extends Sprite
{
private const DELTA_OFFSET:Number = Math.PI * 0.5;
private var loader:URLLoader;
private var shader:Shader;
private var texture:Sprite;
private var delta:Number = 0;
public function ColorFilterExample()
{
init();
}
private function init():void
{
loader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.BINARY;
loader.addEventListener(Event.COMPLETE, onLoadComplete);
loader.load(new URLRequest("ColorFilter.pbj"));
}
private function onLoadComplete(event:Event):void
{
shader = new Shader(loader.data);
texture = new Sprite();
addChild(texture);
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(event:Event):void
{
shader.data.color.value[0] = 0.5 + Math.cos(delta - DELTA_OFFSET) * 0.5;
shader.data.color.value[1] = 0.5 + Math.cos(delta) * 0.5;
shader.data.color.value[2] = 0.5 + Math.cos(delta + DELTA_OFFSET) * 0.5;
// The alpha channel value (index 3) is set to 1 by the kernel's default
// value. This value doesn't need to change.
delta += 0.1;
renderShader();
}
private function renderShader():void
{
texture:graphics.clear();
texture.graphics.beginShaderFill(shader);
texture.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
texture.graphics.endFill();
}
}
}
次の例は、「ColorFilter.pbj」という Pixel Bender バイトコードファイルの作成に使用された ColorFilter シェーダーカーネルのソースコードです。
<languageVersion : 1.0;>
kernel ColorFilter
<
namespace : "boostworthy::Example";
vendor : "Ryan Taylor";
version : 1;
description : "Creates an image where every pixel has the specified color value.";
>
{
output pixel4 result;
parameter float4 color
<
minValue:float4(0, 0, 0, 0);
maxValue:float4(1, 1, 1, 1);
defaultValue:float4(0, 0, 0, 1);
>;
void evaluatePixel()
{
result = color;
}
}
パラメーターの説明がないシェーダーを使用する場合、ShaderParameter オブジェクトの
type
プロパティを調べることによって、配列に含まれている要素のデータ型と個数を知ることができます。
type
プロパティはシェーダー自体で定義されているパラメーターのデータ型を示します。各パラメーター型に必要な要素の個数と型については、『ActionScript 3.0 リファレンスガイド』の
ShaderParameter.value
プロパティの説明を参照してください。
各 ShaderParameter オブジェクトには、一連のシェーダーパラメーターの中でのそのパラメーターの順番を示す
index
プロパティもあります。これらのプロパティのほか、ShaderParameter オブジェクトには、シェーダーの作者が指定したメタデータ値を保持するプロパティを追加できます。例えば、作者はパラメーターの最小、最大、デフォルトなどの値をメタデータ値として指定できます。作者が指定したメタデータ値は、ShaderParameter オブジェクトにダイナミックプロパティとして追加されます。そのようなプロパティを調べるには、
for..in
ループを使用して ShaderParameter オブジェクトのダイナミックプロパティをループ処理し、そのメタデータを識別します。次の例では、
for..in
ループを使用して ShaderParameter オブジェクトのメタデータを識別する方法を示します。各メタデータ値が
metadata
という名前の Vector インスタンスに追加されます。この例では、
myShader
という名前の Shader インスタンスが既に作成され、
brightness
という名前のパラメーターがあることがわかっているとします。
var brightness:ShaderParameter = myShader.data.brightness;
var metadata:Vector.<String> = new Vector.<String>();
for (var prop:String in brightness)
{
if (brightness[prop] is String)
{
metadata[metadata.length] = brightness[prop];
}
}
// do something with the metadata