Not yet rated

Problem

Once you create a Pixel Bender Shader object, how do you find out what metadata and properties are associated with it?

Solution

This recipe shows how to walk the parameters and metadata of a shader object.

Detailed explanation

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 );
    }
}




+
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License. Permissions beyond the scope of this license, pertaining to the examples of code included within this work are available at Adobe.

Report abuse

Related recipes