MetaDiamonds

MetaDiamonds, Click to watch!

The next MetaShape is the MetaDiamond. Its like the metaballs and the MetaEllipses but with diamonds instead.

The MetaDiamonds will be based off the filter used in the previous MetaShape posts. It will use pixelbender.

MetaDiamonds are defined by this functions:

M(x,y) = R / ( |x0-x| + |y0-y| )

X and Y are the current pixel location. x0 and y0 are the diamonds coordinates.

Now using the filter from the previous posts, it is pretty easy to put this into pixel bender

<languageVersion : 1.0;>

kernel MetaDiamonds
<   namespace : "com.rocketmandevelopment";
 vendor : "Rocketman Development";
 version : 1;
 description : "MetaDiamonds";
>
{
parameter float minThreshold
<
 minValue:float(0.0);
 maxValue:float(5.0);
 defaultValue:float(3.0);
 description: "minThreshold";
>;
parameter float maxThreshold
<
 minValue:float(0.0);
 maxValue:float(2.0);
 defaultValue:float(1.5);
 description: "maxThreshold";
>;

parameter float3 ball1
<
 minValue:float3(0.0,0.0,0.0);
 maxValue:float3(640.0,480.0,100.0);
 defaultValue:float3(50.0,50.0,50.0);
 description: "ball1, params, x,y,radius";
>;

parameter float3 ball2
<
 minValue:float3(0.0,0.0,0.0);
 maxValue:float3(640.0,480.0,100.0);
 defaultValue:float3(100.0,100.0,50.0);
 description: "ball2, params, x,y,radius";
>;

parameter float3 ball3
<
 minValue:float3(0.0,0.0,0.0);
 maxValue:float3(640.0,480.0,100.0);
 defaultValue:float3(400.0,200.0,50.0);
 description: "ball2, params, x,y,radius";
>;

parameter float3 ball4
<
 minValue:float3(0.0,0.0,0.0);
 maxValue:float3(640.0,480.0,100.0);
 defaultValue:float3(500.0,300.0,50.0);
 description: "ball2, params, x,y,radius";
>;

parameter float3 ball5
<
 minValue:float3(0.0,0.0,0.0);
 maxValue:float3(640.0,480.0,100.0);
 defaultValue:float3(230.0,100.0,50.0);
 description: "ball2, params, x,y,radius";
>;
 input image4 src;
 output pixel4 dst;

 void
 evaluatePixel()
 {
 dst = sampleNearest(src,outCoord());
 dst.rbg = float3(0,0,0);
 float2 coord = outCoord();
 float sum = 0.0;
 sum += (ball1.z)/( abs(ball1.x-coord.x) + abs(ball1.y-coord.y) );
 sum += (ball2.z)/( abs(ball2.x-coord.x) + abs(ball2.y-coord.y) );
 sum += (ball3.z)/( abs(ball3.x-coord.x) + abs(ball3.y-coord.y) );
 sum += (ball4.z)/( abs(ball4.x-coord.x) + abs(ball4.y-coord.y) );
 sum += (ball5.z)/( abs(ball5.x-coord.x) + abs(ball5.y-coord.y) );
 if(sum >= minThreshold){
 dst.rgb = float3(255,255,255);
 }

 }
}

The important (and different) part of that is the diamond code:

 sum += (ball1.z)/( abs(ball1.x-coord.x) + abs(ball1.y-coord.y) );

That is the formula from above. It’s pretty easy to make these MetaShapes now that we have that base filter.

To use it in flash:


public class PixelBenderMetaballs extends Sprite {
[Embed(source='../MetaDiamonds.pbj', mimeType='application/octet-stream')]//IMPORTANT PART: Embed the filter
private static const MetaballsFilter:Class;

private const canvas:BitmapData = new BitmapData(640,480,false,0);
private const blur:BlurFilter = new BlurFilter(2,2,1);
private var metaballsFilter:ShaderFilter;
private var b1:Metaball;
private var b:Bitmap;
private var b2:Metaball;
private var b3:Metaball;
private var b4:Metaball;
private var b5:Metaball;

public function PixelBenderMetaballs(){
super();
b = new Bitmap(canvas);
b.smoothing = true;
addChild(b);
var ba:ByteArray = new MetaballsFilter() as ByteArray;
var s:Shader = new Shader(ba);
metaballsFilter = new ShaderFilter(s);
metaballsFilter.shader.data.src.image = canvas;
b1 = new Metaball(100,100,10);
b2 = new Metaball(150,150,12);//Set up the metadiamonds
b3 = new Metaball(200,200,10);
b4 = new Metaball(250,250,14);
b5 = new Metaball(300,300,9);
b1.stage = b2.stage = b4.stage = b5.stage = b3.stage = stage;
metaballsFilter.shader.data.minThreshold.value = [3.0];
metaballsFilter.shader.data.ball1.value = [b1.x,b1.y,b1.radius];//set the values in the filter
metaballsFilter.shader.data.ball2.value = [b2.x,b2.y,b2.radius];
metaballsFilter.shader.data.ball3.value = [b3.x,b3.y,b3.radius];
metaballsFilter.shader.data.ball4.value = [b4.x,b4.y,b4.radius];
metaballsFilter.shader.data.ball5.value = [b5.x,b5.y,b5.radius];
metaballsFilter.shader.precisionHint = ShaderPrecision.FAST;
b.filters = [metaballsFilter];
addEventListener(Event.ENTER_FRAME, ef);
}

private function ef(e:Event):void {
b1.update();
b2.update();
b3.update();
b4.update();
b5.update();
metaballsFilter.shader.data.ball1.value = [b1.x,b1.y,b1.radius];//update everything
metaballsFilter.shader.data.ball2.value = [b2.x,b2.y,b2.radius];
metaballsFilter.shader.data.ball3.value = [b3.x,b3.y,b3.radius];
metaballsFilter.shader.data.ball4.value = [b4.x,b4.y,b4.radius];
metaballsFilter.shader.data.ball5.value = [b5.x,b5.y,b5.radius];
b.filters = [metaballsFilter,blur];
}

}

Click here to watch MetaDiamonds!