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

Radial Blur

radial blur by stage3d
Get Adobe Flash player
by boycy815 17 Feb 2012
/**
 * Copyright boycy815 ( http://wonderfl.net/user/boycy815 )
 * GNU General Public License, v3 ( http://www.gnu.org/licenses/quick-guide-gplv3.html )
 * Downloaded from: http://wonderfl.net/c/Hkzg
 */

package 
{
    import com.adobe.utils.AGALMiniAssembler;
    import com.bit101.components.HSlider;
    import com.bit101.components.PushButton;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.display.Stage3D;
    import flash.display3D.Context3D;
    import flash.display3D.IndexBuffer3D;
    import flash.display3D.Program3D;
    import flash.display3D.textures.Texture;
    import flash.display3D.VertexBuffer3D;
    import flash.events.Event;
    import flash.geom.Matrix;
    import flash.geom.Matrix3D;
    import flash.net.FileFilter;
    import flash.net.FileReference;
    import flash.utils.ByteArray;
    import net.hires.debug.Stats;
    
    /**
     * http://www.cnblogs.com/flash3d
     * @author boycy815
     */
    public class Main extends Sprite 
    {
        private const WIDTH:Number = 512;
        private const HEIGHT:Number = 512;
        
        //stage3d五巨头
        private var _stage3d:Stage3D;
        private var _context3d:Context3D;
        private var _program3d:Program3D;
        private var _index:IndexBuffer3D;
        private var _vertex:VertexBuffer3D;
        private var _texture:Texture;
        
        
        //顶点着色程序
        //输出坐标后对坐标进行变换使坐标与纹理图像坐标对应
        //这是由于纹理的坐标原点是左上角,y轴向下,最大值为1最小值为0
        //而顶点的坐标原点则是在舞台中央,而且y轴向上,最大值为1最小值为-1
        private var _vertexProgram:String = "mov op, va0\n" +
                                            "mov vt0, va0\n" +
                                            "neg vt0.y, vt0.y\n" +
                                            "add vt0, vt0, vc0.y\n" +
                                            "div vt0, vt0, vc0.z\n" +
                                            "mov v0, vt0";
        
        //将变换矩阵拷到临时寄存器
        //进行采样
        private var _fragmentProgram_0:String =   "mov ft3, fc1\n" +
                                                  "mov ft4, fc2\n" +
                                                  "mov ft5, fc3\n" +
                                                  "mov ft6, fc4\n" +
                                                  "mov ft0, v0\n" +
                                                  "tex ft1, ft0, fs0<2d,linear,nomip>\n";
        
        //对矩阵按中心等比缩小固定值
        //对采样点应用矩阵变换以向中心移动位置
        //对变换后的采样点进行采样,并将颜色值累计到中间变量
        private var _fragmentProgram_1:String =   "sub ft3.x, ft3.x, fc0.z\n" +
                                                  "sub ft4.y, ft4.y, fc0.z\n" +
                                                  "add ft3.w, ft3.w, fc0.y\n" +
                                                  "add ft4.w, ft4.w, fc0.y\n" +
                                                  "m44 ft0, v0, ft3\n" +
                                                  "tex ft2, ft0, fs0<2d,linear,nomip>\n" +
                                                  "add ft1, ft1, ft2\n";
        
        //对累计的颜色值除以采样次数得到采样平均值,输出颜色值
        private var _fragmentProgram_2:String = "div ft1, ft1, fc0.w\n" +
                                                "mov oc, ft1";
        
        
        private const STEP:Number = 28;
        
        
        public function Main():void 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            _stage3d = stage.stage3Ds[0];
            _stage3d.addEventListener(Event.CONTEXT3D_CREATE, onCreate);
            _stage3d.requestContext3D();
            addChild(new Stats());
        }
        
        private function onCreate(e:Event):void
        {
            e.target.removeEventListener(Event.CONTEXT3D_CREATE, onCreate);
            
            _context3d = _stage3d.context3D;
            //_context3d.enableErrorChecking = true;
            
            var agal:AGALMiniAssembler = new AGALMiniAssembler();
            
            var fragmentProgram:String = _fragmentProgram_0;
            
            //在agal中累计STEP - 1次采样,注意不要超过程序最大长度
            //这个方法有点土,不知各路大大有没高招
            for (var i:int = 1; i < STEP; i++)
            {
                fragmentProgram = fragmentProgram + _fragmentProgram_1;
            }
            fragmentProgram = fragmentProgram + _fragmentProgram_2;
            
            var vp:ByteArray = agal.assemble("vertex", _vertexProgram);
            var fp:ByteArray = agal.assemble("fragment", fragmentProgram);
            _program3d = _context3d.createProgram();
            _program3d.upload(vp, fp);
            _context3d.setProgram(_program3d);
            
            _context3d.configureBackBuffer(WIDTH, HEIGHT, 0, false);
            _context3d.setBlendFactors("one", "zero");
            _context3d.setCulling("back");
            
            //两个三角形拼成平面
            _index = _context3d.createIndexBuffer(6);
            _index.uploadFromVector(new<uint>[0, 1, 2, 0, 2, 3], 0, 6);
            
            _vertex = _context3d.createVertexBuffer(4, 2);
            _vertex.uploadFromVector(new<Number>[-1, -1,
                                                -1, 1,
                                                 1, 1,
                                                 1, -1], 0, 4);
            _context3d.setVertexBufferAt(0, _vertex, 0, "float2");
            
            //上传纹理
            _texture = _context3d.createTexture(WIDTH, HEIGHT, "bgra", false);
            _context3d.setTextureAt(0, _texture);
            
            _context3d.setProgramConstantsFromVector("vertex", 0, new<Number>[0, 1, 2, 3]);
            //0.0025为一次缩放步长,0.005为一次缩放步长两倍
            _context3d.setProgramConstantsFromVector("fragment", 0, new<Number>[0, 0.0025, 0.005, STEP]);
            //单位矩阵,采用时候用
            _context3d.setProgramConstantsFromMatrix("fragment", 1, new Matrix3D());
            
            start();
        }
        
        private var _hs:HSlider;
        
        private function start():void
        {
            new PushButton(this, 82, 7, "open", onUpload);
            _hs = new HSlider(this, 192, 12, onBar);
            _hs.setSliderParams(0, 100, 50);
            _hs.enabled = false;
        }
        
        private function onBar(e:Event):void
        {
            var v:Number = e.currentTarget.value * 0.00005;
            _context3d.setProgramConstantsFromVector("fragment", 0, new<Number>[0, v, v * 2, STEP]);
            _context3d.clear(0, 0, 0, 0);
            _context3d.drawTriangles(_index);
            _context3d.present();
        }
        
        private function onUpload(e:Event):void
        {
            var fr:FileReference = new FileReference();
            fr.addEventListener(Event.SELECT, onSelect);
            fr.browse([new FileFilter("图片", "*.jpg;*.png")]);
        }
        
        private function onSelect(e:Event):void
        {
            e.currentTarget.removeEventListener(Event.SELECT, onSelect);
            e.currentTarget.addEventListener(Event.COMPLETE, onComplete);
            e.currentTarget.addEventListener(Event.OPEN, function(e:Event):void { } );
            e.currentTarget.load();
        }
        
        private function onComplete(e:Event):void
        {
            e.currentTarget.removeEventListener(Event.COMPLETE, onComplete);
            var loader:Loader = new Loader();
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderOnComplete);
            loader.loadBytes(e.currentTarget.data);
        }
        
        private function loaderOnComplete(e:Event):void
        {
            e.currentTarget.removeEventListener(Event.COMPLETE, loaderOnComplete);
            
            var btmap:BitmapData = new BitmapData(WIDTH, HEIGHT);
            btmap.draw(e.currentTarget.loader, new Matrix(1, 0, 0, 1, (WIDTH - e.currentTarget.loader.width) / 2, (HEIGHT - e.currentTarget.loader.height) / 2));
            
            _texture.uploadFromBitmapData(btmap);
            
            _context3d.clear(0, 0, 0, 0);
            _context3d.drawTriangles(_index);
            _context3d.present();
            
            _hs.enabled = true;
        }
    }
    
}