Xor's Raymarcher

This is my first time touching TurtleToy and even JavaScript, but it's been fun to play around with it. Let me know if anything needs improvement. JS seems to be quite forgiving.

Log in to post a comment.

/*
    "Xor's Raymarcher"

    This is my first time touching TurtleToy and even JavaScript, but it's been fun to play around with it.
    Let me know if anything needs improvement. JS seems to be quite forgiving.
*/

let col = -1; //min=-1, max=1, step=2
let res = 100;//min=50, max=200, step=50
let pos = 0;  //min=0, max=20, step=1

Canvas.setpenopacity(col);
const vec = new Turtle();

//Based on reinder's work:
const sub3=(a,b)=>[a[0]-b[0],a[1]-b[1],a[2]-b[2]];
const mul3=(a,b)=>[a[0]*b,a[1]*b,a[2]*b];
const dot3=(a,b)=>a[0]*b[0]+a[1]*b[1]+a[2]*b[2];
const len3=(a)=>Math.sqrt(dot3(a,a));
const nor3=(a)=>mul3(a,1/len3(a));



//SDF function.
function dist(p)
{
    //Rotate the position coordinates.
    p = [p[0]*.8+p[2]*.6,
         p[1],
         p[2]*.8-p[0]*.6];
    //Repeat cube coordinates.
    c = [p[0]-Math.floor(p[0]/8)*8-4,
         p[1]-Math.floor(p[1]/8)*8-4,
         p[2]-Math.floor(p[2]/8)*8-4];
    //Calculate cube length vector.
    c = [Math.max(Math.abs(c[0])-1,0),
         Math.max(Math.abs(c[1])-1,0),
         Math.max(Math.abs(c[2])-1,0)];
         
    return Math.min(len3(c)-1.,-p[1]+6);
}
//Raymarching function.
function raymarch(p,d)
{
    //Only 20 steps!
    for(i = 0;i<20;i++)
    {
        s = dist(p);
        if (s<.01) return p;
        p = [p[0]+d[0]*s,p[1]+d[1]*s,p[2]+d[2]*s];
    }
    return p;
}
function walk(i)
{
    //Calculate pixel coordinates.
    f = Math.floor(i/res);
    d = Math.ceil(i/2)*4-i*2-1;
    x = (i-f*res)/(res-1)*200-100;
    y = f/(res-1)*200-100;
    
    //Calculate camera.
    p = [0,-1,pos];
    v = nor3([x,y,100]);
    r = raymarch(p,v);
    
    //Calculate vector direction.
    nx = dist([r[0]+v[2],r[1]+v[1],r[2]-v[0]])-
         dist([r[0]-v[2],r[1]+v[1],r[2]+v[0]]);
    ny = dist([r[0]+v[0],r[1]+v[2],r[2]-v[1]])-
         dist([r[0]+v[0],r[1]-v[2],r[2]+v[1]]);
    n = 20/len3(sub3(r,p));
    
    //Output vector.
    vec.jmp(x,y);
    vec.goto(x+ny*n,y-nx*n);
    return i < res*res;
}