Skip to content

Instantly share code, notes, and snippets.

@khoparzi
Created March 30, 2021 19:41
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save khoparzi/8bbe8542cf7f8b4292c1a0174c0f8b4c to your computer and use it in GitHub Desktop.
Save khoparzi/8bbe8542cf7f8b4292c1a0174c0f8b4c to your computer and use it in GitHub Desktop.
Almost a month's worth of Marching.js sketches exploring various experiments with Signed Distance Fields and combinatorial geometries through the month of March 2021. [Marching.js](https://charlieroberts.github.io/marching/playground/) is a JavaScript shader compiler specifically focused on ray marching via signed distance functions.
// 1 Mar 2021
// Alright time for a new 30 day series! I present to you a new round of Marching.js
m = march(
u = Union2(
hl1 = Halve(Onion(Sphere(3), 0.012), Halve.UP),
hl2 = Halve(Onion(Sphere(2), 0.012), Halve.UP),
hl3 = Halve(Onion(Sphere(1), 0.012), Halve.UP),
hl4 = Halve(Onion(Sphere(0.5), 0.012), Halve.UP),
).material('black').rotate(90, 1, 0, 0)
)
.fog( .15, Vec3(.5) )
.light( Light( Vec3(1,.5,0), Vec3(1), .125 ) )
.render(10, true)
.camera( 0, 0, 10 )
onframe = t => {
hl1.rotate(t * 250, 0, sin(t), 0.5)
hl2.rotate(t * 350, 0, sin(t), 0.5)
hl3.rotate(t * 450, 0, sin(t), 0.5)
hl4.rotate(t * 550, 0, sin(t), 0.5)
}
// 2 Mar 2021
// Hex Glitches
quality = 'low'
use('hydra').then( ()=> {
hydra = Hydra()
hydra.shape(10,.2).rotate(0, 2).out()
march(
rpt = Repeat(
sphere = HexPrism(.25, .45).texture( hydra.texture() ),
2
).rotate(30, 1, 1, 1)
)
.post( Edge(), Invert(1), f = Focus(.125) )
.render(10, true)
sphere.tex.scale = 8
onframe = t => {
rpt.rotate(20, 0, 1, 0)
camera.pos.z = t/3
}
})
// 3 - Weird Dice Mar 2021
march(
Intersection(
Sphere(1),
Pipe(Repeat(Box(.125), .25).texture('stripes'), b = Box(.52))
)
).background(Vec3(.5)).render('high', true)
onframe = t => {
b.rotate(t * 15, 1, 1, 0)
}
// 4 Mar 2021
smallBox = 1.25
speedMul = 3.5
march(
su = RoundDifference(
StairsUnion(Box(), b2 = Sphere(smallBox))
, b3 = Box(smallBox), 0.5
)
).fog(.125, Vec3(0.8)).render(20, true)
onframe = t => {
b3.move(cos(t * speedMul + .5) * 1.5, 0, 0)
b2.move(sin(t * speedMul) * 1.5, 0, 0)
su.rotate(t * 45, 1, 1, 1)
}
// 5 Mar 2021
smallBox = 0.25
speedMul = 5
march(
su = RoundDifference(
StairsUnion(Mandelbox(3.5), b2 = Sphere(smallBox))
, b3 = Box(smallBox), 0.5
)
).fog(.125, Vec3(0.8)).render(20, true)
onframe = t => {
b3.move(cos(t * speedMul + .5) * 1.5, 0, 0)
b2.move(sin(t * speedMul) * 1.5, 0, 0)
su.rotate(t * 45, 0, 1, 1)
}
// 6 Mar 2021
// mat = Material( 'phong', Vec3(.05, 0, 0), Vec3(1,0,0), Vec3(3), 64, Vec3( 0,6,4) )
mat = Material( 'phong', .125, 1, 1)
march(
tw = Twist(hp = HexPrism().material(mat), Vec2(0.75, 0.2))
).background(Vec3(0.25)).fog(.012, Vec3(0.4))
.post( rays = Godrays() )
.render(10, true)
// try below one line at a time
rays.color = [1,0,1]
rays.decay = 1.01
// change z position of rays to put
// them in the box
rays.threshold = .125
onframe = t => {
hp.rotate(t * 30, 1, 0, 0)
tw.rotate(t * 30, -1, 0, 0)
}
// 7 Mar 2021
march(
tr1 = PolarRepeat(Torus().rotate(90, 1, 0, 0), 5).material('green'),
Twist(tr2 = PolarRepeat(Torus(Vec2(1.5, .125)).rotate(90, 1, 0, 0), 8)).material('red'),
Plane().rotate(90, 0.4, 0, 1).translate(0, 0, -6).material('glue')
)
.light(Light(Vec3(2, 2, 3), Vec3(0, .51, .45)))
.render(5, true)
onframe = t => {
tr1.rotate(t * 30, 0, 1, 0)
tr2.rotate(t * 30, 0, sin(t / 4) * 0.8, 0.2)
}
// 8 Mar 2021
mat = Material( 'phong', .125, 1, .1)
march(
Twist(pr = PolarRepeat(tr = Torus(Vec2(1., .05)).rotate(90, 1, 0, 0).translate(0.75, 0, 0), 12), Vec3(0.53)).material(mat)
).background(Vec3(.5))
.light(Light(Vec3(2, 2, 3), Vec3(.5)))
.post( rays = Godrays() ).render(2, true)
rays.decay = .9
rays.threshold = .5
rays.color = [.1,.1,.1]
onframe = t => {
pr.rotate(45 * t, 1, 0, 1)
tr.rotate(30 * t, 1, 1, 0)
}
// 9 Mar 2021
use('hydra').then(() => {
h = Hydra()
osc(1, 0.125, 1.5).brightness(-0.5).out()
//voronoi().out()
mat = Material( 'phong', .125, 1, .1)
march(
pr = PolarRepeat(tr = Torus88(Vec2(1., .05)).rotate(90, 1, 0, 0)
.translate(0.75, 0, 0), 12).material(mat)
.texture(h.texture()),
Plane().material(mat)
)//.background(Vec3(.5))
.light(Light(Vec3(1, 2, 3), Vec3(.75)))
//.post( rays = Godrays() )
.render(5, true)
onframe = t => {
pr.rotate(10 * t, 0, 1, 0)
tr.rotate(15 * t, -1, 0, 0)
}
})
// 10 Mar 2021
col1 = Vec3(0.25, .25, 0.1)
col2 = Vec3(10.75, 0, 0)
mat1 = Material('phong', col1, col1, 1)
mat2 = Material('phong', col2, col2, 1)
march(
diff = Difference(Box(.6), pr = Repeat(Torus().rotate(90, 1, 0, 0), 1)).material(mat2)
.scale(1.5)
).background(Vec3(.1))
.light(Light(Vec3(1, 2, 4), Vec3(1)))
.post(Focus(), Godrays())
.render(10, true)
onframe = t => {
pr.rotate(45 * t, 1, -1, 0)
diff.rotate(30 * t, 0, 1, 1)
}
/////////////////
// 11 - Spherical Differences
march(
Difference(
mb = Mandelbulb(),
Sphere(.975)
).rotate(90, 1, 0, 0).material('red')
).render('fractal.high', true)
onframe = t => {
mb.rotate(30 * t, 0, 1, 0)
mb.fold = 3 + sin(t * 0.125) * 4
}
////
// 12 - Checkered Union
dif = StairsUnion(tr = Torus(Vec2(1.5, .2)), oh = Octahedron()).rotate(30, 1, 1, 0).texture('checkers')
march(
dif
).background(.8).render(10, true)
onframe = t => {
oh.rotate(t * 30, 1, 1, 0)
tr.rotate(t * 30, -1, 0, 0)
}
// 13 - Mechanised Cephalopods
col1 = Vec3(7)
col2 = Vec3(.5, 0.125, 0.9)
mat1 = Material('phong', col1, col1, .91)
mat2 = Material('phong', col2, col2, .1)
march(
su = StairsUnion(
tr1 = PolarRepeat(Torus(Vec2(.972, 0.12)).rotate(90, 1, 0, 0), 8),
Capsule().translate(-.5, -.5, 0)
, .4
).material(mat1)
)
.light(Light(Vec3(4, -1, 4), Vec3(0.35, .125, .25), .2, .1))
.background(.25)
.post(Focus(.1))
.render(5, true)
onframe = t => {
tr1.rotate(t * 30, 0, 1, 0)
su.rotate(t * 30, 0, sin(t / 4) * 0.8, 0.2)
}
// 14 - Shadow of Roses
march(
pr = PolarRepeat(
ju = Julia(),
6
).material('red').translate(0, .5),
Plane().rotate(30, 1, 0, 0).material('white')
)
.post(f = Focus(.45))
.light(Light(Vec3(2, 2, 3), Vec3(0.5, .51, .45)))
.render('fractal.high', true)
onframe = t => {
pr.rotate(30 * t, 0, 1, 0)
ju.fold = 1 + sin(t * 0.06125 * .5) * 2
}
// 15 - Mental Monday
march(
mb = Mandelbulb()
.material(Material('phong', Vec3(.0), Vec3(.5), Vec3(1), 32, Vec3(0))),
Plane(Vec3(0, 0, 1), 0.5).material('white glow')
)
.fog(.1, Vec3(0.5))
.background(Vec3(.5))
.light(
l1 = Light(Vec3(-1, 1, 4), Vec3(1), 0.25),
l2 = Light(Vec3(-2, 1, 4), Vec3(1), 0.25)
)
.render('fractal.high')
.camera(0, 0, 4)
onframe = t => {
mb.fold = 3 + (sin(t * 0.0625) * 5)
}
// 16 - Two Worlds
use('hydra').then(() => {
h = Hydra()
solid()
.add(
shape(2)
.scale(0.1)
.rotate(0.000001)
)
.modulate(
noise(() => 5 + 0.01).scale(10, 0.1)
)
.scale(2, 1, 5).out(o1)
src(o1)
.scrollX([0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2].ease('easeInOutCubic').fast(0.25))
.kaleid(200)
.add(
src(o1)
.scrollY(0.75)
.kaleid(4)
.rotate([Math.PI * 0.25, Math.PI * 0.5, Math.PI * 0.75, Math.PI * 1.01, Math.PI * 1.25, Math.PI * 1.5].ease('easeInCubic').fast(0.25)), () => (time * 0.0125 % 1) * 2 - 1)
.scale(.125, 1, () => window.innerWidth / window.innerHeight).contrast().out()
march(
sp = Sphere(1.5)
.material('black')
.texture(h.texture())
).background(Vec3(.5))
.render(5, true)
onframe = t => {
sp.rotate(t * 30, 0, sin(t / 4) * 0.8, 0.2)
}
})
// 17 Mar - Army of Jupiters
march(
rpt = Repeat(
un = Union(Sphere(.2), tr = Torus()),
2, 2
).material('black')
).post(Godrays())
//.fog( .1, Vec3(0,0,.25) )
.background( Vec3(.5) )
.render(10, true)
onframe = t => {
un.rotate(t * 90, 0, sin(t), 0.5)
rpt.rotate(3 * t, 1, -1, 0)
}
// 18 - Sphere Flowers
march(
StairsDifference(
Sphere(1.2),
rpt = PolarRepeat(
Octahedron(),
6, .6
)
)
)
.background(Vec3(.7))
.render(10, true)
onframe = t => {
rpt.rotate(t * 30, 0, 1, -1)
rpt.count = 3 + sin(t * 0.125) * 6
}
// 19 - Spy Theme
use('hydra').then(() => {
h = Hydra()
solid(1)
.mult(src(s0).mult(shape(30, 0.8).scrollY(0.1)).scrollY(-0))
.scale(-1, 1, () => window.innerWidth / window.innerHeight).contrast()
.repeat()
.out()
march(
sp = Box(1.4)
.texture(h.texture())
).background(Vec3(.5))
.render(5, true)
//
onframe = t => {
sp.rotate(t * 30, 0, -1, 0)
}
})
s0.initCam(0)
// 20 - Bulbus Fragments
mat1 = Vec3(0.8, 0.7, .35)
march(
si = StairsIntersection(
ju = Julia(.875).scale(2).rotate(90, 0, 0.5, 1), rpt = Repeat(Sphere(.1), .15), .125)
.material(Material('phong', mat1, mat1, Vec3(0.2, 0.1, 0), 2, Vec3(0)))
).light(
l1 = Light(Vec3(3, 0, 3), Vec3(0.25), 0.125), l2 = Light(Vec3(-2, 0, 2), Vec3(0.125), 0.4)
).background(Vec3(.2)).render('fractal.high')
onframe = t => {
rpt.rotate(t * 20, 0, -1, 0)
rpt.distance = .21 + sin(t * .125) * .12
ju.fold = 1
}
// 21 - Lockdown
march(
si = StairsDifference(
Box().material('white'),
repeat = Repeat(
sphere = Sphere(.0125),
Vec3(.5)
),
.125
)
).post(Focus())
.light(
l1 = Light(Vec3(3, 0, 3), Vec3(0.25), 0.125), l2 = Light(Vec3(-2, 2, 2), Vec3(0.125), 0.24)
).background(Vec3(.2))
.render(10, true)
// start our FFT
FFT.start()
// animate
onframe = time => {
si.rotate(time * 15, 0, 1, 1)
repeat.distance.x = FFT.low // - .32
repeat.distance.y = FFT.mid - .32
repeat.distance.z = FFT.high
sphere = FFT.mid * FFT.high
}
// 22 - Drifting out of Focus
march(
Twist(
mb = PolarRepeat(
Box().scale(.24).rotate(30, 1, 0, 1).material('white'),
6
)
, Vec2(1.2)
)
).background(Vec3(.2))
.post( f = Focus() )
.fog( .15, Vec3(0) )
.render('high')
onframe = t => {
camera.pos.z = 2 + cos(t * 0.124) * .5
f.depth = sin(t * 0.126) * .15
mb.rotate(t * 15, -1, -1, -1)
}
// change width of focus
f.radius = .05
f.depth = .15
// 23 - Happy Birthday Shaan!
use('hydra').then(() => {
h = Hydra()
osc(20,0.1,1).rotate(10,0.6).pixelate(20,20).modulateKaleid( voronoi(5,0.3,0.3),4).out(o0);
march(
Repeat(sp = HexPrism(1.5), .2)
.material('blackhole')
.texture(h.texture())
).background(Vec3(.5))
.render(5, true)
onframe = t => {
sp.rotate(t * 30, 0, sin(t / 4) * 0.8, 0.2)
}
})
// 24 - Twisted Toroidals
mat1 = Material( 'phong', .05, 1, .5 )
//
objs = []
for(let i = 0; i < 8; i++) {
torus = Torus( v2(i * .25, i * .015) )
.rotate( 15 * i, 0, sin(i), cos(i) )
.material( mat1 )
objs[i] = torus
}
//
mat = Material( 'phong', v3(0), v3(.1), v3(.25) )
tori = objs.reduce( ( current, next ) => this.Union( current, next ) )
//
march(
tw = Twist(tori, Vec2(.1, .4))
, Plane( v3(0,0,1), 1).material( mat ).translate(0, 0, -1)
)
.light(
l1 = Light(Vec3(-1, 1, -4), Vec3(0, 0, .31), 0.25),
l2 = Light(Vec3(-2, 2, 5), Vec3(.51), 0.125)
).post(f = Focus(.15, .15))
.render('high')
.camera( 0,0, 5 )
//
onframe = t => {
tori.rotate(t * 30, 0, 1, -1)
f.depth = sin(t * 0.126) * .15
}
// 25 - Stolen Ideas
objs = []
for(let i = 0; i < 6; i++) {
cy = Difference(
Cylinder( Vec2(i * .24,.9) ),
Cylinder( Vec2(i * .23,1) )
).rotate(5 * i, 1, 0, 0)
objs[i] = cy
}
//
mat = Material( 'phong', Vec3(0), Vec3(.1), Vec3(.25) )
cys = objs.reduce( ( current, next ) => this.Union( current, next ) )
//
march(
tw = Union(cys.material('white'), Sphere(.12).move(0, .78, .04).material('black')).rotate(90, 1, .8, 0)
, Plane( Vec3(0,0,1), 1).material( mat ).translate(0, 0, -1)
)
.light(
l1 = Light(Vec3(2, 1, 4), Vec3(.91), 0.25),
l2 = Light(Vec3(-2, 2, 5), Vec3(.81), 0.25)
)
.post(f = Focus(.15, .15))
.render('high')
//
onframe = t => {
cys.rotate(t * 30, 0, 1, 0)
}
// 26 - Falling Time
objs = [], sp = []
for(let i = 0; i < 12; i++) {
cy = Difference(
sp[i] = Sphere(.4), Torus(Vec2(0.4, 0.42))
).rotate(15 * i, 1, 0, 0).move(cos(i) * 2, sin(i) * 2, 0)
objs[i] = cy
}
//
cys = objs.reduce( ( current, next ) => this.Union( current, next ) )
//
march(
cys.material('white')
).background(.35)
.light(Light(Vec3(1, 2, 4), Vec3(.81)))
.post(Antialias())
.render('high').camera(0, 0, 6)
//
onframe = t => {
cys.rotate(t * 30, 0, 1, 0)
for(let i = 0; i < 12; i++) {
objs[i].rotate(15 * (i+2) * t, 1, 0.2, 0.5)
}
}
// 27 - Evil Eye
use('hydra').then(() => {
h = Hydra()
osc(200,0.1,1).kaleid(2.3).rotate(1.57).out();
march(
Difference(
pl = Plane().rotate(45, 1, 0, 0),
Repeat(tr = Torus(Vec2(.5, .2)), .8)
).material('normal'),
sp = Box(.7).rotate(90, 1, .5, 0)//.material(mat)
.material('blackhole')
.texture(h.texture())
).render('high')
//
onframe = t => {
gr = pow(sin(3.14 * t / 2) + 1, .5)
tr.rotate(30 * t, 1, 0, 0)
sp.move(0, gr)
sp.rotate(gr * 30, -1, 0, 0)
}
})
// 28 - Shattered
use('hydra').then(() => {
h = Hydra()
voronoi().out();
march(
bb = Bump(Box(), h.texture(), .4)
.material('white')
).background(Vec3(.61, 0, .81)).render('high')
onframe = t => {
tt = 1 - pow(abs(t), 1.)
bb.rotate(tt * 30, 1, sin(t), 0)
}
})
// 29 - Big Guns
colorsA = []
colorsA[0] = Vec3(0.86,0.22,0.27);
colorsA[1] = Vec3(0.92,0.49,0.07);
colorsA[2] = Vec3(0.91,0.89,0.26);
colorsA[3] = Vec3(0.0,0.71,0.31);
colorsA[4]= Vec3(0.05,0.35,0.65);
colorsA[5] = Vec3(0.38,0.09,0.64);
colorsA[6]= Vec3(.9,0.758,0.798);
colorsA[7] = Vec3(0.361,0.969,0.282);
colorsA[9] = Vec3(0.396,0.878,0.878);
colorsA[10] = Vec3(1.0, 0.189, 0.745);
colorsA[11] = Vec3(0.96, 0.474, 0.227);
objs = []
size = .5
thickness = .86
const t = size - (size * .5)
for(let i = 1; i < 5; i++) {
const s = size * i
bm1 = Mirror(Box(size * thickness).translate( t, 0, 0))
bm2 = Mirror(Box(size * thickness).translate( t, 0, 0)).rotate(90, 0, 1, 0)
bm3 = Mirror(Box(size * thickness).translate( t, 0, 0)).rotate(90, 0, 0, 1)
un2 = Union2(bm1, bm2, bm3)
mat = Material('phong', colorsA[i+1], colorsA[i+1], .9)
und = Difference(Box(size), un2).scale(.5 * i).material(mat)
objs.push(und)
}
uns = objs.reduce( ( current, next ) => this.Union( current, next ) )
march(
uns
)
.light(
l1 = Light(Vec3(2, 1, 4), Vec3(.91), 0.5),
l2 = Light(Vec3(-1, 2, 5), Vec3(.81), 0.25)
)
.background( Vec3(.125) )
.post(Edge(), Focus(.2, .0125))
.render('high')
bins = [100,200,400,800,1600,3200,6400,12800,22050]
FFT.start(bins)
onframe = t => {
for(let i = 0; i < objs.length; i++) {
objs[i].rotate(90 * t * (i+2) * .25, 0, sin(t) * (i + 1) * .3, (i + 1) * .3)
uns.scale(FFT[2] + .2)
}
}
// 30 - Teleport!
use('hydra').then(() => {
h = Hydra()
osc(10, 0, 1).rotate(1.57).out();
march(
//rpt = Repeat(
StairsUnion(
bx = Box(.5),
Repeat(tor = Torus(.11, 2), .25),
.5,
5
).material('blackhole').texture(h.texture()),
Plane().texture('dots', {
strength: -.5,
scale: 2,
color: [.1, .2, .1]
})
)
.background(Vec3(.125))
.render('high', true)
.camera(0, 0, 3)
//
onframe = t => {
bx.rotate(90 * t, 0, 1, 0)
tor.move(0, ((t * .5) % 1) * 2 - 1)
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment