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;
}
}
}