Public
Edited
Jan 21, 2024
Insert cell
Insert cell
canvas = DOM.canvas(width, 600)
Insert cell
regl.frame(() => {
setupQuad(() => {
regl.draw();
updateLife();
});
})
Insert cell
setupQuad = regl({
frag: `
precision mediump float;
uniform sampler2D prevState;
uniform float tick;
varying vec2 uv;
void main() {
float state = texture2D(prevState, uv).r;
gl_FragColor = vec4(vec3(state), 1);

float t = fract(tick/float(${RADIUS}) / 5.0);
if ( dot(uv-t, uv-t) < 0.0001){
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
};

}`,

vert: `
precision mediump float;
attribute vec2 position;
varying vec2 uv;
void main() {
uv = 0.5 * (position + 1.0);
gl_Position = vec4(position, 0, 1);
}`,

attributes: {
position: [-4, -4, 4, -4, 0, 4]
},

uniforms: {
prevState: ({ tick }) => state[tick % 2],
tick: ({ tick }) => tick
},

depth: { enable: false },

count: 3
})
Insert cell
updateLife = regl({
frag: `
precision mediump float;
uniform sampler2D prevState;
uniform float tick;
varying vec2 uv;
void main() {
float n = 0.0;
for(int dx=-1; dx<=1; ++dx)
for(int dy=-1; dy<=1; ++dy) {
n += texture2D(prevState, uv+vec2(dx,dy)/float(${RADIUS})).r;
}
float s = texture2D(prevState, uv).r;
if(n > 3.0+s || n < 3.0) {
gl_FragColor = vec4(0,0,0,1);
} else {
gl_FragColor = vec4(1,1,1,1);
}

float t = fract(tick/float(${RADIUS}) / 5.0);
if ( dot(uv-t, uv-t) < 0.0001){
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
};
}`,

framebuffer: ({ tick }) => state[(tick + 1) % 2],

uniforms: {
tick: ({ tick }) => tick
}
})
Insert cell
state = (Array(2)).fill().map(() =>
regl.framebuffer({
color: regl.texture({
radius: RADIUS,
data: INITIAL_CONDITIONS,
wrap: 'repeat'
}),
depthStencil: false
}))
Insert cell
RADIUS = 512
Insert cell
INITIAL_CONDITIONS = Array(RADIUS * RADIUS * 4)
.fill(0)
.map(() => (Math.random() > 0.9 ? 255 : 0))
Insert cell
regl = (await import("https://cdn.skypack.dev/regl@2")).default({
canvas,
pixelRatio: 2.0,
extensions: ["oes_standard_derivatives", "oes_texture_float"]
})
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