In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Away3D + Flint 3D Particles Demo

Away3D v4.0.9 + Flint 3D Particles Demo
@author flashisobar http://flashisobar.blogspot.com/

demo:
Skybox
Point/Directional light
Shadow
LightsHelper - applys lights to all materials
Loader3D - load 3D Object(awd file format)
Flint3D - fog/cloud effect

3D model by SolCommand http://www.solcommand.com/
Create cloud reference http://wonderfl.net/c/h9dR
Skybox map reference https://github.com/away3d/away3d-examples-fp11/
Get Adobe Flash player
by flashisobar 30 Aug 2013
/**
 * Copyright flashisobar ( http://wonderfl.net/user/flashisobar )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/lH6h
 */

package
{
    import away3d.cameras.Camera3D;
    import away3d.cameras.lenses.PerspectiveLens;
    import away3d.containers.ObjectContainer3D;
    import away3d.containers.Scene3D;
    import away3d.containers.View3D;
    import away3d.controllers.HoverController;
    import away3d.debug.AwayStats;
    import away3d.debug.Debug;
    import away3d.debug.Trident;
    import away3d.entities.Mesh;
    import away3d.events.LoaderEvent;
    import away3d.lights.DirectionalLight;
    import away3d.lights.LightBase;
    import away3d.lights.PointLight;
    import away3d.loaders.Loader3D;
    import away3d.loaders.parsers.Parsers;
    import away3d.materials.ColorMaterial;
    import away3d.materials.lightpickers.StaticLightPicker;
    import away3d.materials.methods.DitheredShadowMapMethod;
    import away3d.materials.methods.FilteredShadowMapMethod;
    import away3d.materials.methods.FogMethod;
    import away3d.primitives.PlaneGeometry;
    import away3d.primitives.SkyBox;
    import away3d.primitives.TorusGeometry;
    import away3d.textures.BitmapCubeTexture;
    import away3d.tools.helpers.LightsHelper;
    import away3d.utils.Cast;
    import flash.display.BitmapData;
    import flash.display.Bitmap;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.filters.DropShadowFilter;
    import flash.geom.Vector3D;
    import flash.net.URLLoaderDataFormat;
    import flash.net.URLRequest;
    import flash.system.LoaderContext;
    import flash.system.Security;
    import flash.text.TextField;
    import flash.text.TextFormat;
    import flash.ui.Keyboard;
    import flash.utils.getTimer;
    import jp.progression.commands.lists.LoaderList;
    import jp.progression.commands.net.LoadBitmapData;
    import jp.progression.data.getResourceById;
    import org.flintparticles.integration.away3d.v4.A3D4Renderer;
    
    /**
     * away3d v4.0.X test2
     * 
     * @author flashisobar http://flashisobar.blogspot.com/
     * 
     * Press SPACE to show fog effect
     * 
     * demo:
     * Point light
     * Directional light
     * Skybox
     * Shadow
     * LightsHelper - applys lights to all materials
     * Loader3D - load 3D Object(awd file format)
     * Flint3D - fog/cloud effect
     *
     * 3D model by SolCommand http://www.solcommand.com/
     * Create cloud reference http://wonderfl.net/c/h9dR
     * Skybox map reference https://github.com/away3d/away3d-examples-fp11/
     *
     */
    [SWF(width="465",height="465",frameRate="60",backgroundColor="0x0")]
    
    public class Main extends Sprite
    {
        private const BASE_URL:String = "http://labs-baybow.rhcloud.com/";
        private var scene:Scene3D;
        private var camera:Camera3D;
        private var view:View3D;
        private var stats:AwayStats;
        private var plight:PointLight;
        private var dlight:DirectionalLight;
        private var lightPicker:StaticLightPicker;
        private var torustexture:ColorMaterial;
        private var torus:Mesh;
        
        private var cameraController:HoverController;
        private var move:Boolean;
        private var lastPanAngle:Number;
        private var lastTiltAngle:Number;
        private var lastMouseX:Number;
        private var lastMouseY:Number;
        
        // Environment map for skybox
        private var arrSkyboxMap:Array = [
                        "snow_positive_x.jpg",
                        "snow_positive_y.jpg",
                        "snow_positive_z.jpg",
                        "snow_negative_x.jpg",
                        "snow_negative_y.jpg",
                        "snow_negative_z.jpg"
                    ]
        private var skybox:SkyBox;
        private var sunLight:DirectionalLight;
        
        private var _loader:Loader3D;
        private var _objContainer:ObjectContainer3D;
        
        private var emitter:EmitterSmoke;
        private var particleContainer:ObjectContainer3D;
        private var particleRenderer:A3D4Renderer;
        private var isFog:Boolean = true;
        private var _text:TextField;
        
        ///private var source:BitmapData = new BitmapData(465, 465, false, 0x000000);
        
        public function Main():void
        {
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            
            if (stage)
                init();
            else
                addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        private function init(e:Event = null):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            // entry point
            Wonderfl.disable_capture();
            Security.loadPolicyFile('http://labs-baybow.rhcloud.com/crossdomain.xml');
            ///addChild(new Bitmap(source));
            
            // debug
            //Debug.active = true;

            initText();
            initLoading();
            //init3D();
            //initText();
        }
        
        private function initLoading():void 
        {
            trace("init");
            var loaderlist:LoaderList = new LoaderList();
            loaderlist.onStart = function():void {
                trace("onStart");
            }
            loaderlist.onProgress = function():void {
                trace("onProgress:", this.percent, "%", this.loaded, "/", this.total);
                _text.text = "loading texture: "+ int(this.percent)+" %";
            }
            loaderlist.onComplete = function():void {
                trace("onComplete");
                _text.text = "loading 3D model";
                Parsers.enableAllBundled();
                _loader = new Loader3D();
                _loader.scale(2);
                _loader.addEventListener(LoaderEvent.RESOURCE_COMPLETE, onResourceComplete);
                _loader.addEventListener(LoaderEvent.LOAD_ERROR, onLoadError);
                _loader.load(new URLRequest(BASE_URL + 'assets/3d/ship.awd'));

            }
            for (var i:int = 0; i < arrSkyboxMap.length; i++) 
            {
                loaderlist.addCommand(new LoadBitmapData(new URLRequest(BASE_URL + "assets/" +arrSkyboxMap[i]), { context: new LoaderContext(true), resId:"map" + i } ));
            }
            loaderlist.execute();
        }

        private function onResourceComplete(ev:LoaderEvent):void 
        {
            _loader.removeEventListener(LoaderEvent.RESOURCE_COMPLETE, onResourceComplete);
            _loader.removeEventListener(LoaderEvent.LOAD_ERROR, onLoadError);
            
            init3D();
            showHelp();
            initListener();
        }
        
        private function showHelp():void 
        {
            _text.text = "SPACE - switch fog\n";
            _text.appendText("Mouse click and drag\n\n");
            _text.appendText("3D model by SolCommand\n");
        }
        
        private function initListener():void 
        {
            addEventListener(Event.ENTER_FRAME, _onEnterFrame);
            stage.addEventListener(Event.RESIZE, onResize);            
            onAddedToStage();
            onResize();
        }
        
        private function initText():void
        {
            _text = new TextField();
            _text.defaultTextFormat = new TextFormat("Arial", 11, 0xFFFFFF);
            _text.width = 240;
            _text.height = 100;
            _text.selectable = false;
            _text.mouseEnabled = false;
            _text.text = "loading texture: 0 %";
            _text.filters = [new DropShadowFilter(1, 45, 0x0, 1, 0, 0)];

            addChild(_text);
        }
        
        /*
         * scene
         * camera + controller
         * view
         * light
         * 3D Object
         * render
         */
        private function init3D():void
        {
            scene = new Scene3D();
            camera = new Camera3D();
            camera.x = 0;
            camera.y = 100;
            camera.z = -1000;
            camera.lookAt(new Vector3D());
            
            cameraController = new HoverController(camera, null, 45, 20);
            
            view = new View3D();
            view.backgroundColor = 0x222233;
            view.antiAlias = 4; // 2,4,16
            view.scene = scene;
            view.camera = camera;
            addChild(view);
            
            // light
            // create a light for shadows that mimics the sun's position in the skybox
            // 太陽光-方向性光源
            sunLight = new DirectionalLight();
            sunLight.castsShadows = true;
            sunLight.direction = new Vector3D(-1, -1, -1);
            sunLight.ambient = .1;    // 環境
            sunLight.diffuse = .7;
            scene.addChild(sunLight);
            
            // create a light for ambient effect that mimics the sky
            // 環境光-無方向性點光源
            plight = new PointLight();
            plight.position = new Vector3D(0, 100, -1000);
            plight.color = 0xFFFFFF;
            plight.specular = .1;    // 反射
            plight.diffuse = .7;    // 發散
            plight.radius = 2000;
            plight.fallOff = 2500;
            scene.addChild(plight);
            
            lightPicker = new StaticLightPicker([sunLight, plight]);
            
            //var axis:Trident = new Trident(250, true);
            //scene.addChild(axis);
            
            // skybox
            //var cubeTexture:BitmapCubeTexture = new BitmapCubeTexture(Cast.bitmapData(EnvPosX), Cast.bitmapData(EnvNegX), Cast.bitmapData(EnvPosY), Cast.bitmapData(EnvNegY), Cast.bitmapData(EnvPosZ), Cast.bitmapData(EnvNegZ))
            var cubeTexture:BitmapCubeTexture = new BitmapCubeTexture(Cast.bitmapData(getResourceById("map0").data), Cast.bitmapData(getResourceById("map3").data), Cast.bitmapData(getResourceById("map1").data), Cast.bitmapData(getResourceById("map4").data), Cast.bitmapData(getResourceById("map2").data), Cast.bitmapData(getResourceById("map5").data))
            skybox = new SkyBox(cubeTexture);
            scene.addChild(skybox);
            
            // floor
            //var floor:WireframePlane = new WireframePlane(2000, 2000, 20, 20, 0x0F0F0F, 1,"xz");
            var texture_floor:ColorMaterial = new ColorMaterial(0x333333, .8);
            var floor:Mesh = new Mesh(new PlaneGeometry(2500, 2500, 20, 20), texture_floor);
            // apply shadow effect
            //texture_floor.shadowMethod = new DitheredShadowMapMethod(sunLight);    // 陰影不這麼銳利
            texture_floor.shadowMethod = new FilteredShadowMapMethod(sunLight);    // 一般陰影
            texture_floor.specular = 0;    // 不要有反射
            texture_floor.lightPicker = lightPicker;
            floor.y = -500;
            scene.addChild(floor);
            
            // donut
            var torusgeometry:TorusGeometry = new TorusGeometry(80, 60, 40, 20);
            var texture2:ColorMaterial = new ColorMaterial(Math.random() * 0xFFFFFF, 1);
            texture2.lightPicker = lightPicker;
            torus = new Mesh(torusgeometry, texture2);
            scene.addChild(torus);
            
            // add 3D Object
            _objContainer = new ObjectContainer3D();
            scene.addChild(_objContainer);
            _loader.x = 450;
            _objContainer.addChild(_loader);
            //scene.addChild(_loader);
            // apply lights
            var lights:Vector.<LightBase> = new Vector.<LightBase>(2);
            lights[0] = sunLight;
            lights[1] = plight;
            LightsHelper.addStaticLightsToMaterials(_loader, lights);

            // flint
            emitter = new EmitterSmoke();
            emitter.start();
            
            // Create Particle Container
            particleContainer = new ObjectContainer3D();
            particleContainer.visible = isFog;
            scene.addChild(particleContainer);
            
            particleRenderer = new A3D4Renderer(particleContainer);
            particleRenderer.addEmitter(emitter);
            
            // stats
            stats = new AwayStats(view);
            stats.x = stage.stageWidth - stats.width;
            addChild(stats);
        }
        
        private function onLoadError(ev:LoaderEvent):void
        {
            trace('Could not find', ev.url);
            _loader.removeEventListener(LoaderEvent.RESOURCE_COMPLETE, onResourceComplete);
            _loader.removeEventListener(LoaderEvent.LOAD_ERROR, onLoadError);
            _loader = null;
        }
        
        private function onResize(event:Event = null):void
        {
            view.width = stage.stageWidth;
            view.height = stage.stageHeight;
        }
        
        private function onAddedToStage(e:Event = null):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
            
            stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
            stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
            stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
        }
        
        private function onKeyDown(e:KeyboardEvent):void 
        {
            switch (e.keyCode) {
                case Keyboard.SPACE:
                    isFog = !isFog;
                    particleContainer.visible = isFog;
                    break;
            }
        }
        
        private function onMouseDown(event:MouseEvent):void
        {
            lastPanAngle = cameraController.panAngle;
            lastTiltAngle = cameraController.tiltAngle;
            lastMouseX = stage.mouseX;
            lastMouseY = stage.mouseY;
            move = true;
            stage.addEventListener(Event.MOUSE_LEAVE, onStageMouseLeave);
        }
        
        private function onMouseUp(event:MouseEvent):void
        {
            move = false;
            stage.removeEventListener(Event.MOUSE_LEAVE, onStageMouseLeave);
        }
        
        private function onStageMouseLeave(event:Event):void
        {
            move = false;
            stage.removeEventListener(Event.MOUSE_LEAVE, onStageMouseLeave);
        }
        
        private function _onEnterFrame(e:Event):void
        {
            var msec:Number = getTimer();

            if (move)
            {
                cameraController.panAngle = 0.3 * (stage.mouseX - lastMouseX) + lastPanAngle;
                cameraController.tiltAngle = 0.3 * (stage.mouseY - lastMouseY) + lastTiltAngle;
            }
            plight.position = camera.position;
            
            // update 3D object
            torus.rotationZ += 1;
            torus.y = (Math.sin(msec / 200) * 200);
            _objContainer.rotationY += 1;
            //_objContainer.z -= 1;
            view.render();
            ///view.renderer.queueSnapshot(source);
        }
    }

}


import flash.display.Bitmap;
import flash.geom.Vector3D;
import org.flintparticles.common.actions.Age;
import org.flintparticles.common.actions.Fade;
import org.flintparticles.common.actions.ScaleImage;
import org.flintparticles.common.actions.TargetScale;
import org.flintparticles.common.counters.Steady;
import org.flintparticles.common.displayObjects.RadialDot;
import org.flintparticles.common.initializers.Lifetime;
import org.flintparticles.threeD.actions.DeathZone;
import org.flintparticles.threeD.actions.Move;
import org.flintparticles.threeD.actions.RandomDrift;
import org.flintparticles.threeD.emitters.Emitter3D;
import org.flintparticles.threeD.initializers.Position;
import org.flintparticles.threeD.initializers.Velocity;
import org.flintparticles.threeD.zones.BoxZone;
import org.flintparticles.threeD.actions.Friction;

class EmitterSmoke extends Emitter3D
{
    public function EmitterSmoke()
    {
        counter = new Steady(10);
        
        addInitializer(new Position(new BoxZone(100, 100, 1000, new Vector3D(1000, 0, 0))));
        //addInitializer(new Lifetime(10));
        addInitializer(new Velocity(new BoxZone(200, 20, 200, new Vector3D(-100, 0, 0)))); // 雲移動的方向速度
        addInitializer(new A3D4DisplayObjects([
                new Bitmap(new Materials().cloud1),
                new Bitmap(new Materials().cloud2),
                new Bitmap(new Materials().cloud3),
                new Bitmap(new Materials().cloud4)],
            null, true, 300));
        
        //addAction(new Age());
        addAction(new Move());
        addAction(new ScaleImage(4, 10));
        addAction(new Friction(0.9));
        addAction(new Fade(0.7, 1.0));
        addAction(new TargetScale(10));
        addAction(new RandomDrift(50, 10, 50)); // 亂數飄移XYZ方向
        addAction(new DeathZone(new BoxZone(2000, 1000, 2000), true));
    }
}



import away3d.entities.Sprite3D;
//import away3d.materials.AnimatedBitmapMaterial;
import away3d.materials.MaterialBase;
import away3d.materials.TextureMaterial;
import away3d.textures.BitmapTexture;

import org.flintparticles.common.initializers.ImageInitializerBase;
import org.flintparticles.common.utils.WeightedArray;

import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.MovieClip;
import flash.geom.Matrix;
import flash.geom.Rectangle;

/**
 * The A3D4DisplayObjects Initializer sets the DisplayObject to use to 
 * draw the particle in a 3D scene. It is used with the Away3D renderer when
 * particles should be represented by one of a number of display objects.
 * 
 * <p>The initializer creates an Away3D Sprite3D and a BitmapMaterial, with the display object
 * as the image source for the material, for rendering the display 
 * object in an Away3D scene.</p>
 * 
 * <p>This class includes an object pool for reusing objects when particles die.</p>
 */
class A3D4DisplayObjects extends ImageInitializerBase
{
    private var _displayObjects:WeightedArray;
    
    /**
     * The constructor creates an A3D4DisplayObjects initializer for use by 
     * an emitter. To add an A3D4DisplayObjects to all particles created by 
     * an emitter, use the emitter's addInitializer method.
     * 
     * @param displayObjects An array containing the DisplayObjects to use for 
     * each particle created by the emitter.
     * @param weights The weighting to apply to each DisplayObject. If no weighting
     * values are passed, the DisplayObjects are used with equal probability.
     * @param usePool Indicates whether particles should be reused when a particle dies.
     * @param fillPool Indicates how many particles to create immediately in the pool, to
     * avoid creating them when the particle effect is running.
     * 
     * @see org.flintparticles.common.emitters.Emitter#addInitializer()
     */
    public function A3D4DisplayObjects( displayObjects:Array, weights:Array = null, usePool:Boolean = false, fillPool:uint = 0 )
    {
        super( usePool );
        _displayObjects = new WeightedArray();
        var len:int = displayObjects.length;
        var i:int;
        if( weights != null && weights.length == len )
        {
            for( i = 0; i < len; ++i )
            {
                addDisplayObject( displayObjects[i], weights[i] );
            }
        }
        else
        {
            for( i = 0; i < len; ++i )
            {
                addDisplayObject( displayObjects[i], 1 );
            }
        }
        if( fillPool > 0 )
        {
            this.fillPool( fillPool );
        }
    }
    
    public function addDisplayObject( displayObject:DisplayObject, weight:Number = 1 ):void
    {
        _displayObjects.add( displayObject, weight );
        if( _usePool )
        {
            clearPool();
        }
    }
    
    public function removeDisplayObject( displayObject:DisplayObject ):void
    {
        _displayObjects.remove( displayObject );
        if( _usePool )
        {
            clearPool();
        }
    }
    
    /**
     * Used internally, this method creates an image object for displaying the particle 
     * by creating a Sprite3D and using one of the display objects as its material.
     */
    override public function createImage():Object
    {
        var displayObject:DisplayObject = _displayObjects.getRandomValue();
        var material:MaterialBase;
        if( displayObject is MovieClip )
        {
            //material = new AnimatedBitmapMaterial( MovieClip( displayObject ), true, true );
        }
        else
        {
            var bounds:Rectangle = displayObject.getBounds( displayObject );
            var width:int = textureSize( bounds.width );
            var height:int = textureSize( bounds.height );
            var bitmapData:BitmapData = new BitmapData( width, height, true, 0x00FFFFFF );
            var matrix:Matrix = displayObject.transform.matrix.clone();
            matrix.translate( -bounds.left, -bounds.top );
            matrix.scale( width / bounds.width, height / bounds.height );
            bitmapData.draw( displayObject, matrix, displayObject.transform.colorTransform, null, null, true );
            //material = new BitmapMaterial( bitmapData, true, true );
            material = new TextureMaterial(new BitmapTexture(bitmapData));
            material.smooth = true;
            material.repeat = true;

        }
        return new Sprite3D( material, displayObject.width, displayObject.height );
    }
    
    private function textureSize( value:Number ):int
    {
        var val:int = Math.ceil( value );
        var count:int = 0;
        while( val )
        {
            count++;
            val = val >>> 1;
        }
        return 1 << count + 1;
    }
}


import flash.display.BitmapData;
import flash.geom.Rectangle;

class Materials
{
    /**perlinNoiseに使うとまずいシード値(画像に穴があくかもしれない)*/
    public const ERROR_SEEDS:Array = [346, 514, 1155, 1519, 1690, 1977, 2327, 2337, 2399, 2860, 2999, 3099, 4777, 4952, 5673, 6265, 7185, 7259, 7371, 7383, 7717, 7847, 8032, 8350, 8676, 8963, 8997, 9080, 9403, 9615, 9685];
    public const CLOUD_SIZE:Rectangle = new Rectangle(0, 0, 200, 100);
    public var cloud1:BitmapData;
    public var cloud2:BitmapData;
    public var cloud3:BitmapData;
    public var cloud4:BitmapData;
    
    public function Materials()
    {
        var ct:Number = (Math.random() < 0.3) ? Math.random() * 0.3 : Math.random() * 1.5;
        cloud1 = Painter.createCloud(CLOUD_SIZE.width, CLOUD_SIZE.height, rndSeed(), ct, Color.cloudBase, Color.cloudLight, Color.cloudShadow);
        ct = (Math.random() < 0.3) ? Math.random() * 0.3 : Math.random() * 1.5;
        cloud2 = Painter.createCloud(CLOUD_SIZE.width, CLOUD_SIZE.height, rndSeed(), ct, Color.cloudBase, Color.cloudLight, Color.cloudShadow);
        ct = (Math.random() < 0.3) ? Math.random() * 0.3 : Math.random() * 1.5;
        cloud3 = Painter.createCloud(CLOUD_SIZE.width, CLOUD_SIZE.height, rndSeed(), ct, Color.cloudBase, Color.cloudLight, Color.cloudShadow);
        ct = (Math.random() < 0.3) ? Math.random() * 0.3 : Math.random() * 1.5;
        cloud4 = Painter.createCloud(CLOUD_SIZE.width, CLOUD_SIZE.height, rndSeed(), ct, Color.cloudBase, Color.cloudLight, Color.cloudShadow);
    }

    
    private function rndSeed():int
    {
        var seed:int = Math.random() * 10000 + 1;
        if (ERROR_SEEDS.indexOf(seed) >= 0) seed++;
        return seed;
    }

}

import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.display.Sprite;
import flash.filters.BevelFilter;
import flash.filters.ColorMatrixFilter;
import flash.filters.GlowFilter;
import flash.geom.Matrix;
import flash.geom.Point;

/**
 * 色
 */
class Color
{
    /**雲の色*/
    static public var cloudBase:uint = 0xD7DDE5;
    /**雲のハイライト色*/
    static public var cloudLight:uint = 0xFFFFFF;
    /**雲の影の色*/
    static public var cloudShadow:uint = 0x6D8790;
}

class Painter
{
    /**
     * 雲画像生成
     * @param    width    幅
     * @param    height    高さ
     * @param    seed    ランダムシード値
     * @param    contrast    コントラスト0~
     * @param    color    ベースの色
     * @param    light    明るい色
     * @param    shadow    暗い色
     */
    static public function createCloud(width:int, height:int, seed:int, contrast:Number = 1, color:uint = 0xFFFFFF, light:uint = 0xFFFFFF, shadow:uint = 0xDDDDDD):BitmapData
    {
        var gradiation:Sprite = new Sprite();
        var drawMatrix:Matrix = new Matrix();
        drawMatrix.createGradientBox(width, height);
        gradiation.graphics.beginGradientFill("radial", [0x000000, 0x000000], [0, 1], [0, 255], drawMatrix);
        gradiation.graphics.drawRect(0, 0, width, height);
        gradiation.graphics.endFill();
        var alphaBmp:BitmapData = new BitmapData(width, height);
        alphaBmp.perlinNoise(width / 3, height / 2.5, 5, seed, false, true, 1 | 2 | 4, true);
        var zoom:Number = 1 + (contrast - 0.1) / (contrast + 0.9);
        if (contrast < 0.1)
            zoom = 1;
        if (contrast > 2.0)
            zoom = 2;
        var ctMatrix:Array = [contrast + 1, 0, 0, 0, -128 * contrast, 0, contrast + 1, 0, 0, -128 * contrast, 0, 0, contrast + 1, 0, -128 * contrast, 0, 0, 0, 1, 0];
        alphaBmp.draw(gradiation, new Matrix(zoom, 0, 0, zoom, -(zoom - 1) / 2 * width, -(zoom - 1) / 2 * height));
        alphaBmp.applyFilter(alphaBmp, alphaBmp.rect, new Point(), new ColorMatrixFilter(ctMatrix));
        var image:BitmapData = new BitmapData(width, height, true, 0xFF << 24 | color);
        image.copyChannel(alphaBmp, alphaBmp.rect, new Point(), 4, 8);
        image.applyFilter(image, image.rect, new Point(), new GlowFilter(light, 1, 4, 4, 1, 3, true));
        var bevelSize:Number = Math.min(width, height) / 30;
        image.applyFilter(image, image.rect, new Point(), new BevelFilter(bevelSize, 45, light, 1, shadow, 1, bevelSize / 5, bevelSize / 5, 1, 3));
        var image2:BitmapData = new BitmapData(width, height, true, 0);
        image2.draw(Painter.createGradientRect(width, height, [light, color, shadow], [1, 0.2, 1], null, 90), null, null, BlendMode.MULTIPLY);
        image2.copyChannel(alphaBmp, alphaBmp.rect, new Point(), 4, 8);
        image.draw(image2, null, null, BlendMode.MULTIPLY);
        alphaBmp.dispose();
        return image;
    }
    
    /**
     * グラデーションスプライト生成
     */
    static public function createGradientRect(width:Number, height:Number, colors:Array, alphas:Array, ratios:Array = null, rotation:Number = 0):Sprite
    {
        var i:int, rts:Array = new Array();
        if (ratios == null)
            for (i = 0; i < colors.length; i++)
                rts.push(int(255 * i / (colors.length - 1)));
        else
            for (i = 0; i < ratios.length; i++)
                rts[i] = Math.round(ratios[i] * 255);
        var sp:Sprite = new Sprite();
        var mtx:Matrix = new Matrix();
        mtx.createGradientBox(width, height, Math.PI / 180 * rotation, 0, 0);
        if (colors.length == 1 && alphas.length == 1)
            sp.graphics.beginFill(colors[0], alphas[0]);
        else
            sp.graphics.beginGradientFill("linear", colors, alphas, rts, mtx);
        sp.graphics.drawRect(0, 0, width, height);
        sp.graphics.endFill();
        return sp;
    }
}