Code
const regl = createREGL({extensions: ['ANGLE_instanced_arrays']});
const drawLines = reglLines(regl, {
// Trigger the command to automatically insert caps at any break, signaled
// by a position with (w = 0)
insertCaps: true,
vert: `
precision highp float;
#pragma lines: attribute vec2 xy;
#pragma lines: attribute float break;
#pragma lines: position = getPosition(xy, break);
#pragma lines: width = getWidth();
#pragma lines: varying vec2 pos = getXY(xy);
// Return w = 0 wherever there's a break
vec4 getPosition(vec2 xy, float isBreak) {
if (isBreak > 0.0) return vec4(0);
return vec4(xy, 0, 1);
}
float getWidth() { return 40.0; }
vec2 getXY(vec2 xy) { return xy; }`,
frag: `
precision lowp float;
varying vec2 pos;
void main () {
// Convert the x-coordinate into a color
gl_FragColor = vec4(0.6 + 0.4 * cos(8.0 * (pos.x - vec3(0, 1, 2) * 3.141 / 3.0)), 0.7);
}`,
// Turn off depth and turn on blending to make it very clear if we accidentally
// draw end caps twice
depth: { enable: false },
blend: {
enable: true,
func: { srcRGB: "src alpha", srcAlpha: 1, dstRGB: "one minus src alpha", dstAlpha: 1 }
},
});
const n = 31;
const lineCount = 10;
// Detecting NaN in GLSL can be questionable, so we can just be verbose and use a separate
// attribute to indicate breaks.
const positions = [[0,0]];
const isBreak = [1];
function xy (line, i) {
let t = (i / (n - 1) * 2 - 1) * 0.9;
const y = ((line + 0.5) / lineCount * 2 - 1) * 0.9;
return [t, y + 1 / lineCount * Math.sin((t - line * 0.1) * 8.0)];
}
for (let line = 0; line < lineCount; line++) {
for (let i = 0; i < n; i++) {
positions.push(xy(line, i));
isBreak.push(0);
}
// Add a dummy vertex and signal a break in the line
positions.push([0,0]);
isBreak.push(1);
}
// After this, render as normal!
const lineData = {
join: 'round',
cap: 'round',
vertexCount: positions.length,
vertexAttributes: {
xy: regl.buffer(positions),
break: regl.buffer(new Uint8Array(isBreak))
},
};
function draw () {
regl.poll();
regl.clear({color: [0.2, 0.2, 0.2, 1]});
drawLines(lineData);
}
draw();
window.addEventListener('resize', draw);