P. 1
Pixel Bender Guide

Pixel Bender Guide

|Views: 46|Likes:

Availability:

See more
See less

01/01/2013

pdf

text

original

FLASH NOTE: Dependent values are not available when Pixel Bender is used in Flash Player.

Consider a convolution operation with a procedurally generated look-up table of pixel weights:

kernel GaussianBlur
<

namespace:"Tutorial";
version:1;

>
{

CHAPTER 3: Writing Pixel Bender Filters

Using dependent values 37

input image4 source;
output pixel4 result;

void evaluatePixel()
{

const float sigma = 2.0;
float c = 1.0 / ( sqrt(2.0 * 3.1415926535 ) * sigma );
float ec = 2.0 * sigma * sigma;

float weight0 = exp( -( 0.0 * 0.0 ) / ec ) * c;
float weight1 = exp( -( 1.0 * 1.0 ) / ec ) * c;
float weight2 = exp( -( 2.0 * 2.0 ) / ec ) * c;
float weight3 = exp( -( 3.0 * 3.0 ) / ec ) * c;
float weight4 = exp( -( 4.0 * 4.0 ) / ec ) * c;

float4 acc = float4( 0.0 );
acc += sampleNearest( source, outCoord() ) * weight0;
acc += sampleNearest( source, outCoord() + float2( 1.0, 0.0 ) ) * weight1;
acc += sampleNearest( source, outCoord() + float2( -1.0, 0.0 ) ) * weight1;
acc += sampleNearest( source, outCoord() + float2( 2.0, 0.0 ) ) * weight2;
acc += sampleNearest( source, outCoord() + float2( -2.0, 0.0 ) ) * weight2;
acc += sampleNearest( source, outCoord() + float2( 3.0, 0.0 ) ) * weight3;
acc += sampleNearest( source, outCoord() + float2( -3.0, 0.0 ) ) * weight3;
acc += sampleNearest( source, outCoord() + float2( 4.0, 0.0 ) ) * weight4;
acc += sampleNearest( source, outCoord() + float2( -4.0, 0.0 ) ) * weight4;

result = acc;

}

}

This code works but has a problem: the look-up table is regenerated on every pixel, which defeats the
purpose of a look-up table. We want to precompute these values once, then apply them to all pixels. You
could pass in the values using kernel parameters, but then you need external code to compute the values.

In order to keep the computation within the kernel, but perform it only once, you can declare the table as
a set of dependent member variables. You then use the evaluateDependents() function to compute the
value of the variables. Values declared as dependent are initialized within the body of
evaluateDependents(), which is run once, before any pixels are processed. The values are then
read-only, and are held constant over all pixels as evaluatePixel() is executed.

Here is the complete GaussianBlur kernel, modified to use dependent variables:

kernel GaussianBlur
<

namespace : "Tutorial";
version : 1;

>
{

dependent float weight0;
dependent float weight1;
dependent float weight2;
dependent float weight3;
dependent float weight4;

input image4 source;
output pixel4 result;

CHAPTER 3: Writing Pixel Bender Filters

Hints and tips 38

void evaluateDependents()
{

const float sigma = 2.0;
float c = 1.0 / ( sqrt( 2.0 * 3.1415926535 ) * sigma );
float ec = 2.0 * sigma * sigma;

weight0 = exp( -( 0.0 * 0.0 ) / ec ) * c;
weight1 = exp( -( 1.0 * 1.0 ) / ec ) * c;
weight2 = exp( -( 2.0 * 2.0 ) / ec ) * c;
weight3 = exp( -( 3.0 * 3.0 ) / ec ) * c;
weight4 = exp( -( 4.0 * 4.0 ) / ec ) * c;

}

void evaluatePixel()
{

float4 acc = float4( 0.0 );
acc += sampleNearest( source, outCoord() ) * weight0;
acc += sampleNearest( source, outCoord() + float2( 1.0, 0.0 ) ) * weight1;
acc += sampleNearest( source, outCoord() + float2( -1.0, 0.0 ) ) * weight1;
acc += sampleNearest( source, outCoord() + float2( 2.0, 0.0 ) ) * weight2;
acc += sampleNearest( source, outCoord() + float2( -2.0, 0.0 ) ) * weight2;
acc += sampleNearest( source, outCoord() + float2( 3.0, 0.0 ) ) * weight3;
acc += sampleNearest( source, outCoord() + float2( -3.0, 0.0 ) ) * weight3;
acc += sampleNearest( source, outCoord() + float2( 4.0, 0.0 ) ) * weight4;
acc += sampleNearest( source, outCoord() + float2( -4.0, 0.0 ) ) * weight4;

result = acc;

}

}

scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->