bnb({
w, h,
webgl: true,
numFrames: 120,
fps: 20,
record: true,
chromaticAberration: 0.5,
samplesPerFrame: 8,
preload: (s, g) => {
const sphereRadius = 190
const scale = 180
const len = 30
class Pt {
constructor() {
const x = prng.rand(-100, 100)
const y = prng.rand(-100, 100)
const z = prng.rand(-100, 100)
this.pos = PVector(x, y, z).mag(sphereRadius)
this.noise = simplex.noise3D(...this.pos.clone().div(scale).toArray())
}
display(s, t) {
this.pos.rotateY(TAU / (g.numFrames * g.samplesPerFrame))
const sinT = s.sin((t * 4 + this.noise) * TAU)
const p = PVector.add(this.pos, this.pos.clone().mag(sinT * len))
const d = s.norm(p.dist(g.cameraPos), g.distMin, g.distMax)
s.strokeWeight(.1 + d * 2.1)
const c = scales[colorScale](sinT * .45 + .55)
s.stroke(...hexToRgb(c), d * 250)
s.point(...p.toArray())
}
}
g.pts = array(N).map(i => new Pt())
g.cameraPos = PVector(0, 0, 500)
g.distMin = g.cameraPos.dist(PVector(0, 0, sphereRadius + len))
g.distMax = g.cameraPos.dist(PVector(0, 0, -(sphereRadius + len)))
},
draw: (s, t, g) => {
s.background(scales[colorScale](0))
s.camera(...g.cameraPos.toArray(), 0, 0, 0, 0, 1, 0)
g.pts.forEach(pt => pt.display(s, t))
}
})