drawLinesFromTexture = regl({
vert: `
precision highp float;
uniform mat4 uProjectionView;
uniform vec4 uMask;
uniform float uLineWidth, uAspect;
attribute vec2 aLookup, aNextLookup;
attribute float aX, aNextX;
attribute vec2 aLinePosition;
uniform sampler2D uSrc;
vec2 lineNormal (vec4 p, vec4 n, float aspect) {
return normalize((p.yx / p.w - n.yx / n.w) * vec2(1, aspect)) * vec2(-1.0 / aspect, 1);
}
void main () {
float y = dot(texture2D(uSrc, aLookup), uMask);
float yNext = dot(texture2D(uSrc, aNextLookup), uMask);
vec2 xy = vec2(aX, y);
vec2 xyNext = vec2(aNextX, yNext);
vec4 p = uProjectionView * vec4(xy, 0, 1);
vec4 n = uProjectionView * vec4(xyNext, 0, 1);
// Select one or the other positions
gl_Position = mix(p, n, aLinePosition.y);
// Apply the screen-space offset
gl_Position.xy += lineNormal(p, n, uAspect) * aLinePosition.x * uLineWidth * gl_Position.w;
}`,
frag: `
precision mediump float;
uniform vec4 uColor;
void main () {
gl_FragColor = uColor;
}`,
attributes: {
aLookup: {buffer: regl.prop('lookupTable'), divisor: 1, stride: 8},
aNextLookup: {buffer: regl.prop('lookupTable'), divisor: 1, offset: 8, stride: 8},
aX: {buffer: regl.prop('x'), divisor: 1},
aNextX: {buffer: regl.prop('x'), offset: 4, divisor: 1},
aLinePosition: [-1, 0, 1, 0, -1, 1, 1, 1],
},
uniforms: {
uSrc: regl.prop('positionsData'),
uLineWidth: (ctx, props) => props.lineWidth / ctx.framebufferHeight * ctx.pixelRatio,
uMask: regl.prop('mask'),
uColor: regl.prop('color'),
},
primitive: 'triangle strip',
instances: (ctx, props) => props.count - 1,
count: 4,
});