Published
Edited
Jun 24, 2020
Insert cell
Insert cell
viewof regl = {
let div = DOM.canvas(width / 2, width / 2);
let regl = wrapREGL(div);
div.value = regl;
return div;
}
Insert cell
drawParticles = regl({
vert: `
precision mediump float;
attribute vec4 freq, phase;
attribute vec3 color;
uniform float time;
uniform mat4 view, projection;
varying vec3 fragColor;
void main() {
vec3 position = 8.0 * cos(freq.xyz * time + phase.xyz);
gl_PointSize = 5.0 * (1.0 + cos(freq.w * time + phase.w));
gl_Position = projection * view * vec4(position, 1);
fragColor = color;
}`,

frag: `
precision lowp float;
varying vec3 fragColor;
void main() {
if (length(gl_PointCoord.xy - 0.5) > 0.5) {
discard;
}
gl_FragColor = vec4(fragColor, 1);
}`,

attributes: {
freq: {
buffer: pointBuffer,
stride: VERT_SIZE,
offset: 0
},
phase: {
buffer: pointBuffer,
stride: VERT_SIZE,
offset: 16
},
color: {
buffer: pointBuffer,
stride: VERT_SIZE,
offset: 32
}
},

uniforms: {
view: ({tick}) => {
const t = 0.01 * tick
return mat4.lookAt([],
[30 * Math.cos(t), 2.5, 30 * Math.sin(t)],
[0, 0, 0],
[0, 1, 0])
},
projection: ({viewportWidth, viewportHeight}) =>
mat4.perspective([],
Math.PI / 4,
viewportWidth / viewportHeight,
0.01,
1000),
time: ({tick}) => tick * 0.001
},

count: NUM_POINTS,

primitive: 'points'
})
Insert cell
regl.frame(() => {
regl.clear({
depth: 1,
color: [1, 1, 1, 1]
})

drawParticles()
})
Insert cell
NUM_POINTS = 2000
Insert cell
VERT_SIZE = 4 * (4 + 4 + 3)
Insert cell
pointBuffer = regl.buffer(Array(NUM_POINTS).fill().map(function () {
const color = hsv2rgb(Math.random() * 360, 0.6, 1)
return [
// freq
Math.random() * 10,
Math.random() * 10,
Math.random() * 10,
Math.random() * 10,
// phase
2.0 * Math.PI * Math.random(),
2.0 * Math.PI * Math.random(),
2.0 * Math.PI * Math.random(),
2.0 * Math.PI * Math.random(),
// color
color[0] / 255, color[1] / 255, color[2] / 255
]
}))
Insert cell
wrapREGL = require('regl')
Insert cell
mat4 = require('https://bundle.run/gl-mat4@1.2.0')
Insert cell
hsv2rgb = require('https://bundle.run/hsv2rgb@1.1.0')
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more