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

Clear Water (Stage3D vs. WebGL)

ver. js WebGL - http://jsdo.it/3cm/ydrm

minimalcomps.js - http://www.bit-101.com/blog/?p=3359

chrome 14 - run chrome.exe --ignore-gpu-blacklist
firefox 7 - about:config, search webgl, force-enable to true
Get Adobe Flash player
by zob 21 Oct 2011
/**
 * Copyright zob ( http://wonderfl.net/user/zob )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/r6Me
 */

/**
 * Copyright keim_at_Si ( http://wonderfl.net/user/keim_at_Si )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/enj6
 */

// forked from keim_at_Si's Clear Water with refraction rendering forked from: 3D水面 / Water 3D
// forked from saharan's 3D水面 / Water 3D
/**
 * [REMARK] You cannot compile this source code on wonderfl!!
 * [注意] このソースコードは wonderfl ではコンパイルできません !!
 */
package {
    import flash.system.LoaderContext;
    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;
    import flash.text.*;
    import flash.net.*;
    import com.bit101.components.*;
    import net.hires.debug.*;
    
    import com.adobe.utils.*;
    import flash.display3D.*;
    import flash.display3D.textures.*;
    //import org.si.ptolem.core.*;

//    [SWF(frameRate = "30", width="640", height="480")]
    /**
     * Clear Water 3D molehill version
     *
     * Click&Drag:Make wave
     * 
     * @author saharan
     * @modifyer keim_at_Si(refraction)
     */
    [SWF(frameRate = "60", width="465", height="465")]
    public class MainWaterBK extends Sprite {
        private const NUM_DETAILS:int = 64;
        private const INV_NUM_DETAILS:Number = 1 / NUM_DETAILS;
        private const MESH_SIZE:Number = 100;
        private const SURFACE_DETAILS:int = NUM_DETAILS-4;
        private const VCOUNT:int = SURFACE_DETAILS * SURFACE_DETAILS;
        private var count:uint;
        private var bmd:BitmapData, bmd2:BitmapData, bmd3:BitmapData, tmp2:BitmapData;
        private var loader:Loader, loader2:Loader;
        private var vertices:Vector.<Number>;
        private var transformedVertices:Vector.<Number>;
        private var indices:Vector.<int>;
        private var uvt:Vector.<Number>, uvt2:Vector.<Number>;
        private var heights:Vector.<Number>;
        private var velocity:Vector.<Number>;
        
/*      // for local
        private var refractionTexture:String = "_env1.png";
        private var reflectionTexture:String = "_env2.png";
//*/
        // for wonderfl
        private var refractionTexture:String = "http://assets.wonderfl.net/images/related_images/b/b2/b217/b2177f87d979a28b9bcbb6e0b89370e77ce22337";
        private var reflectionTexture:String = "http://assets.wonderfl.net/images/related_images/b/bb/bbf1/bbf12c60cf84e5ab43e059920783d036da25df48";
//*/
        private var viewedAngleH:Number = 0, rotH:Number = 0;
        private var viewedAngleV:Number = -20 * 0.017453292519943295, rotV:Number = 0;
        private var cameraDistance:Number = MESH_SIZE;// MESH_SIZE;
        private var focalLength:Number = MESH_SIZE * 4;// MESH_SIZE * 4;
        private var boxHeight:Number = MESH_SIZE*0.75;;// MESH_SIZE * 0.75;
        private var refractiveIndex:Number = 1.4;
        private var reflectionRatio:Number = 0.4;
        private var cameraPosition:Vector3D = new Vector3D();
        
        private var INDEX_PADDING:int = 9; //7
        
    //-------------------------------------------------- constructor
        function MainWaterBK() : void {
            // create surface
            Wonderfl.disable_capture();
            
            var i:int, j:int, idx:int;
            vertices = new Vector.<Number>(VCOUNT * INDEX_PADDING, true);
            transformedVertices = new Vector.<Number>(VCOUNT * 2, true);
            uvt = new Vector.<Number>(VCOUNT * 2, true);
            uvt2 = new Vector.<Number>(VCOUNT * 2, true);
            for (i = 0; i < VCOUNT; i++) {
                vertices[i*INDEX_PADDING]   = ((int(i/SURFACE_DETAILS)+2) * INV_NUM_DETAILS - 0.5) * MESH_SIZE;
                vertices[i*INDEX_PADDING+1] = ((int(i%SURFACE_DETAILS)+2) * INV_NUM_DETAILS - 0.5) * MESH_SIZE;
                vertices[i*INDEX_PADDING+2] = 0;
            }
            indices = new Vector.<int>();
            for (i=1; i<SURFACE_DETAILS; i++) for (j=1; j<SURFACE_DETAILS; j++) {
                idx = j * SURFACE_DETAILS + i;
                indices.push(idx-SURFACE_DETAILS-1, idx-SURFACE_DETAILS, idx, 
                             idx-SURFACE_DETAILS-1, idx, idx-1);
            }
            
            // create field
            heights = new Vector.<Number>(NUM_DETAILS * NUM_DETAILS, true);
            velocity = new Vector.<Number>(NUM_DETAILS * NUM_DETAILS, true);
            for (i = 0; i < NUM_DETAILS * NUM_DETAILS; i++) velocity[i] = heights[i] = 0;
            
            addEventListener(Event.ADDED_TO_STAGE, setup);
            
            addChild(new Stats);
        }

        private function setup(e:Event) : void {
            e.target.removeEventListener(e.type, arguments.callee);
            // load resource
            loader = new Loader();
            loader.load(new URLRequest(refractionTexture), new LoaderContext(true));
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaded);
            loader2 = new Loader();
            loader2.load(new URLRequest(reflectionTexture), new LoaderContext(true));
            loader2.contentLoaderInfo.addEventListener(Event.COMPLETE, loaded);
        }
        
        private function loaded(e:Event) : void {
            e.target.removeEventListener(e.type, arguments.callee);
            if (loader.content && loader2.content) {
                bmd  = Bitmap(loader.content).bitmapData;
                bmd2 = Bitmap(loader2.content).bitmapData;
                createCausticTexture();
                molehill_setup();
                // [modification] controlers
                new HUISlider(container, 0,  0, "Angle", function(e:Event):void { viewedAngleV = -e.target.value*0.017453292519943295;}).setSliderParams(0, 80, 20);
                new HUISlider(container, 0, 20, "Refraction", function(e:Event):void { refractiveIndex = e.target.value;}).setSliderParams(1, 3, 1.4);
                new HUISlider(container, 0, 40, "Reflection", function(e:Event):void { reflectionRatio = e.target.value;}).setSliderParams(0, 1, 0.4);
                addAllEventListeners();
            }
        }
        
        private function createCausticTexture() : void {
            tmp2 = new BitmapData(bmd2.width, bmd2.height, false, 0);
            bmd3 = new BitmapData(128, 128, false, 0x404040);
            var shape:Shape = new Shape(), g:Graphics = shape.graphics, m:Matrix=new Matrix();
            m.createGradientBox(96, 96);
            g.beginGradientFill("radial", [0xd0d0d0,0x808080,0x404040], [1,1,1], [0,48,255], m);
            g.drawRect(0, 0, 96, 96);
            g.endFill();
            bmd3.draw(shape, new Matrix(1,0,0,1,16,48));
        }
        
        private function addAllEventListeners() : void {
            // add all listeners     
            stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
            addEventListener(Event.ENTER_FRAME, frame);
            count = 0;
        }
        
    //-------------------------------------------------- events
        private function mouseDown(e:MouseEvent) : void {
            stage.addEventListener(MouseEvent.MOUSE_UP, mouseUp);
            stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseDrag);
            ripple((232.5 - mouseY)/ 465 * MESH_SIZE, (mouseX -232.5)/ 465 * MESH_SIZE, 20);
        }
        
        private function mouseUp(e:MouseEvent) : void {
            stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUp);
            stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseDrag);
        }
        
        private function mouseDrag(e:MouseEvent) : void {
            ripple((232.5 - mouseY)/ 465 * MESH_SIZE, (mouseX -232.5)/ 465 * MESH_SIZE, 3);
        }
        
        private function ripple(mx:Number, my:Number, intensity:Number) : void {
            var i:int, j:int, idx:int, dx:Number, dy:Number, acc:Number, imin:int, jmin:int, imax:int, jmax:int;
            mx = (mx / MESH_SIZE + 0.5) * NUM_DETAILS;
            my = (my / MESH_SIZE + 0.5) * NUM_DETAILS;
            imin = (mx > 5) ? int(mx - 3) : 2;
            jmin = (my > 5) ? int(my - 3) : 2;
            imax = (mx < NUM_DETAILS-5) ? int(mx + 4) : (NUM_DETAILS - 1);
            jmax = (my < NUM_DETAILS-5) ? int(my + 4) : (NUM_DETAILS - 1);
            for (i=imin; i<imax; i++) for (j=jmin; j<jmax; j++) {
                dx = mx - i;
                dy = my - j;
                acc = 3 - Math.sqrt(dx * dx + dy * dy);
                if (acc > 0) velocity[j*NUM_DETAILS+i] += acc*intensity;
            }
        }
        
    //-------------------------------------------------- on each frame
        private function frame(e:Event = null):void {
            count++;
            move();
            setMesh();
            molehill_draw();
        }

        private function move():void {
            // ---Water simulation---
            var i:int, j:int, idx:int, v:Number, imax:int, jmax:int;
            imax = jmax = NUM_DETAILS - 1;
            for (i=1; i<imax; i++) for (j=1; j<jmax; j++) {
                idx = j * NUM_DETAILS + i;
                heights[idx] += velocity[idx];
                if (heights[idx] > 100) heights[idx] = 100;
                else if (heights[idx] < -100) heights[idx] = -100;
            }
            for (i=1; i<imax; i++) for (j=1; j<jmax; j++) {
                idx = j * NUM_DETAILS + i;
                v = -heights[idx] * 4; idx-=NUM_DETAILS;
                v += heights[idx];     idx+=NUM_DETAILS-1;
                v += heights[idx];     idx+=2;
                v += heights[idx];     idx+=NUM_DETAILS-1;
                v += heights[idx];     idx-=NUM_DETAILS;
                velocity[idx] = (velocity[idx] + v * 0.5) * 0.9;
            }
            
            // why dont I use Matrix3D !?
            /*
            var targetAngleH:Number = ((mouseX -232.5) / 465 * 40) * 0.017453292519943295,
                targetAngleV:Number = -((mouseY -232.5) / 465 * 40 + 40) * 0.017453292519943295;
            //*/
            var targetAngleH:Number = ((mouseX -232.5) / 465 * 80) * 0.017453292519943295,
                targetAngleV:Number = -((mouseY -232.5) / 465 * 80) * 0.017453292519943295;
            //*/
            rotH += (targetAngleH - viewedAngleH) * 0.01;
            rotV += (targetAngleV - viewedAngleV) * 0.01;
            viewedAngleH += (rotH *= 0.9);
            viewedAngleV += (rotV *= 0.9);
            modelviewMatrix.identity();
            modelviewMatrix.prependTranslation(0, 0, cameraDistance);
            modelviewMatrix.prependRotation(- viewedAngleV * (57.29577951308232), Vector3D.X_AXIS);
            modelviewMatrix.prependRotation( -viewedAngleH * (57.29577951308232), Vector3D.Y_AXIS);
            
            _invmat.copyFrom(modelviewMatrix);
            _invmat.invert();
            //_invmat.copyRowTo(3, cameraPosition);
            _invmat.copyColumnTo(3, cameraPosition);
            //cameraPosition.negate();
        }
        private var _invmat:Matrix3D = new Matrix3D();

        private function setMesh():void {
            var i:int, j:int, index:int, len:Number, u:Number, v:Number,
                t:Number, s:Number, r:Number, hitz:Number, sign:Number,
                vx:Number, vy:Number, vz:Number, 
                nx:Number, ny:Number, nz:Number, 
                dx:Number, dy:Number, dz:Number, 
                rimo:Number = refractiveIndex - 1,
                xymax:Number = MESH_SIZE * 0.45, //MESH_SIZE * 0.5,
                ixymax:Number = 1 / xymax;
            
            for (i = 0; i < SURFACE_DETAILS; i++) {
                for (j = 0; j < SURFACE_DETAILS; j++) {
                    index = (j * SURFACE_DETAILS + i) * INDEX_PADDING;
                    len = heights[(j + 2) * NUM_DETAILS + i + 2];
                    //trace("len = ",len);
                    vx = vertices[index]; index++;
                    vy = vertices[index]; index++;
                    vz = vertices[index] = len * 0.25; index++;
                    
                    // ---Sphere map---
                    nx = (len - heights[(j+2)*NUM_DETAILS+i+1]) * 0.25;
                    ny = (len - heights[(j+1)*NUM_DETAILS+i+2]) * 0.25;
                    nz = 1 / Math.sqrt(nx * nx + ny * ny + 1);
                    nx *= nz;
                    ny *= nz;
                    
                    // [modification] Refraction map
                    // incident vector (you can calculate them in the setup if you want faster)
                    dx = vx - cameraPosition.x;
                    dy = vy - cameraPosition.y;
                    dz = vz - cameraPosition.z;
                    len = 1 / Math.sqrt(dx * dx + dy * dy + dz * dz);
                    dx *= len;
                    dy *= len;
                    dz *= len;
                    // output vector
                    t = (dx * nx + dy * ny + dz) * rimo;
                    dx += nx * t;
                    dy += ny * t;
                    dz += nz * t;
                    // in this calculation, we can omit normalization of output vector !
                    //len = 1 / Math.sqrt(dx * dx + dy * dy + dz * dz);
                    //dx *= len;
                    //dy *= len;
                    //dz *= len;
                    // uv coordinate
                    if (dx == 0) {
                        if (dy == 0) {
                            u = v = 0.5;
                            sign = 0;
                        } else sign = (dy < 0) ? -1 : 1;
                    } else {
                        sign = (dx < 0) ? -1 : 1;
                        t = (sign * xymax - vx) / dx;
                        s = t * dy + vy;
                        if (-xymax < s && s < xymax) {
                            hitz = t * dz + vz;
                            if (hitz > boxHeight) {
                                r = (boxHeight-vz) / dz;
                                u = (dx * r + vx) * ixymax * 0.25 + 0.5;
                                v = (dy * r + vy) * ixymax * 0.25 + 0.5;
                            } else {
                                r = boxHeight / (hitz + boxHeight);
                                u = sign       * r * 0.5 + 0.5;
                                v = s * ixymax * r * 0.5 + 0.5;
                            }
                            sign = 0;
                        } else sign = (dy < 0) ? -1 : 1;
                    }
                    if (sign != 0) {
                        t = (sign * xymax - vy) / dy;
                        s = t * dx + vx;
                        hitz = t * dz + vz;
                        if (hitz > boxHeight) {
                            r = (boxHeight-vz) / dz;
                            u = (dx * r + vx) * ixymax * 0.25 + 0.5;
                            v = (dy * r + vy) * ixymax * 0.25 + 0.5;
                        } else {
                            r = boxHeight / (hitz + boxHeight);
                            u = s * ixymax * r * 0.5 + 0.5;
                            v = sign       * r * 0.5 + 0.5;
                        }
                    }
                    vertices[index] = nx * 0.5 + 0.5 + ((i - NUM_DETAILS * 0.5) * INV_NUM_DETAILS * 0.25); index++;
                    vertices[index] = ny * 0.5 + 0.5 + ((NUM_DETAILS * 0.5 - j) * INV_NUM_DETAILS * 0.25); index++;
                    vertices[index] = u; index++;
                    vertices[index] = v;
                }
            }
        }
        
        
        public var context3D:Context3D;
        public var container:Sprite;
        public var vertexBuffer:VertexBuffer3D;
        public var normalBuffer:VertexBuffer3D;
        public var indexBuffer:IndexBuffer3D;
        public var program:Program3D;
        public var tex:Texture, tex2:Texture;
        public var asm:AGALMiniAssembler = new AGALMiniAssembler();
        
        public var projectionMatrix:PerspectiveMatrix3D = new PerspectiveMatrix3D();
        public var modelviewMatrix:Matrix3D = new Matrix3D();
        public var matrix3D:Matrix3D = new Matrix3D();
        private var _driverInfo:TextField = new TextField();
        
        private function molehill_setup() : void {
            // stage setup
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
            // stage3D setup
            addChild(container = new Sprite());
            container.x = 96;
            container.y = 16;
            _driverInfo.textColor = 0xffffff;
            _driverInfo.width = 450;
            _driverInfo.x = 0;
            _driverInfo.y = 435;
            container.addChild(_driverInfo);
            var stage3D:Stage3D = stage.stage3Ds[0];
            //stage3D.viewPort = new Rectangle(96,16,450,450);
            //stage3D.x = 96;
            //stage3D.y = 16;
            stage3D.addEventListener(Event.CONTEXT3D_CREATE, function(e:Event):void{
                // context3d setup
                context3D = e.target.context3D;
                if (!context3D) throw new Error("no context3D");
                context3D.enableErrorChecking = true;              // check internal error
                context3D.configureBackBuffer(465, 465, 0, true);  // disable AA/ enable depth/stencil
                context3D.setRenderToBackBuffer();
                context3D.setBlendFactors(Context3DBlendFactor.SOURCE_ALPHA, Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA);
                context3D.setCulling(Context3DTriangleFace.BACK); // culling back face
                _driverInfo.text = context3D.driverInfo;

                // set buffers
                var uindices:Vector.<uint> = new Vector.<uint>(indices.length, true);
                for (var i:int=0; i<uindices.length; i++) uindices[i] = indices[i];
                vertexBuffer = context3D.createVertexBuffer(VCOUNT, INDEX_PADDING);
                indexBuffer = context3D.createIndexBuffer(uindices.length);
                indexBuffer.uploadFromVector(uindices, 0, uindices.length);
                program = context3D.createProgram();
                program.upload(asm.assemble("vertex", vs), asm.assemble("fragment", fs));
                
                tex = context3D.createTexture(512, 512, "bgra", false);
                tex.uploadFromBitmapData(bmd);
                tex2 = context3D.createTexture(512, 512, "bgra", false);
                tex2.uploadFromBitmapData(bmd2);
                
                projectionMatrix.perspectiveFieldOfViewLH(60/180*3.141592653589793, 1, 1, 200);
            });
            stage3D.requestContext3D();
        }
        
        private function molehill_draw() : void {
            context3D.clear(0.2, 0.2, 0.2, 1);
            matrix3D.copyFrom(projectionMatrix);
            matrix3D.prepend(modelviewMatrix);
            
            vertexBuffer.uploadFromVector(vertices, 0, VCOUNT);
            context3D.setDepthTest(true, "less");
            context3D.setProgram(program);
            context3D.setTextureAt(0, tex);
            context3D.setTextureAt(1, tex2);
            context3D.setVertexBufferAt(0, vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
            context3D.setVertexBufferAt(1, vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
            context3D.setVertexBufferAt(2, vertexBuffer, 5, Context3DVertexBufferFormat.FLOAT_2);
            context3D.setProgramConstantsFromMatrix("vertex", 0, matrix3D, true);
            context3D.setProgramConstantsFromVector("vertex", 9, Vector.<Number>([0,0.5,1,2]));
            context3D.setProgramConstantsFromVector("fragment", 0, Vector.<Number>([reflectionRatio,1-reflectionRatio,0,1]));
            context3D.drawTriangles(indexBuffer, 0, indices.length/3);
            context3D.present();
        }
    }
}

var vs:String = <agalCode><![CDATA[
mov vt0.xyz, va0.xyz
mov vt0.w, vc9.z
m44 op, vt0, vc0
mov v0, va1
mov v1, va2
]]></agalCode>;

var fs:String = <agalCode><![CDATA[
tex ft0, v0.xy, fs0 <2d,clamp,nearest>
tex ft1, v1.xy, fs1 <2d,clamp,nearest>
mul ft0, ft0, fc0.x
mul ft1, ft1, fc0.y
add oc, ft0, ft1
]]></agalCode>;