Now that MAX 2007 in Chicago is over and the Flash Player team is somewhat settling for the final landing of Flash Player 9 Update 3 I've got to talk a little about
Adobe Image Foundation, code named Hydra.
I have not been involved in this project as much as I would have liked to, with
Bob Archer and
Kevin Goldsmith driving most of the specifications and communication so far, nevertheless some technical questions in the context of Flash have been asked I should be able to answer. But let me make this post a little more approachable and explain the basics.
What is Hydra? If I would have to explain it in one sentence I would say: It is a shader language specifically tuned for 2D pixel graphics.
What is a shader language? Most of you will not know the answer to this. Let me try to put it into terms you might understand, with the assumption that you already have played with BitmapData objects in ActionScript 2.
Scenario: You have a bitmap and you want to exchange the red channel with the green channel. Easy enough, in Flash 8 or newer you can actually use the ColorMatrixFilter to do this. Lets say you do not have that filter, how would you do it? Well, this is what I would write in ActionScript 2:
import flash.display.*;
// create a green bitmap
var bitmap:BitmapData = new BitmapData(550,440,false,0x00FF00);
// go through the whole bitmap pixel by pixel
for(var y:Number=0; y<bitmap.height; y++) {
for(var x:Number=0; x<bitmap.width; x++) {
// get a single pixel from our bitmap
var pixel:Number = bitmap.getPixel(x, y);
var red:Number = (pixel>>16)&0xFF; // extract red
var green:Number = (pixel>> 8)&0xFF; // extract green
var blue:Number = (pixel )&0xFF; // extract blue
// create a new pixel with the red and green channels flipped
var newpixel:Number = (green<<16)|
(red << 8)|
(blue );
// replace the ol' one with the new one
bitmap.setPixel(x, y, newpixel);
}
}
// now the bitmap is pure red
// show it
this.createEmptyMovieClip("bitmap_mc",this.getNextHighestDepth());
bitmap_mc.attachBitmap(bitmap, 2, "auto", true);
That sure looks ugly and slow. Now lets express the same as above using Hydra, and believe me, it will do exactly the same as the above AS2 code:
kernel FlipRedGreen
{
void evaluatePixel(in image3 source, out pixel3 result)
{
result.grb = sample(source, outCoord());
}
}
There are several things you will notice:
- There are no for loops to go over the pixels. That's right, shader languages only express what it inside the loop and assume that this is the operation you want to perform on every pixel.
- There are a bunch of strange types here! Not really: image3 stands for a bitmap with RGB data and pixel3 stands for an individual RGB pixel. If you would want to include alpha you could say image4 and pixel4.
- What is sample()? It is the same as BitmapData.getPixel() and returns a pixel, in this case a pixel3 type.
- What is outCoord()? It is the same as the x and y positions in the AS2 code but it returns a single value containing x and y without the need to specify them seperately.
- How does the actual flip work? Now that is some of the beauty which comes with using a shader language. You can perform all kinds of operations directly with the component identifiers.
In this case we say 'result.grb =' which will flip the red and green channel. I could write 'result =' or 'result.rgb =' to just copy the pixel without a change. Or I could write any other combination like .bgr, .gbr to flip the different components.
If you really want to get fancy you can also write something like this:
'result = sample(source, outCoord()).rrr;' or
'result = sample(source, outCoord()).bbr;'.
In this case we make the component choice on the other side of the assigment.
In essence, no more bit fiddling anymore, you have a high level access to the actual component data.
This is one of the most simple examples I can think of, Hydra is much more powerful and expressive than that. So I invite you to
take a look and get comfortable with it, this is something which will stay with us for a long time to come. And possibly not only for graphics, but let me talk about that in a future post. :-) I also promise that I will have another post specifically talking about the technical aspects of the Flash Player implementation. I can think of those and more:
- How will I be able to access this in my ActionScript code?
- How much faster will it really be than ActionScript code?
- Where will I be able to use Hydra? Just filters and blend modes, or more?
- Will Flash Authoring support Hydra?
- Will the Flash Player take advantage of hardware acceleration?
- Will this work in the Flash Player even if there is no hardware acceleration available?
I know you are clamoring for answers, though for most questions we have not figured them out ourselves just yet.
There is obviously one more question: "Instead of working on new features, when do you get your act together and ship a 64-bit version of the player?" :-) I always have a good laugh when we get this one, especially since it has been answered many times already.