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

negative spheres

Get Adobe Flash player
by yonatan 20 Sep 2014
  • Forked from yonatan's raymarching (cpu)
  • Diff: 62
  • Related works: 2
  • Talk

    FLASHMAFIA at 23 Sep 2014 01:46
    wish i got time to put my hands on this! yum...
    yonatan at 23 Sep 2014 01:59
    It works better as fragment shader. When you get the time check these out (I used them as a reference): https://www.shadertoy.com/view/XsB3Rm https://www.shadertoy.com/view/Mds3Rn and iq's distance fields article: http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
    Embed
/**
 * Copyright yonatan ( http://wonderfl.net/user/yonatan )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/pEl4
 */

// forked from yonatan's raymarching (cpu)
package {
    import flash.display.*;
    import flash.geom.*;
    import flash.utils.*;
    import flash.events.*;
    import net.hires.debug.Stats;

    [SWF(frameRate="60")]
    public class main extends Sprite {
        private var SIZE:int = 128, M:int = 3;
        private var R:Number = 0.75;
        private var bmd:BitmapData = new BitmapData(SIZE, SIZE, false, 0);
        private var bmp:Bitmap;

        function main(){
            graphics.beginFill(0);
            graphics.drawRect(0,0,465,465);
            addChild(bmp = new Bitmap(bmd));
            bmp.scaleX = bmp.scaleY = M;
            bmp.x = bmp.y = (465 - SIZE*M) >> 1;
            var s:Stats = new Stats;
            addChild(s);
            s.visible = false;
            addEventListener(Event.ENTER_FRAME, oef);
            stage.addEventListener(MouseEvent.CLICK, function(e:Event):void { s.visible = !s.visible; });
        }

        private var dir:Vector3D = new Vector3D;
        private var normal:Vector3D = new Vector3D;
        private var t:Number;
        private var sin:Number, innerRadius:Number;
        private var cos:Number;

        private function oef(e:Event):void {
            var k:Number, k2:Number, c:uint, x:Number, y:Number, z:Number;
            var mink:Number = 0.05;
            t = getTimer()*0.00025;
            innerRadius = 1.0 + 0.33 * Math.sin(t*5);
            sin = Math.sin(t);
            cos = Math.cos(t);
            for(var cy:int = 0; cy < SIZE; cy++) {
                for(var cx:int = 0; cx < SIZE; cx++) {
                    dir.setTo(cx-SIZE*0.5, cy-SIZE*0.5, SIZE * .33);
                    dir.normalize();
                    var dx:Number = cos * dir.x - sin * dir.z;
                    var dz:Number = sin * dir.x + cos * dir.z;
                    var dy:Number = dir.y;
                    var px:Number = 0, py:Number = sin * 8, pz:Number = t * 10;
                    for(var i:int=0; i<16; i++) {
                        /*
                        k = scene(px, py, pz);
                        /*/
                        // inlined:
                        x = (px > 0 ? px : -px) % 4 - 2;
                        y = (py > 0 ? py : -py) % 4 - 2;
                        z = (pz > 0 ? pz : -pz) % 4 - 2;

                        if(x<0)x=-x; if(y<0)y=-y; if(z<0)z=-z;
                        k = (x > z ?
                            x > y ? x : y :
                            y > z ? y : z) - 1.0;
                        var dist:Number = Math.sqrt(x*x+y*y+z*z);
                        var sph:Number = dist - innerRadius;
                        var negsph:Number = -(dist - 1.33);
                        if(negsph > k) k = negsph;
                        if(sph < k) k = sph;
                        //*/

                        px += dx * k;
                        py += dy * k;
                        pz += dz * k;
                        if(k<mink) break;
                    }
                    if(k<mink) {
                        k2 = k*2;
                        px -= k; py -= k; pz -= k;
                        normal.setTo(
                            scene(px+k2, py, pz),
                            scene(px, py+k2, pz),
                            scene(px, py, pz+k2));
                        normal.normalize();
                        //var c:uint = (1 + normal.x) * 127 << 16 | (1 + normal.y) * 127 << 8 | (1 + normal.z) * 127;
                        // var c:uint = ((1+normal.z)*127|0)*0x10101;
                        c = k > mink ? 0 : (normal.z > 0 ? normal.z : 0) * 255 << 16 | (0.5 + normal.z) * 127 + 64 << 8 | (1 + normal.z) * 127;
                    } else {
                        dz *= dz*dz;
                        c = (dz > 0 ? dz : 0) * 255 << 16 | (0.5 + dz) * 127 + 64 << 8 | (1 + dz) * 127;
                    }
                    bmd.setPixel(cx, cy, c);
                }
            }
        }

        private function scene(x:Number, y:Number, z:Number):Number {
            x = (x > 0 ? x : -x) % 4 - 2;
            y = (y > 0 ? y : -y) % 4 - 2;
            z = (z > 0 ? z : -z) % 4 - 2;

            if(x<0)x=-x; if(y<0)y=-y; if(z<0)z=-z;
            var box:Number = (x > z ?
                x > y ? x : y :
                y > z ? y : z) - 1.0;
            var dist:Number = Math.sqrt(x*x+y*y+z*z);
            var sph:Number = dist - innerRadius;
            var negsph:Number = -(dist - 1.33);
            var ret:Number = box;
            if(negsph > ret) ret = negsph;
            if(sph < ret) ret = sph;
            return ret;
        }
    }
}