Archive for October, 2007

Jens’ AS3 workflow special

If you understand German I would strongly recommend you to read the article series about AS3 development at the blog of Jens Franke. Jens is about to release around 10 to 15 posts in the next two weeks in his special.

And reading is not only worthwhile for your own knowledge. There will be a raffle at the end. Prices include a full copy of FDT3.0, four FDT3.0 discount keys and five books from O’Rielly. All in all a very nice idea from Jens.

FlashMate

…or my WinApi weekend. Someone at the office asked why the Flash player does not remember size and position. My answer was FDT would do it for you. But since we are not using it (arrg!) I asked the C++ gurus here what keywords I have to google for to do it on my own.

The result is FlashMate. Just download, unzip and start it. It will be completly silent (perfect for startup) and while FlashMate is running your player will remember size and position for SWF files individually. You can also disable FlashMate for certain files. Just right click on the titlebar and uncheck it.

Hope this nifty little thing will make your daily life a little bit easier. Ugly source code is included — I am not a good C/C++ coder at all but digging a little bit in the WinApi was fun. Now back to managed memory :)

Improvements and bug reports are more than welcome.

Kuwahara!

kuwahara.hydra

Working with Hydra for some days gave me a better knowledge of how things actually work and I thought it might be worth trying something that is a little bit harder. It is very funny to implement a complex filter on the one hand and keeping it Flash compatible on the other hand. You will see a lot of this in the code.

I really enjoyed writing this one. It helped me again a lot and I think you might learn a lot from the source code as well. By the way I started first with a k of 4 but that was crashing Hydra all the time. Might have looked better but 2 is also ok. Have fun!

Hydra TechnoDots

technodots.hydra

Thanks to Zeh for poiting out that a short if is possible and succeeds in the Hydra compiler with Flash warnings enabled. So you can use them only if your values are constant but the use of this is already fantastic. See this nice “technodots” filter which shoul be 100% Flash compatible if we can trust the compiler. It works because all parameters and function results have been set to variables before doing the if.

I think Adobe showed this filter during the keynote. Could not find sources for it and my internet is at home to crappy in order to watch the video again but it was something like this if I remember correct.

Update: To complete the list of filters they showed during the keynote here is a cheap twirl as well.

More on Hydra

spherize2.hydra
As I told you I will have a closer look on hydra and the results are nice. I was able to build a Spherize, SinePlasma and OldschoolPlasma in about an hour. I think you have to keep in mind that Hydra will work together with Flash. Plasma functions are a good example because you could generate the texture in grayscale using Hydra and then use a paletteMap() in Flash.

I am not so sure about the spherize though. I have one if-statement inside and they are not allowed if you use Flash. Funny new problems will pop up but I have a good feeling and one thing is for sure: the syntax and editor are already better than what we have with AS3/FlexBuilder! Highlightning of matching brackets, no stupid function and no var keywords. Finally! Can I have that with AS3 please?

  • Oldschool – Simple oldschool plasma effect. You have to use a color palette with this.
  • Ripple filter – Sine distortion for an image.
  • Sineplasma – Sine plasma with adjustable levels, frequency and amplitude.
  • Spherize filter – Spherical displacement map with adjustable center, radius and refraction strength.
  • Structure – Filter with adjustable 3×3 structuring function.
  • Warp – I wanted to do an affine transformation until I found out it does not work with the way hydra works. I will try again.
  • Gamma correction – Look how simple it is!
  • Pixelate – Could not be easier than that.
  • Sepia – I hate those ColorMatrixFilter sepia effects. Now this one is fast and has nice quality using Y-transform.
  • Quantization – A color quantization filter.

Hydra

The keynote at Adobe MAX at Chicago just finished. Get your hands on Hydra now!

via Kevin Goldsmith

I am currently reading through the Hydra manual. Actually it is kinda sad again. It is cool BUT the cool stuff is not available in Flash. Anyways I thinkwe can squeeze a lot of nice effect out of this anways.

My very first Hydra filters:

kernel BlendModeADD
{
  parameter pixel4 intensity;

  void evaluatePixel(in image4 source, out pixel4 result)
  {
    pixel4 in_pixel = sampleLinear( source, outCoord() );
    result = in_pixel + intensity;
  }
}

Here is another one:

kernel ColorMatrixFilter
{
  parameter float4x4 matrix;

  void evaluatePixel(in image4 source, out pixel4 result)
  {
    pixel4 in_pixel = sampleLinear( source, outCoord() );
    result = in_pixel * matrix;
  }
}

I think pure AS3 developers will like this syntax ;)

Update: Here is a simple sharpen filter. Check out the two techinques. I think both are completly wrong but it works. Time will definitly tell how to use this proper.

kernel Sharpen
{
    parameter float strength;

    void evaluatePixel(in image4 source, out pixel4 result)
    {
        int i;
        int j;

        float2 coords = outCoord();
        pixel4 s = pixel4( -strength, -strength, -strength, -strength );
        pixel4 total = pixel4(0,0,0,0);
        float factor = 8.0 * strength + 1.0;
        pixel4 f = pixel4(factor,factor,factor,factor);

        for ( i = -1; i <= 1; i++ )
        {
            for ( j = -1; j <= 1; j++ )
            {
                pixel4 current = sampleLinear( source, coords + float2(i,j));

                if ( i == 0 && j == 0 )
                {
                    total += f * current;
                }
                else
                {
                    total += s * current;
                }
            }
        }

        result = total;
    }

    /*
    void evaluatePixel(in image4 source, out pixel4 result)
    {
        float2 coord = outCoord();
        pixel4 tL = sampleLinear(source, coord - float2(1,1));
        pixel4 tM = sampleLinear(source, coord - float2(0,1));
        pixel4 tR = sampleLinear(source, coord + float2(1,-1));
        pixel4 mL = sampleLinear(source, coord - float2(1,0));
        pixel4 mR = sampleLinear(source, coord + float2(1,0));
        pixel4 bL = sampleLinear(source, coord - float2(1,-1));
        pixel4 bM = sampleLinear(source, coord + float2(0,1));
        pixel4 bR = sampleLinear(source, coord - float2(-1,-1));
        pixel4 mM = sampleLinear( source, outCoord() );
        pixel4 s = pixel4( -strength, -strength, -strength, -strength );
        float ms = 8.0 * strength + 1.0;
        pixel4 up = pixel4(ms,ms,ms,ms);
        result = s * tL + s * tM + s * tR + s * mL + s * mR + s * bL + s * bM + s * bR + mM * up;
    }
    */
}

Update 2: More hydra examples.

Converting a Number to 4 bytes and vice versa

For the hell of it I wanted to implement the fast inverse square-root that has been flying around in the Quake3 source-code for instance. Fantastic game by the way. There has been quiet a lot of talk about this algorithm. So can we do that with Flash? No we can not. It would be nice but it is simply not possible because you can not just map a Number into an int. With languages like C++ you can. So first of all: I found already an approach that is very fast but not as nearly as good as the original algorithm. It is also not the same “magic”. It is just some newton iterations and faster but worse then 1/Math.sqrt(x).

So what do you need to implement the original inverse square root algorithm? A way to convert any number to its four byte representation aka the way it is stored in memory. The original algorithm is freakin fast because it does not have to calculate the four bytes. It can just juggle with them. Since we have to insert some heavy math here our approach will always be slower but it helped me understanding IEEE single precision numbers a lot. Maybe anyone has a use for this?

Remember the isqrt function is WAY slower than doing 1/Math.sqrt(x)!

[as]private function isqrt( x: Number ): Number
{
var xhalf: Number = x * 0.5;
var i: int = toFloat( x );
i = 0×5f3759df – ( i >> 1 ); // the magic first guess
x = toNumber( uint(i) );
x = x * ( 1.5 – xhalf * x * x );
return x;
}

private function toNumber( x: uint ): Number
{
//– precheck here
if ( 0xffc00000 == x )
{
return NaN;
}
else
if ( 0×7f800000 == x )
{
return Number.POSITIVE_INFINITY;
}
else
if ( 0xff800000 == x )
{
return Number.NEGATIVE_INFINITY;
}

//– can not shift because flash doesnt like it…
var v: Boolean = uint( x & uint(0×80000000) ) == uint(0×80000000);
var e: int = ( uint( x >> uint(23) ) & 0xff ) – 127;
var m: int = x & 0×7fffff;
var n: Number;

//– if e > 0 we can do 2^e very easy by shifting it
//– otherwise we do 1/(2^e) and 2^e can be achieved by shifting it
if ( e > 0 )
{
n = ( 1 + m / ( 1 << 23 ) ) * ( 1 << e );
}
else
{
n = ( 1 + m / ( 1 << 23 ) ) * ( 1 / ( 1 << -e ) );
}

if ( v )
{
return -n;
}

return n;
}

private function toFloat( x: Number ): uint
{
//-- do a quick precheck
if ( Number.POSITIVE_INFINITY == x )
{
return 0x7f800000;
}
else
if ( Number.NEGATIVE_INFINITY == x )
{
return 0xff800000;
}
else
if ( isNaN( x ) )
{
return 0xffc00000;
}

//-- calculate ieee single precision
var v: Boolean, e0: int, e1: int, m: int;
var f: Boolean = x > 0;

if ( x > 0 )
{
e0 = int( Math.log( x ) / Math.LN2 );
m = ( ( x / ( 1 << e0 ) ) – 1 ) * ( 1 << 23 );
}
else
{
v = true;
e0 = int( Math.log( -x ) / Math.LN2 );
m = ( ( -x / ( 1 << e0 ) ) – 1 ) * ( 1 << 23 );
}

e1 = e0 + 127;

//– usually here would go the test for e1 = 0×00 or e1 = 0xff
//– BUT we tested already and that’s why we do not do it here

//– be save
e1 &= 0xff;
m &= 0×7fffff;

//– merge into 4bytes
var float: uint;

if ( v )
{
float = 0×80000000;
}

float |= e1 << 23;
float |= m;

return float;
}[/as]