有些著色器會定義參數值,用於建立其結果。例如,改變影像亮度的著色器可能會指定亮度參數,用來判斷作業影響亮度的程度。在著色器中定義的單一參數依著色器中的參數定義而定,會預期接到單一值或多個值。著色器中定義的每個參數都是在 ActionScript 中以 ShaderParameter 物件來代表。ShaderParameter 物件是 Shader 物件之 data 屬性中 ShaderData 實體的屬性,如
識別著色器輸入和參數
一節中所述。例如,假設著色器定義了參數
brightness
,而該著色器連結至 Shader 物件
myShader
。在此情況下,您要使用下列識別名稱,存取對應於
brightness
參數的 ShaderParameter 物件:
myShader.data.brightness
若要設定參數的一個或多個值,請建立包含一個或多個值的 ActionScript 陣列,並指定該陣列至 ShaderParameter 物件的
value
屬性。
value
屬性是定義為 Array 實體,因為單一著色器參數有可能需要多個值。即使著色器參數只預期單一值,您也必須將該值包覆在 Array 物件中,指定至
ShaderParameter.value
屬性。下面列出的程式碼示範,將單一值設定為
value
屬性:
myShader.data.brightness.value = [75];
如果著色器的 Pixel Bender 原始碼為參數定義了預設值,就會建立包含一個或多個預設值的陣列,並在建立 Shader 物件時指定至 ShaderParameter 物件的
value
屬性。將陣列指定至
value
屬性 (包括指定它是否為預設值) 之後,可以透過變更陣列元素的值來變更參數值。您不必建立新陣列,並指定至
value
屬性。
下列範例會示範如何在 ActionScript 中設定著色器的參數值。在此範例中,著色器會定義參數
color
。
color
參數是在 Pixel Bender 原始碼中宣告為
float4
變數,也就是說,它是具有四個浮點數的陣列。在範例中,
color
參數值是持續不斷地改變,而且每次變更,就使用著色器在螢幕上繪製彩色矩形。所得到的結果就是動畫式的顏色變更。
這個 ActionScript 程式碼是以三個方法為基礎所寫成:
-
init()
:在
init()
方法中,程式碼會載入包含著色器的 Pixel Bender 位元組碼檔案。載入這個檔案時,會呼叫
onLoadComplete()
方法。
-
onLoadComplete()
:在
onLoadComplete()
方法中,程式碼會建立名為
shader
的 Shader 物件,以及名為
texture
的 Sprite 實體。在
renderShader()
方法中,程式碼會將著色器結果繪製到
texture
內 (每個影格繪製一次)。
-
onEnterFrame()
:每個影格呼叫
onEnterFrame()
方法一次,製作出動畫效果。在此方法中,程式碼將著色器參數值設定為新顏色,然後呼叫
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 著色器核心的原始碼,可用來建立 ColorFilter.pbj Pixel Bender 位元組碼檔案:
<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
屬性指出著色器本身中所定義參數的資料類型。如需一份每個參數類型應該會接到的元素類型和數目清單,請參閱「Adobe® Flash® Professional CS5 的 ActionScript® 3.0 參考」中
ShaderParameter.value
屬性所列的項目。
每個 ShaderParameter 物件也都具有
index
屬性,指出該參數在著色器的參數順序中所應佔據的位置。除了這些屬性之外,ShaderParameter 物件也可以具有包含由著色器作者所提供中繼資料值的屬性。例如,作者可以為參數指定下限、上限和預設值等中繼資料值。作者所指定的任何中繼資料值都會加入至 ShaderParameter 物件做為動態屬性。若要檢視這些屬性,請使用
for..in
迴圈,重複執行 ShaderParameter 物件的動態屬性,以識別其中繼資料。下列範例說明如何使用
for..in
迴圈來識別 ShaderParameter 物件的中繼資料。每一個中繼資料值都會加入至 Vector 實體
metadata
。請注意,此範例假設 Shader 實體
myShader
已經建立,而且該實體已知具有參數
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