Once you create a Pixel Bender Shader object, how do you find out what metadata and properties are associated with it?
This recipe shows how to walk the parameters and metadata of a shader object.
shader is an instance of a Pixel Bender Shader object. The code below walks the properties and metadata of the Shader object and adds the info to a string for display.
// walk parameters & metadata
var infoString:String = new String();
for (var p:String in shader.data)
{
infoString += p + ": " + shader.data[p] + "\n";
if (shader.data[p] is ShaderParameter)
{
// add the type of the parameter to the string
infoString += "* " + (shader.data[p] as
ShaderParameter).type + "\n";
}
for (var d:String in shader.data[p])
{
// use the built-in string conversion for the all the info
associated
infoString += "\t" + d + ": " + shader.data[p][d] + "\n";
}
}
the output from the above code is:
name: twirl
description: twist an image around
twirlAngle: [object ShaderParameter]
* float
name: twirlAngle
minValue: 0
maxValue: 360
defaultValue: 90
version: 2
center: [object ShaderParameter]
* float2
name: center
minValue: 0,0
maxValue: 2048,2048
defaultValue: 256,256
namespace: AIF
vendor: Adobe Systems
radius: [object ShaderParameter]
* float
name: radius
minValue: 0.10000000149011612
maxValue: 2048
defaultValue: 10
gaussOrSinc: [object ShaderParameter]
* int
name: gaussOrSinc
minValue: 0
maxValue: 1
defaultValue: 0
oImage: [object ShaderInput]
name: oImage
for the twirl filter sample filter that ships with the
Pixel Bender Toolkit:
/*****************************************************************************
*
* Copyright (C) 2008 Adobe Systems Incorporated
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains the
property of
* Adobe Systems Incorporated and its suppliers, if any. The
intellectual and
* technical concepts contained herein are proprietary to
Adobe Systems
* Incorporated and its suppliers and may be covered by U.S.
and Foreign
* Patents, patents in process, and are protected by trade secret or
copyright
* law. Dissemination of this information or reproduction of this
material is
* strictly forbidden unless prior written permission is obtained
from Adobe
* Systems Incorporated.
*
*****************************************************************************/
<languageVersion: 1.0;>
// twirl: A simple example to demonstrate the use of the sampling
// function to yield an interesting effect. The filter
performs
// some math based on the parameter values to change the
sampling
// location.
kernel twirl
< namespace : "Pixel Bender Samples";
vendor : "Adobe Systems";
version : 2;
description : "twist an image around"; >
{
// define PI for the degrees to radians calculation
const float PI = 3.14159265;
// An input parameter to specify the radius of the twirl
effect.
// For this parameter, we're using metadata to indicate the
minimum,
// maximum, and default values, so that the tools can set the
values
// in the correctly in the UI for the filter.
// NOTE: This parameter indicates how many pixel values out
from the
// center location we would like to twirl. The radius is in
the pixel
// coordinate space to ensure that we always rotate in a
circle. For
// more information regarding the coordinate spaces, please
consult the
// pixel bender spec.
parameter float radius
<
minValue:float(0.1);
maxValue:float(2048.0);
defaultValue:float(10.0);
>;
// An input parameter to specify the center of the twirl
effect.
// As above, we're using metadata to indicate the minimum,
// maximum, and default values, so that the tools can set the
values
// in the correctly in the UI for the filter.
parameter float2 center
<
minValue:float2(0.0, 0.0);
maxValue:float2(2048.0, 2048.0);
defaultValue:float2(256.0, 256.0);
>;
// An input parameter to specify the angle that we would like
to twirl.
// For this parameter, we're using metadata to indicate the
minimum,
// maximum, and default values, so that the tools can set the
values
// in the correctly in the UI for the filter.
parameter float twirlAngle
<
minValue:float(0.0);
maxValue:float(360.0);
defaultValue:float(90.0);
>;
// An input parameter that indicates how we want to vary the
twirling
// within the radius. We've added support to modulate by one
of two
// functions, a gaussian or a sinc function. Since Flash does
not support
// bool parameters, we instead are using this as an int with
two possible
// values. Setting this parameter to be 1 will
// cause the gaussian function to be used, unchecking it will
cause
// the sinc function to be used.
parameter int gaussOrSinc
<
minValue:int(0);
maxValue:int(1);
defaultValue:int(0);
>;
input image4 oImage;
output float4 outputColor;
// Region functions are not available in Flash targets, so we only
define
// the functions if we are executing on a different backend.
#if !AIF_FLASH_TARGET
// needed(): Indicates what area of the input is needed to
fulfill the
// requested output region. In this case, we
consider a
// radius = 1.0 area of the input for each output
pixel, so we
// need to outset the area by one.
region needed(region outputRegion, imageRef inputRef)
{
// if we have a gaussian function, negligible rotation
occurs at 3 * radius
// for a sinc function, we want a radius where the value is
< 0.03. That
// happens at a factor of 33.3 times the radius.
float2 fallOffPoint = pixelSize(oImage);
fallOffPoint *= radius;
if(gaussOrSinc == 0)
fallOffPoint *= 3.0;
else
fallOffPoint *= 33.3;
region rotatedRegion = region(float4(center.x -
fallOffPoint.x,
center.y -
fallOffPoint.y,
center.x +
fallOffPoint.x,
center.y +
fallOffPoint.y));
return union(outputRegion, rotatedRegion);
}
// changed(): Indicates what area of the output is affected by
the
// specified input. In this case, we will blur out
the image
// by exactly one pixel, so the output is the input
outset by
// one.
region changed(region inputRegion, imageRef inputRef)
{
// if we have a gaussian function, negligible rotation
occurs at 3 * radius
// for a sinc function, we want a radius where the value is
< 0.03. That
// happens at a factor of 33.3 times the radius.
float2 fallOffPoint = pixelSize(oImage);
fallOffPoint *= radius;
if(gaussOrSinc == 0)
fallOffPoint *= 3.0;
else
fallOffPoint *= 33.3;
region rotatedRegion = region(float4(center.x -
fallOffPoint.x,
center.y -
fallOffPoint.y,
center.x +
fallOffPoint.x,
center.y +
fallOffPoint.y));
return union(inputRegion, rotatedRegion);
}
#endif
// evaluatePixel(): The function of the filter that actually
does the
// processing of the image. This function is
called once
// for each pixel of the output image.
void
evaluatePixel()
{
// convert the angle to radians
float twirlAngleRadians = radians(twirlAngle);
// adjust the radius value from pixel coordinates to world
coordinates
// to do this, we multiply by the pixel size.
float adjustedRadius = length(radius * pixelSize(oImage));
// calculate where we are relative to the center of the
twirl
float2 relativePos = outCoord() - center;
// calculate the absolute distance from the center
normalized
// by the twirl radius.
float distFromCenter = length( relativePos );
distFromCenter /= adjustedRadius;
// modulate the angle based on either a gaussian or a sync.
float adjustedRadians;
// precalculate either the gaussian or the sinc weight
float sincWeight = sin( distFromCenter ) *
twirlAngleRadians / ( distFromCenter );
float gaussWeight = exp( -1.0 * distFromCenter *
distFromCenter ) * twirlAngleRadians;
// protect the algorithm from a 1 / 0 error
adjustedRadians = (distFromCenter == 0.0) ?
twirlAngleRadians : sincWeight;
// switch between a gaussian falloff or a sinc fallof
adjustedRadians = (gaussOrSinc == 1) ? adjustedRadians :
gaussWeight;
// rotate the pixel sample location.
float cosAngle = cos( adjustedRadians );
float sinAngle = sin( adjustedRadians );
float2x2 rotationMat = float2x2(
cosAngle, sinAngle,
-sinAngle, cosAngle
);
relativePos = rotationMat * relativePos;
// sample and set as the output color. since relativePos
// is related to the center location, we need to add it
back in.
// We use linear sampling to smooth out some of the
pixelation.
outputColor = sampleLinear( oImage, relativePos + center );
}
}
+