Blobs Redux

December 19th 2009



For a quick project I was asked to revisit my old blobs effect. The client (which, again, sells flavoured liquids) wanted a xmas greetings e-card, so the idea was to play with the liquid that would form specific shapes.

Animating was a matter of using eaze and its beziers, but making it look a bit realistic took most of the research time.

Here it's how the old version of the effect worked:

As I'm sure you had guessed already it's all based from a bunch of circles.



Then we apply a BlurFilter to the Sprite that contains the circles.



And then by copying it to a BitmapData we apply a threshold and a colorTransform.



That's it. Simple enough for a quick experiment...

This i's how the new version works:

What we had so far happened to be a bit too CPU intensive for what it was. If we were going to make it even more complex we had to optimise. We had to remove the BlurFilter step somehow.

Looking at how the Sprite wth the BlurFilter applied looked like, I though that maybe I could recreate a very similar look using pre-blurred circles.


That way, instead of doing a blur pass to a big Sprite, it would be just a copyPixels using this bitmap as source with the positions where the original circles are. The result looks like this:



Which, for the human eyes is very different, but for the computer is very similar. (I could play with brightness/contrast to make it more similar for the human eyes).

Another step for this one was to apply a colorTransform to the working bitmap instead of filling it with white every frame. By doing that we would win "trails" which would improve the liquid effect, and, at the same time doing a kind of brightness/contrast for us.



At this point we apply the threshold again.



This is pretty much like the old effect, but much faster (no fullscreen BlurFilter). Now I could make the effect a bit nicer emulating reflections. I tried many ways but in the end this 2 step process was the fastest and better looking.

First step is to apply a BevelFilter to the output of the threshold.



Doing a BevelFilter is quite slow, but I can't think of a better way.

The fact that we're using reds here is not because the final color is going to be red (which it wasn't for the client). This BevelFilter uses 0xff0000 for hightlights, 0x000000 for shadows and the threshold was 0x800000. That's basically a grayscale but using the red channel. And you may wonder why.

Well, there is this (fast) method called paletteMap that does a very interesting thing. You can map a colour channel to an array of colours. In fact, you can map all of the channels to arrays of colours but I don't know what I could do with that (yet). Lets keep it simple for now.


This is the strip of colours I'm using. Just to make it clear, what paletteMap will do is to replace all the reds with the colours in that strip... as in, 0x000000 will use the colour[0], 0x010000 will use colour[1], 0xff0000 will use colour[255]... and so on... we end up getting this:



Surprised? No? Well... I was. :)

4 comments written so far...

Great stuff! I always wondered how this 'liquid simulation' was done.
December 19th 2009
Snake
great! nice work :))
December 19th 2009
iface
right! you've got the idea, you understand the stuff...
now wondering about..
little sluggy.
AS4 supporting this?

http://www.khronos.org/opengles/sdk/docs/man/glCreateShader.xml

Is the swf movie another Element itself?
Accepting a outsider created Context?
Performance pitfalls?
mmmh... can wait for a sample!!!

"
A WebGLRenderingContext object shall be created by calling the getContext() method of a given HTMLCanvasElement object with the exact string ‘webgl’.
"
December 19th 2009
JaK
I tried Pixel Bender (flash shaders) for doing the whole filter (Theshold, Bevel, PaletteMap all in once). But it was much slower (even optimising it) than doing it with Actionscript only.

Over 2010 I'll be moving to WebGL, so I'll take a look at GLSL and all these things...

Let's see what can be done with that ;)
December 19th 2009
mr.doob

Have your say!

Name:

Website:

Comment:

Some of the projects that I worked on.



Some of the HTML5 and Actionscript experiments I've done.