topical media & game development

talk show tell print

#filter-marble.ax

#filter-marble.ax [swf] flex


  

author: jmay www.connectedpixel.com All original source code listed here is licensed under a Creative Commons License.

  
  package {
  import flash.display.BitmapData;
  import flash.geom.Rectangle;
  import flash.geom.Point;
  import flash.geom.Matrix;
  import flash.filters.BlurFilter;
  import flash.filters.BitmapFilter;
  import flash.filters.ColorMatrixFilter;
  import flash.filters.DisplacementMapFilter;
  import flash.geom.ColorTransform;
   
   
  class @ax-filter-marble {
      
  

//////////////////////////////////////////////////////

// Properties. Settable via setter/getters below // Sinusoidal or Perlin floor private var _bSinusoidalFloor:Boolean = false; // Sinusoidal floor parameters private var _waveLength:Number = 100; private var _sinMidColorPt:Number = 128; private var _sinContrastMultiplier:Number = 1.0; // Perlin floor parameters private var _bPerlinFloorBaseX:Number = 50; private var _bPerlinFloorBaseY:Number = 150; private var _floorRandomSeed:Number = 317; private var _perlinMidColorPt:Number = 128; private var _perlinContrastMultiplier:Number = 2.0; // Perlin floor modifiers private var _contrastMultiplier:Number = 1.0; private var _colorMidLevel:Number = 128; // offset private var _veinAngleDeg:Number = 0; // Marble Distortion parameters private var _bEnableDistortion:Boolean = true; private var _baseX :Number = 20; private var _baseY :Number = 20; private var _nOctaves :Number = 2; private var _randomSeed :Number = 147; private var _bFractalNoise :Boolean = false; private var _blurX :Number = 5; private var _blurY :Number = 5; // Distortion strength private var _displacementScaleX = 150; // Color mapping private var _rgb0:Number = 0x1c2a1f; private var _rgb1:Number = 0xadc8b4;

//////////////////////////////////////////////////////

private var _identityMatrix:Matrix; private var _identityColorTrans:ColorTransform; private var _marbleColorFilter:ColorMatrixFilter; private function invalidateMarbleColorFilter():void { delete _marbleColorFilter; _marbleColorFilter = undefined; }

////////////////////////////////////////////////////////////////

// Properties. public function set sinusoidalFloor(bSin:Boolean):void { _bSinusoidalFloor = bSin; } public function get sinusoidalFloor():Boolean { return _bSinusoidalFloor; } public function set waveLength(len:Number):void { if (isNaN(len)) return; if (len < 2) len = 2; if (len > 1000) len = 1000; _waveLength = len; } public function get waveLength():Number { return _waveLength; } public function set sinMidColorPt(val:Number):void { if (isNaN(val)) return; if (val < 10) val = 10; if (val > 246) val = 246; _sinMidColorPt = val; } public function get sinMidColorPt():Number { return _sinMidColorPt; } public function set sinContrast(contrast:Number):void { if (contrast < 0.1 ) contrast = 0.1; if (contrast > 10.0) contrast = 10.0; _sinContrastMultiplier = contrast; } public function get sinContrast():Number { return _sinContrastMultiplier; }

/////////////////////////////////////////////////////////////////

public function set perlinMidColorPt(val:Number):void { if (isNaN(val)) return; if (val < 10) val = 10; if (val > 246) val = 246; _perlinMidColorPt = val; } public function get perlinMidColorPt():Number { return _perlinMidColorPt; } public function set perlinContrast(contrast:Number):void { if (contrast < 0.1 ) contrast = 0.1; if (contrast > 10.0) contrast = 10.0; _perlinContrastMultiplier = contrast; } public function get perlinContrast():Number { return _perlinContrastMultiplier; } public function set floorBaseX(bx:Number):void { _bPerlinFloorBaseX = bx; } public function set floorBaseY(by:Number):void { _bPerlinFloorBaseY = by; } public function get floorBaseX():Number { return _bPerlinFloorBaseX; } public function get floorBaseY():Number { return _bPerlinFloorBaseY; } public function set floorRandomSeed(seed:Number):void { _floorRandomSeed = seed; } public function get floorRandomSeed():Number { return _floorRandomSeed; }

//////////////////////////////////////////////////////////////////////

public function set enableDistortion(bEnab:Boolean):void { _bEnableDistortion = bEnab; } public function get enableDistortion():Boolean { return _bEnableDistortion; } public function set perlinBaseX(bx:Number):void { if (isNaN(bx)) return; if (bx < 3) bx = 3; if (bx > 1000) bx = 1000; _baseX = bx; } public function get perlinBaseX():Number { return _baseX; } public function set perlinBaseY(by:Number):void { if (isNaN(by)) return; if (by < 3) by = 3; if (by > 1000) by = 1000; _baseY = by; } public function get perlinBaseY():Number { return _baseY; } public function set octaves(nOct:Number):void { _nOctaves = nOct; } public function get octaves():Number { return _nOctaves; } public function set rgb0(rgb:Number):void { _rgb0 = rgb; invalidateMarbleColorFilter(); } public function get rgb0():Number { return _rgb0; } public function set rgb1(rgb:Number):void { _rgb1 = rgb; invalidateMarbleColorFilter(); } public function get rgb1():Number { return _rgb1; } public function set seed(s:Number):void { _randomSeed = s; } public function get seed():Number { return _randomSeed; } public function set fractalNoise(bFractal:Boolean):void { _bFractalNoise = bFractal; } public function get fractalNoise():Boolean { return _bFractalNoise; } public function set displacementScaleX(dx:Number):void { if (isNaN(dx)) return; if (dx < 1) dx = 1; if (dx > 256) dx = 256; _displacementScaleX = dx; } public function get displacementScaleX():Number { return _displacementScaleX; }

//////////////////////////////////////////////////////////////////

public function @ax-filter-marble() { _identityMatrix = new Matrix(); _identityColorTrans = new ColorTransform(); }

//////////////////////////////////////////////////////////////////

// Convenience function. Returns a bitmap of the desired // size using the current Marble settings.

/////////////////////////////////////////////////////////////////

public function createBitmap(w:Number,h:Number):BitmapData { var Marble_bmp:BitmapData = new BitmapData(w, h, false, 0x000000); render(Marble_bmp); return Marble_bmp; }

///////////////////////////////////////////////////////////////////

// Render the Marble grain onto the bitmap using the current property // values. // buffer0_bmp and buffer1_bmp are optional. If they are not supplied // temporary bitmaps will be created. They MUST have the same // width and height as the destination bmp.

/////////////////////////////////////////////////////////////////

public function render(bmp:BitmapData):void { var w:Number = bmp.width; var h:Number = bmp.height; // Needed in some of the following flash api calls. var rect:Rectangle = new Rectangle(0,0,w,h); var origin:Point = new Point(0,0); var mid:Number; var mult:Number; // The source bitmap needs to be larger than the destination bitmap because // DisplacementMapFilter will grab pixels from a larger area. var paddingX:Number = _displacementScaleX + 8; // Add 16 as slop var floor_bmp:BitmapData = new BitmapData(w+paddingX,h,false,0x000000); if (_bSinusoidalFloor){ drawSine(floor_bmp, _waveLength); mid = _sinMidColorPt; mult = _sinContrastMultiplier; } else{ floor_bmp.perlinNoise(_bPerlinFloorBaseX,_bPerlinFloorBaseY,1,_floorRandomSeed,false,true,4,false); mult = _perlinContrastMultiplier; mid = _perlinMidColorPt; } var offset:Number = mult * (mid-128); var ampColor:Array = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, mult, 0, offset, 0, 0, 0, 1, 0 ]; var ampColorFilter:ColorMatrixFilter = new ColorMatrixFilter(ampColor); floor_bmp.applyFilter(floor_bmp,floor_bmp.rectangle, origin, ampColorFilter);

///////////////////////////////////////////////////

// Add the marble distortion. if (_bEnableDistortion){ // Will hold perlin noise. var srcNoise_bmp:BitmapData = new BitmapData(w+paddingX, h, false, 0xffffffff); // channelOptions - 4 - blue only // grayscale - false srcNoise_bmp.perlinNoise(_baseX,_baseY,_nOctaves,_randomSeed,false,_bFractalNoise,4,false); var filter:DisplacementMapFilter = new DisplacementMapFilter(srcNoise_bmp,origin,4,1,_displacementScaleX,0); var r:Rectangle = new Rectangle(paddingX/2,0,w,h); bmp.applyFilter(floor_bmp,r,new Point(0,0),filter); srcNoise_bmp.dispose(); } else{ bmp.copyPixels(floor_bmp,rect,origin); } floor_bmp.dispose(); // Change it from black and blue to the desired colors. bmp.applyFilter(bmp,rect, origin, getMarbleColorFilter()); } private function drawSine(floor_bmp:BitmapData, wavelength:Number):void { var w:Number = floor_bmp.width; // 1-pixel high bitmap. var tmp_bmp:BitmapData = new BitmapData(w, 1); var phaseInc:Number = 2 * Math.PI / wavelength; var phase:Number = 0; for (var x:Number = 0 ; x < w ; x++){ phase += phaseInc; var colVal:Number = 127 * Math.cos(phase) + 128; colVal = Math.round(colVal); // We're dealing with blue only here. tmp_bmp.setPixel(x,0,colVal); } var stretchMatrix:Matrix = new Matrix(); stretchMatrix.scale(1,floor_bmp.height); // Now, draw the movieclip onto the floor_bmp var blend:Object = 1; // normal floor_bmp.draw(tmp_bmp,stretchMatrix,_identityColorTrans, blend); // Clean up. tmp_bmp.dispose(); }

/////////////////////////////////////////////////////////////////

// Map the black to blue colors to the desired Marble colors.

/////////////////////////////////////////////////////////////////

private function getMarbleColorFilter():ColorMatrixFilter { if (_marbleColorFilter != undefined){ return _marbleColorFilter; } // Apply the desired colors to the bitmap. var r0:Number = (_rgb0 >> 16) & 0xff; var g0:Number = (_rgb0 >> 8 ) & 0xff; var b0:Number = _rgb0 & 0xff; var r1:Number = (_rgb1 >> 16) & 0xff; var g1:Number = (_rgb1 >> 8 ) & 0xff; var b1:Number = _rgb1 & 0xff; var marbleColor:Array = [0, 0, (r1-r0)/255, 0, r0, 0, 0, (g1-g0)/255, 0, g0, 0, 0, (b1-b0)/255, 0, b0, 0, 0, 0, 1, 0 ]; _marbleColorFilter= new ColorMatrixFilter(marbleColor); return _marbleColorFilter; } } }


(C) Æliens 27/08/2009

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.