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,
})