Animating Multiple Pixel Bender Lights

March 21, 2009

Intro
Having multiple lights in PV3D is a desired effect. But after going through the lightmap classes, let me say that it’s impossible without an major rewrite. But with Pixel Bender all you do is add another term to your pbk filter…let’s do it!

Animating Pixel Bender Lights

Animating Pixel Bender Lights

Demo

Source

Discussion

It’s an amazingly simple process. Just add another term to your pixel bender light equation as shown below:

Adding Multiple Images to PV3D

Adding Multiple Images to PV3D

The example above only shows two lights, but you can have as many lights as you want just by adding additional light terms:

The pixel bender code looks like this

float2 outcoord = outCoord();
float attn = (brightness1/((distance(outcoord, center1)+radius1)))+(brightness2/((distance(outcoord, center2)+radius2)));

dst = attn* sampleNearest(src, outcoord);
dst.a=1.0;

Wow, only five lines of code to have multiple light sources – get out of here!

Animating Your Sources

Once you’ve set your shader up then animating it is pretty easy. If you aren’t sure how to set up your shader for animation, check out Lee Brimlow’s video on animating shaders. I do it a little differently than Lee, but not by much. Here are the steps for animating the lights:

  1. Increment your oscillation parameter osc++
  2. Calculate sine and cosine based upon your incremented osc
  3. Update your light positions
  4. Apply the update to your image

The fully documented code is shown below:

private function loop(e:Event):void{

//Increment your oscillation parameter
osc++;
//Calculate sine and cosine
var cos:Number=150*Math.cos(osc/10);
var sin:Number=150*Math.sin(osc/10);
//Update your light positions
shader.data.center1.value = [sin+400, cos+180];
shader.data.center2.value = [cos+200, sin+180];
//Apply the update to your image
image.filters = [filter];
//Rotating your image holder
holder.rotationY+=.25;
}

If you are aware of how hard this is to do in PV3D, you’re going wow…tell me more…and we will…

For the entire source code download the source above, or check out the link below:

Read the rest of this entry »


Adding Pixel Bender to Papervision3D

March 20, 2009

Intro

One of the things which I abhor about modeling in Papervision3D is texture baking. And if you’ve been in the business as long as I have you know why…it’s a labor intensive nightmare…and you can’t ever get it right. But with pixel bender you don’t have to bake your textures anymore and you can adjust your parameters dynamically using ActionScript.

Dynamic Shading using Pixel Bender

Dynamic Shading using Pixel Bender

Demo

Source

YouTube http://www.youtube.com/watch?v=i8BnSqf0Z_g

Discussion

Adding Pixel Bender to Papervision3D was a three step process:

  • Creation of a Pixel Bender Filter
  • Creation of a Pixel Bender Bitmap File Material Class
  • Creation of a Pixel Bender Bitmap Material Class
Adding Pixel Bender to PV3D

Adding Pixel Bender to PV3D

Before you start coding. Make sure you’ve switched to the Flash 10 player!!!

Step 1: In the previous post several pixel builder filters were presented.

Pixel Bender Filters and Algorithms

To create a dynamic light baker filter the simple light filter was modified by throwing out all the pow and exponent methods. The big trick is that exponential behavior can be mimicked by using inverse of distance –now that’s a processor saver. The final algorithm use is shown below:

lively3d Light Source for Texture Baking

lively3d Light Source for Texture Baking

The pixel bender algorithm is easily implemented using the code below:

float2 outcoord = outCoord();
float attn = (brightness/((distance(outcoord, center)+radius)));

dst = attn* sampleNearest(src, outcoord);
dst.a=1.0

In addition to the modification mentioned above the alpha component is split off and set to one. This keeps the images from losing its alpha as you reduce brightness.

Step 2: Next you must create a Pixel Bender Bitmap File Material Class. This is simply done by making a copy of PV3D’s BitmapFileMaterial class and renaming it BitmapBendMaterial class and after changing the constructor and class names extend this class by the BitmapPixelMaterial class.

BitmapBendMaterial extends BitmapPixelMaterial

You’ll now create the BitmapPixelMaterial class.

Step 3: Make a copy of the PV3D BitmapMaterial class and name it BitmapPixelMaterial. Add the appropriate import statements and the pbj and image embed methods and create a shader as shown below:

[Embed (source=”filters/livelyLight.pbj”,
mimeType=”application/octet-stream”)]
private var ShaderClass:Class;

[Embed (source="assets/images/gainesHouse512.jpg")]
private var myImage:Class;

private var shader:Shader

Next incorporate the code to get your shader and image working together:

shader = new Shader(new ShaderClass());
shader.data.center.value = [400, 306];
shader.data.brightness.value = [150];
shader.data.radius.value = [100];

var image:Bitmap = new myImage();
image.filters = [new ShaderFilter(shader)];
shader.data.src.input = image.bitmapData

Finally you must change your fill method to a shader fill method with a matrix method

graphics.beginShaderFill(shader,_localMatrix)

That’s it! To check out the wrapper code download the source or click the more button below:

Read the rest of this entry »


Pixel Bender Filters and Algorithms

March 18, 2009

Intro

Lee Brimlow has two really good video tutorials that will help you get over the hump of learning pixel bender – so I won’t repeat those. Check them out below!

Learn Pixel Bender

Putting Filters into Flash 10

But in this post, I’ll give you a ton of pixel bender filter algorithms and programs. Keep in mind pixel bender is extremely easy to use and extremely easy to learn!!!

I once took a filters class, never thought I’d ever use it. I was up at 4 this morning going over my old visual basic notes pulling out the algorithms and throwing them into pixel bender – what a dream!

Pixel Bender

Pixel Bender Point Light Example

Source (tons of filters all the ones shown below and a few more)!

Discussion

If there is only one reason why there needs to be a new version of Papervision3D (PapervisionX) – it’s pixel bender. These shaders operate at the machine level and bring a level of realism to your 3D that has not yet to be realized on the Web.

Here are a few of those algorithms I promised:

Grayscale

Converting an image from color into shades of gray is one of the simplest image processing task. It’s accomplished by averaging the three color channels and setting each channel to that average. In terms of pixel bender code this is

pixel1 shadeVal=(colorChannel.r+colorChannel.g+colorChannel.b) /3.0;
colorChannel.r = colorChannel.g = colorChannel.b = shadeVal;

Next you’ll create the compliment.

Compliment
To create the compliment of an image, subtract each pixel color channel from 255 or in the case of pixel bender 1 since rgb values in pixel bender have a value from 0 to 1 which represents (0 to 255). The pixel bender code is shown below:

colorChannel.r = 1.0 – colorChannel.r;
colorChannel.g = 1.0 – colorChannel.g;
colorChannel.b = 1.0 – colorChannel.b;

Next you’ll create the brightness filter.

Brightness
To add to the brightness of a color you add to each pixel’s component by the percentage increase in brightness times the difference of its compliment. Check out the algorithm below:

colorChannel.r += brightParam*(2.0 – colorChannel.r);
colorChannel.g += brightParam*(2.0 – colorChannel.g);
colorChannel.b += brightParam*(2.0 – colorChannel.b);

Note: A factor of 2 was introduced in the code above instead of 1 (that’s a hack based on visual appeal). Next you’ll create an exposure filter.

Exposure
Exposure is similar to brightness, but you split your color channel into rgb and alpha and apply a pow function to your rgb color channel.

dst.rgb = pow( colorChannel.rgb, float3(1.0 – exposureParam));
dst.a = colorChannel.a;

Next you’ll create color balance.

Color Balance
Color balance is very similar to brightness except that you adjust each color individually.

colorChannel.r += redParam*(1.0 – colorChannel.r);
colorChannel.g += greenParam*(1.0 – colorChannel.g);
colorChannel.b += blueParam*(1.0 – colorChannel.b);

Next you’ll create binary contrast.

Binary Contrast
Contrast measures the difference between two colors. Binary contrast adjusts your color values to only two possible values: black or white. In this case, you just calculate the grey scale and convert it to black or white depending on a shade parameter.

pixel1 shadeVal=(colorChannel.r+colorChannel.g+colorChannel.b)/3.0;
if(shadeVal>shadeParam)
{
colorChannel.r = colorChannel.g = colorChannel.b = 1.0;
}
else{
colorChannel.r = colorChannel.g = colorChannel.b = 0.0;
}

Next you’ll create a simple pixelate filter.

Simple Pixelate
Simple pixelate uses the floor function to widen your color box region. It’s really just a trick, but demonstrates a good use of the floor function.

float2 pixelCorner = floor(outCoord()/dimAsFloat);
pixelCorner = dimAsFloat*pixelCorner;
outputPixel = sampleNearest(inputImage, pixelCorner);

Next you’ll create a simple blur filter.

Simple Blur
A Blur filter works by including a bit of surrounding pixel color into the color of your current pixel. This is typically accomplished by using some type of weighting function that drops off over distance, such as a Gaussian distribution. You’ll design a simple blur filter using a linear drop off. The algorithm below adds two pixel colors beyond your center pixel and drops off linearly.

color = color + 0.75*color(blurParam/2) + 0.25*color(blurParam)

The algorithm works well for a blurParam from 0 to 10 but then breaks down. To improve it you need to add more terms…but isn’t that always the case. The pixel bender snippet is shown below:

float2 pos = outCoord();
pixel4 color = sampleNearest(src,pos);

color+=0.75*sampleNearest(src, pos+float2(0.5*blurParam, 0))+0.25*sampleNearest(src, pos+float2(blurParam, 0));

color+=0.75*sampleNearest(src, pos-float2(0.5*blurParam, 0))+0.25*sampleNearest(src, pos-float2(blurParam, 0));

color+=0.75*sampleNearest(src, pos+float2(0, 0.5*blurParam))+0.25*sampleNearest(src, pos+float2(0, blurParam));

color+=0.75*sampleNearest(src, pos-float2(0, 0.5*blurParam))+0.25*sampleNearest(src, pos-float2(0, blurParam));

dst = color/5.0;

Next you’ll create an outline sharpen filter.

Sharpen
The sharpen filter is similar to the blur filter in that you must displace the colors (this was created by Ryan Phelan on Adobe pixel bender exchange). But after displacement you must add and subtract them in such a way that you bring out their outlines.

float4 left = sampleLinear(src, coord – float2(radius, 0.0)) * amount;
float4 right = sampleLinear(src, coord + float2(radius, 0.0)) * amount;
float4 top = sampleLinear(src, coord – float2(0.0, radius)) * amount;
float4 bottom = sampleLinear(src, coord + float2(0.0, radius)) * amount;

dst.rgb += (top.rgb);
dst.rgb -= (bottom.rgb);
dst.rgb += left.rgb;
dst.rgb -= right.rgb;

The filter uses two parameters, radius and amount: radius increases the displacement, and amount increases the color.

Next you’ll create a simple point light.

Point Light

Here’s a very simple light algorithm developed by John Engler of the Adobe pixel bender exchange. The algorithm produces an extremely powerful effect and uses a combination of power and distance calculations. Such a calculation would have been avoided in Flash due to processor constraints, but with pixel bender it’s super fast!

The equation places your light at the center position. That’s because at center position there is a singularity in your equation (coord – center = zero) and everything goes white. The AttnDecay variable determines the spread of your light’s decay across your image. The AttnMult variable just multiplies your light source by a value and the brightness variable exponentiates your entire expression, acting like a brightness term.

Light Attenuation Equation

Light Attenuation Equation

The pixel bender code snippet is given below:

float2 outcoord = outCoord();

float attn = pow(attnMult/pow(distance(outcoord, center), attnDecay), brightness);

dst = attn* sampleNearest(src, outcoord);

Next you’ll create the bloom brightness effect.

Bloom Brightness

Bloom brightness is used in Away3D and was developed by Der Schmale. It filters the bright parts of the image and caps the darker parts at black.

float4 current = sample(src, outCoord());

if (length(current.xyz) < threshold)

{
dst = pixel4(0.0, 0.0, 0.0, 1.0);
}
else {
current.xyz *= exposure;
dst = current;
}

The code uses two parameters, threshold and exposure. And when your distance is less than your threshold your pixel rgb channels are set to zero. If greater than your threshold, your exposure kicks in. You’ll see this again when you add pixel blender to PV3D.

Conclusion

In the next post, you’ll learn how to add Pixel Bender to PV3D!



Follow

Get every new post delivered to your Inbox.