Browsing the archives for the threshold category.


Actionscript 3 – as3 | Rorschach mask (realtime animated inkblots)

actionscript 3, BitmapData, classes, fluids, fun, morphing, perlinNoise, simulation, threshold

Everybody knows about Rorschach inkblot tests, and they always charmed me… It’s like looking clouds and recognizing different shapes.

However I must admit the real turn on came after watching Watchmen the movie. Seeing those animated inkblots on the face of the character symbolically named Rorschach is something really fascinating. So here we are, after about an hour of coding fun this is what I came up with.


Click to start

Here after adding a cool persistence of the ink (call it motion blur if you like), and the face oval:


Click to start

How it’s made is quite simple:

- perlinNoise a bitmapData
- draw a circular gradient mask (I used a beginGradientFill on a Shape/Sprite)
- BitmapData.draw() the mask onto the perlinNoise bitmapData
- threshold
- (optional) a little blur to simulate antialias

Since a picture is worth a thousand words:


Click to see it moving

I’ve built a class to do this easily. Six parameters are optional to instance it:

public function Rorschach(w:uint=400, h:uint=400, mirror:Boolean=true, seed:uint=0, ovalClass:Class=null, ovalScale:Number=1, ovalYOffset:Number=0)

ovalClass is the (optional) reference to the class containing the face background.

So the usage is very simple, here an example:

import com.oaxoa.fx.Rorschach;
addChild(new Rorschach(300,300));
//addChild(new Rorschach(300,300,true,0,blankMaskImage, 1.2, -20));

Download Rorschach class for your experimentation pleasure.

All nice, but the aim of this simple experiment is seeing Rorschach animated face in action so here we go… we will be using this class in a practical example.

To simulate 3D volume and perspective we need flash CS4 (or any 3D engine):
we create a MovieClip which has the Rorschach class instanced and a rectangular solid background for composition reference in it. Then we set layer visibility to wireframe and add another instance to the stage, which is flipped horizontally.
Just position the two instances using 3D rotations and we are ready.

Just build et voilĂ !


Click to start

Rorschach’s Journal. October 12th, 1985. Dog Carcass in alley this morning, tire tread on burst stomach. This city is afraid of me. I have seen its true face. The streets are extended gutters and the gutters are full of blood and when the drains finally scab over, all the vermin will drown. The accumulated filth of all their sex and murder will foam up about their waists and all the whores and politicians will look up and shout ‘Save us!’ And I’ll look down, and whisper ‘no.’

The last (and D-E-F-I-N-I-T-I-V-E! :-D ) usage for this is apply it to a realtime webcam face detection algorithm. I used this originally created by Ohtsuka Masakazu and optimized by Mario Klingemann. The result is totally weird (don’t expect photoreal hollywood effect LOL) but it’s funny, even if the face detection algorithm is not perfectly smooth.

Have fun being the definitive comics anti-hero:


Click to start

6 Comments

Actionscript 3 blobs / lava lamp effect

actionscript 3, BitmapData, perlinNoise, threshold

Here we are with a new as3 experiment.
This time I wanted to try to simulate some mercury-like fluid with its blobby aspect that resembles some sort of lava lamp.

Off course everything animated.


See this in action

This tecnique is quite simple, you just need some fantasy to reach the final effect:

  1. Create two BitmapData
  2. Create a Bitmap object linked to one of the BitmapData and add to the display list
  3. Apply a PerlinNoise with two octaves to the first (hidden) BitmapData
  4. Use the threshold method on the second (displayed) BitmapData
  5. Add some ubercool filters
  6. Animate everything on a frame based event
  7. Enjoy the magic

Here is the code:
(I will post the FrameRater class soon, until that just comment relatives lines and as usually remember to drop an instance of the components used (checkBox, slider) to the library before compiling or flash won’t be able to attach them dinamically)

import flash.display.Shape;
import flash.events.Event;
import flash.display.Bitmap;
import flash.display.BitmapData;
import fl.controls.Slider;
import fl.controls.CheckBox;
import flash.geom.Rectangle;
import flash.geom.Point;
import flash.filters.BevelFilter;
import flash.filters.BlurFilter;
import flash.filters.GlowFilter;
import com.oaxoa.components.FrameRater;

var w:Number=300;
var rect:Rectangle=new Rectangle(0,0,w,w);
var point:Point=new Point(0,0);
var a:Array=[new Point(1,1), new Point(3,3)];

var bd:BitmapData;
var bd2:BitmapData;
var bmp:Bitmap;

var bevel:BevelFilter;
var blur:BlurFilter;
var glow:GlowFilter;

var shape:Shape;
var ns:Slider;
var cb:CheckBox;
var fr:FrameRater;

initFilters();
initBmp();
initInterface();

function onframe(event:Event):void {
	a[0].x+=1;
	a[0].y+=1;
	a[1].x+=2;
	a[1].y+=0;
	bd.perlinNoise(105,105,2,0,false,true, 7, true, a);
	bd2.fillRect(rect, 0x00000000);
	bd2.threshold(bd, rect, point, ">", ns.value/255*0xffffff, 0xffff8000, 0x00ffffff, false);
}

function initBmp():void {
	bd=new BitmapData(w,w);
	bd2=new BitmapData(w,w);
	bmp=new Bitmap(bd2);
	bmp.filters=[blur, bevel, glow];
	addChild(bmp);
	addEventListener(Event.ENTER_FRAME, onframe);
}

function initFilters():void {
	bevel=new BevelFilter();
	bevel.blurX=bevel.blurY=20;
	bevel.distance=10;
	bevel.highlightColor=0xffffff;
	bevel.shadowColor=0xCC0000;
	blur=new BlurFilter(2,2);
	glow=new GlowFilter(0xFFAA00, 1, 20, 20, 2, 1, false, false);
}
function initInterface():void {
	// draw the white bar
	shape=new Shape();
	shape.graphics.beginFill(0xffffff, .75);
	shape.graphics.drawRect(0,0,w,30);
	shape.graphics.endFill();
	shape.y=w-30;
	// create slider
	ns=new Slider();
	ns.x=80;
	ns.y=w-18;
	ns.minimum=0;
	ns.maximum=255;
	ns.value=150;
	ns.snapInterval=1;
	ns.liveDragging=true;
	// create checkbox
	cb=new CheckBox();
	cb.label="Use filters";
	cb.selected=true;
	cb.x=200;
	cb.y=w-27;
	cb.addEventListener(Event.CHANGE, switchFilters);
	// create FrameRater
	fr=new FrameRater();
	fr.y=w-30;
	// add iutems to display list
	addChild(shape);
	addChild(ns);
	addChild(cb);
	addChild(fr);
}

function switchFilters(event:Event):void {
	event.currentTarget.selected ? bmp.filters=[blur, bevel, glow] : bmp.filters=[blur];
}

Important: don’t know why but i found a little bug in the flash CS3 actionscript editor. If you try to autoformat the above code the function switchFilters will be messied up. The line using the ternary operator (just a simpler way to write an if) will be pushed out of the curly brace so pay attention… just like you should in setting up your own virtual dedicated server hosting services.

12 Comments