Code
const regl = createREGL({
extensions: ['ANGLE_instanced_arrays']
});
const mat4 = glMatrix.mat4;
// This example illustrates the postproject property. You may specify a function to be applied
// *after* screne-space projection. Together with providing viewportSize, this allows you to
// draw lines in whatever viewport you desire, then to project them to the screen. This useful,
// for example, when drawing lines on a flat surface. It changes nothing if the lines are not
// on a flat surface, though the joins may not look particularly good in the out-of-plane
// dimension.
const drawLines = reglLines(regl, {
vert: `
precision highp float;
// Use a vec2 attribute to construt the vec4 vertex position
#pragma lines: attribute vec2 position;
#pragma lines: position = getPosition(position);
vec4 getPosition(vec2 position) {
return vec4(position, 0, 1);
}
// Return the line width from a uniorm
#pragma lines: width = getWidth();
uniform float width;
float getWidth() {
return width;
}
// Specify a projection function
#pragma lines: postproject = postprojectPosition;
uniform mat4 projectionView;
vec4 postprojectPosition(vec4 position) {
return projectionView * position;
}
`,
frag: `
precision lowp float;
void main () {
gl_FragColor = vec4(1);
}`,
// Multiply the width by the pixel ratio for consistent width
uniforms: {
width: (ctx, props) => ctx.pixelRatio * props.width,
projectionView: (ctx, props) => {
//const aspect = ctx.viewportWidth / ctx.viewportHeight;
const aspect = 2;
const projection = mat4.perspective(mat4.create(), Math.PI / 4, aspect, 0.01, 10.0);
const theta = ctx.time * 0.5;
const r = 1.8;
const eye = [
r * Math.cos(theta),
r * Math.sin(theta),
0.5
];
const center = [0, 0, 0];
const up = [0, 0, 1];
const view = mat4.lookAt(mat4.create(), eye, center, up);
return mat4.multiply(projection, projection, view);
}
},
});
// Construct an array of xy pairs
const n = 501;
const position = [...Array(n + 3).keys()]
.map(i => i / n * Math.PI * 2)
.map(t => {
const r = 0.6 + 0.4 * Math.cos(t * 7.0);
return [r * Math.cos(t), r * Math.sin(t)]
});
// Set up the data to be drawn. Note that we preallocate buffers and don't create
// them on every draw call.
const lineData = {
width: 0.03,
join: 'round',
cap: 'round',
vertexCount: position.length,
vertexAttributes: { position: regl.buffer(position) },
// Screen-project in the 1 x 1 unit square. Since this size is divided out before
// post-projection, this only affects interpretation of "widthV.
viewportSize: [1, 1]
};
regl.frame(() => {
regl.clear({color: [0.2, 0.2, 0.2, 1]});
drawLines(lineData);
});