views:

384

answers:

2

I'm drawing stuff on a bitmapData and I need to continuously fade every pixel to 0x808080 while still drawing (its for a DisplacementMapFilter)... I think this illustrates my problem:
http://www.ventdaval.com/lab/grey.swf

The simpler approach I tried was drawing a semi-transparent grey box on it, but it never reaches a single color (i.e. 0x808081 will never be turned to 0x808080)... The same kind of thing happens with a ColorMatrixFilter trying to progressively reduce the saturation and/or contrast. (the example above is applying a filter with -10 contrast every frame).

I'm trying paletteMap now, and I'm sensing this could be the way to go, but I haven't been able to get it... any ideas?

+1  A: 

You can try to fade it slightly more than you are fading it now, so color will go to 0x808080, you just need to do some calculations.

Yes, you can do this with paletteMap. The third way will be to write PixelBender shader for it. You can also use your normal fading and do paletteMap or PixelBender one once in a few frames, to speed-up all this.

stroncium
Thanks for the answer, but the calculations tell me that I would need to fade by more than 50% to be able to make a 0x808081 pixel into a 0x808080.I ended up using merge and playing with the alpha channel, which kind of worked, but I was unable to get it perfect and then I run out of time to keep trying with PixelBender or paletteMap, which btw I still can't understand how to use exactly... if you have any good reference would be great :)
Cay
Exactly. You need to fade more than 50%(in few fades if you want).http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/display/BitmapData.html#paletteMap() - the only reference I use is this one.
stroncium
+1  A: 

I think the easiest way to do this would be with two successive color filters. That is:

var n:Number = 0.9;
var off:Number = 0x80;
var filter:ColorMatrixFilter = new ColorMatrixFilter( [
        1, 0, 0, 0, -off, 
        0, 1, 0, 0, -off, 
        0, 0, 1, 0, -off, 
        0, 0, 0, 1, -off ] );
var filter2:ColorMatrixFilter = new ColorMatrixFilter( [
        n, 0, 0, 0, off, 
        0, n, 0, 0, off, 
        0, 0, n, 0, off, 
        0, 0, 0, n, off ] );

function onFrame( e:Event ) {
    myBMD.applyFilter( myBMD, myBMD.rect, new Point(), filter );
    myBMD.applyFilter( myBMD, myBMD.rect, new Point(), filter2 );
}

The first filter offsets each channel value downwards by 128 - turning your gray-based image into a black-based image. The second filter multiplies each channel value by the modulator (0.9 in my example), and then offsets the values back up by 128.

fenomas
Incidentally, I did a quick test and this did not seem to have any rounding problems. If it does for you, you could always use a slightly larger offset in the first filter than in the second, which should force all values to converge to exactly 0x80.
fenomas
It's not a bad idea, but the same problem arises... try adding this to your code:var myBMD:BitmapData=new BitmapData(2,2,false,0);myBMD.noise(2);for (var i:uint=0;i<30;i++) { trace(myBMD.getPixel(1,1).toString(16)); onFrame(null);}Notice how the last 10 values are the same (848084), when they should keep changing to finally reach 808080. See what I mean? :S
Cay
Cay: read the comment above yours. In other words, change "-off" to "-off-1" in the first filter.
fenomas
oh, you're right, I didn't get it at first, sorry... still, I loose all color information lower than 0x808080, and I actually need the whole range (to be able to get negative displacement) :(
Cay