draw = regl({
vert: `
precision highp float;
attribute float theta;
attribute vec2 circlePoint;
varying vec3 vColor;
uniform vec2 aspectRatio;
uniform float time;
const float PI = 3.1415926535;
void main () {
// Use lots of sines and cosines to place the circles
vec2 circleCenter = vec2(cos(theta), sin(theta))
* (0.6 + 0.2 * cos(theta * 6.0 + cos(theta * 8.0 + time)));
// Modulate the circle sizes around the circle and in time
float circleSize = 0.2 + 0.12 * cos(theta * 9.0 - time * 2.0);
vec2 xy = circleCenter + circlePoint * circleSize;
// Define some pretty colors
float th = 8.0 * theta + time * 2.0;
vColor = 0.6 + 0.4 * vec3(
cos(th),
cos(th - PI / 3.0),
cos(th - PI * 2.0 / 3.0)
);
gl_Position = vec4(xy / aspectRatio, 0, 1);
}`,
frag: `
precision highp float;
varying vec3 vColor;
uniform float alpha;
void main () {
gl_FragColor = vec4(vColor, alpha);
}`,
attributes: {
circlePoint: circleInstanceGeometry,
theta: { buffer: instanceTheta, divisor: 1 }
},
uniforms: {
aspectRatio: (ctx) =>
ctx.framebufferWidth > ctx.framebufferHeight
? [ctx.framebufferWidth / ctx.framebufferHeight, 1]
: [1, ctx.framebufferHeight / ctx.framebufferWidth],
time: regl.context("time"),
alpha: Math.max(0, Math.min(1, (0.15 * 2000) / numCircleInstances))
},
blend: {
enable: true,
func: { srcRGB: "src alpha", srcAlpha: 1, dstRGB: 1, dstAlpha: 1 },
equation: { rgb: "add", alpha: "add" }
},
primitive: "line strip",
depth: { enable: false },
count: numCircleDivisions + 1,
instances: numCircleInstances
})