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

Caustics

Get Adobe Flash player
by devon_o 30 Aug 2013
/**
 * Copyright devon_o ( http://wonderfl.net/user/devon_o )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/hzeT
 */

package
{
    import com.adobe.utils.AGALMiniAssembler;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.display3D.Context3D;
    import flash.display3D.Context3DProgramType;
    import flash.display3D.Context3DVertexBufferFormat;
    import flash.display3D.IndexBuffer3D;
    import flash.display3D.Program3D;
    import flash.display3D.VertexBuffer3D;
    import flash.events.Event;
    import flash.geom.Matrix3D;
    
    /**
     * Ported from: http://glsl.heroku.com/e#10585.0
     * @author Devon O.
     */

    [SWF(width="465", height="465", frameRate="60", backgroundColor="#000000")]
    public class Caustics extends Sprite
    {
        
        private static const FRAGMENT_SHADER:String =
    <![CDATA[
        //vec2 p = surfacePosition*8.0- vec2(20.0);
        mul ft0.xy, v0.xy, fc0.xx
        sub ft0.xy, ft0.xy, fc0.yy
        
        //vec2 i = p;
        mov ft1.xy, ft0.xy
        
        //float c = 1.0;
        mov ft1.z, fc0.w
        
        // ft0.w = n
        mov ft0.w, fc0.w
        //for (int n = 0; n < MAX_ITER; n++) 
            //--------LOOP 1----------
            //float t = time * (1.0 - (3.0 / n));
            div ft2.x, fc1.y, ft0.w
            sub ft2.x, fc0.w, ft2.x
            mul ft2.x, ft2.x, fc1.x
            
            //i = p + vec2(cos(t - i.x) + sin(t + i.y), sin(t - i.y) + cos(t + i.x));
            mov ft6.xy, ft1.xy
            sub ft3.x, ft2.x, ft6.x
            cos ft3.x, ft3.x
            add ft3.y, ft2.x, ft6.y
            sin ft3.y, ft3.y
            add ft1.x, ft3.x, ft3.y
            
            sub ft3.z, ft2.x, ft6.y
            sin ft3.z, ft3.z
            add ft3.w, ft2.x, ft6.x
            cos ft3.w, ft3.w
            add ft1.y, ft3.z, ft3.w
            
            //c += 1.0/length(vec2(p.x / (sin(i.x+t)/inten),   p.y / (cos(i.y+t)/inten)));
            add ft3.x, ft1.x, ft2.x
            sin ft3.x, ft3.x
            div ft3.x, ft3.x, fc0.z
            div ft3.x, ft0.x, ft3.x
            
            add ft3.y, ft1.y, ft2.x
            cos ft3.y, ft3.y
            div ft3.y, ft3.y, fc0.z
            div ft3.y, ft0.y, ft3.y
            
            dp3 ft3.x, ft3.xy, ft3.xy
            sqt ft3.x, ft3.x
            rcp ft3.x, ft3.x
            add ft1.z, ft1.z, ft3.x
            
            // increment loop counter
            add ft0.w, ft0.w, fc0.w
            
            //--------LOOP 2-----------
            //float t = time * (1.0 - (3.0 / n));
            div ft2.x, fc1.y, ft0.w
            sub ft2.x, fc0.w, ft2.x
            mul ft2.x, ft2.x, fc1.x
            
            //i = p + vec2(cos(t - i.x) + sin(t + i.y), sin(t - i.y) + cos(t + i.x));
            mov ft6.xy, ft1.xy
            sub ft3.x, ft2.x, ft6.x
            cos ft3.x, ft3.x
            add ft3.y, ft2.x, ft6.y
            sin ft3.y, ft3.y
            add ft1.x, ft3.x, ft3.y
            
            sub ft3.z, ft2.x, ft6.y
            sin ft3.z, ft3.z
            add ft3.w, ft2.x, ft6.x
            cos ft3.w, ft3.w
            add ft1.y, ft3.z, ft3.w
            
            //c += 1.0/length(vec2(p.x / (sin(i.x+t)/inten),   p.y / (cos(i.y+t)/inten)));
            add ft3.x, ft1.x, ft2.x
            sin ft3.x, ft3.x
            div ft3.x, ft3.x, fc0.z
            div ft3.x, ft0.x, ft3.x
            
            add ft3.y, ft1.y, ft2.x
            cos ft3.y, ft3.y
            div ft3.y, ft3.y, fc0.z
            div ft3.y, ft0.y, ft3.y
            
            dp3 ft3.x, ft3.xy, ft3.xy
            sqt ft3.x, ft3.x
            rcp ft3.x, ft3.x
            add ft1.z, ft1.z, ft3.x
            
            // increment loop counter
            add ft0.w, ft0.w, fc0.w
            
            //--------LOOP 3----------
            //float t = time * (1.0 - (3.0 / n));
            div ft2.x, fc1.y, ft0.w
            sub ft2.x, fc0.w, ft2.x
            mul ft2.x, ft2.x, fc1.x
            
            //i = p + vec2(cos(t - i.x) + sin(t + i.y), sin(t - i.y) + cos(t + i.x));
            mov ft6.xy, ft1.xy
            sub ft3.x, ft2.x, ft6.x
            cos ft3.x, ft3.x
            add ft3.y, ft2.x, ft6.y
            sin ft3.y, ft3.y
            add ft1.x, ft3.x, ft3.y
            
            sub ft3.z, ft2.x, ft6.y
            sin ft3.z, ft3.z
            add ft3.w, ft2.x, ft6.x
            cos ft3.w, ft3.w
            add ft1.y, ft3.z, ft3.w
            
            //c += 1.0/length(vec2(p.x / (sin(i.x+t)/inten),   p.y / (cos(i.y+t)/inten)));
            add ft3.x, ft1.x, ft2.x
            sin ft3.x, ft3.x
            div ft3.x, ft3.x, fc0.z
            div ft3.x, ft0.x, ft3.x
            
            add ft3.y, ft1.y, ft2.x
            cos ft3.y, ft3.y
            div ft3.y, ft3.y, fc0.z
            div ft3.y, ft0.y, ft3.y
            
            dp3 ft3.x, ft3.xy, ft3.xy
            sqt ft3.x, ft3.x
            
            rcp ft3.x, ft3.x
            add ft1.z, ft1.z, ft3.x
    //}
    //c /= float(MAX_ITER);
    div ft1.z, ft1.z, fc1.w
    
    //c = 1.5-sqrt(c);
    sqt ft1.z, ft1.z
    sub ft1.z, fc1.z, ft1.z
    
    //gl_FragColor = vec4(vec3(c*c*c*c), 1.0);
    mov ft4.xyz, ft1.zzz
    // crank up the blue
    add ft4.z, ft4.z, fc1.z
    mov ft4.w, fc0.w
    
    mov oc, ft4
    ]]>
        
        
        private var mContext3d:Context3D;
        private var mVertBuffer:VertexBuffer3D;
        private var mIndexBuffer:IndexBuffer3D; 
        private var mProgram:Program3D;
        
        private var mMatrix:Matrix3D = new Matrix3D();
        
        public function Caustics()
        {    
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);    
        }
        
        private function init(event:Event = null):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            
            initStage();
            setS3d();
    
            addEventListener(Event.ENTER_FRAME, onTick);
        }
        
        
        private function setS3d():void
        {
            stage.stage3Ds[0].addEventListener( Event.CONTEXT3D_CREATE, initStage3d );
            stage.stage3Ds[0].requestContext3D();
        }
        
        private function initStage():void
        {
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
        }
        
        private function initStage3d(event:Event):void
        {
            mContext3d = stage.stage3Ds[0].context3D;            
            
            mContext3d.configureBackBuffer(stage.stageWidth, stage.stageHeight, 1, true);
            
            var vertices:Vector.<Number> = Vector.<Number>([
            //    x        y        z            u     v
                -1.0,     -1.0,     0,          0, 0, 
                -1.0,      1.0,     0,             0, 1,
                 1.0,      1.0,     0,             1, 1,
                 1.0,     -1.0,     0,            1, 0  ]);
            
            mVertBuffer = mContext3d.createVertexBuffer(4, 5);
            mVertBuffer.uploadFromVector(vertices, 0, 4);
            
            mIndexBuffer = mContext3d.createIndexBuffer(6);            
            mIndexBuffer.uploadFromVector (Vector.<uint>([0, 1, 2, 2, 3, 0]), 0, 6);
    
            mContext3d.setVertexBufferAt(0, mVertBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
            mContext3d.setVertexBufferAt(1, mVertBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
            generateProgram();
            
            mContext3d.setProgram(mProgram);
        }
        
        
        private function generateProgram():void
        {
            var vertexShaderAssembler : AGALMiniAssembler = new AGALMiniAssembler();
            vertexShaderAssembler.assemble( Context3DProgramType.VERTEX,
                "m44 op, va0, vc0                                \n" +
                "mov v0, va1                                      "
            );
            
            var fragmentShaderAssembler : AGALMiniAssembler= new AGALMiniAssembler();
            fragmentShaderAssembler.assemble( Context3DProgramType.FRAGMENT, FRAGMENT_SHADER);
            
            mProgram = mContext3d.createProgram();
            mProgram.upload( vertexShaderAssembler.agalcode, fragmentShaderAssembler.agalcode);
        }
        
        
        private var mTime:Number = 0.0;
        private function onTick(event:Event):void
        {
            if ( !mContext3d ) 
                return;
            
            mContext3d.clear ( 0, 0, 0, 1 );
            mContext3d.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, mMatrix, true);
            
            mContext3d.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, Vector.<Number>( [ 6, 15, .05, 1 ]) );    
            mContext3d.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 1, Vector.<Number>( [ mTime, 3, 1.25, 3 ]) );
            
            mContext3d.drawTriangles(mIndexBuffer);
            mContext3d.present();
            
            mTime += .015;
            
        }
        
    }
}