JSFiddle - React, Tailwind, and code Playground

by flek

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/regl/2.1.0/regl.min.js"></script>
<canvas id="canvas" style="width: 200px; height: 200px"></canvas>

JavaScript

const canvas = document.querySelector('#canvas');

const bBox = canvas.getBoundingClientRect();

const res = [
  bBox.width * window.devicePixelRatio,
  bBox.height * window.devicePixelRatio,
];

canvas.width = res[0];
canvas.height = res[1];

const GL_EXTENSIONS = ['OES_texture_float', 'OES_element_index_uint'];

function createRegl() {
  const gl = canvas.getContext('webgl', {
    antialias: true,
    preserveDrawingBuffer: true,
  });
  const extensions = [];

  GL_EXTENSIONS.forEach((EXTENSION) => {
    if (gl.getExtension(EXTENSION)) {
      extensions.push(EXTENSION);
    } else {
      console.warn(
        `WebGL: ${EXTENSION} extension not supported. Scatterplot might not render properly`
      );
    }
  });

  return window.createREGL({ gl, extensions });
}

const regl = createRegl();

const fbo = regl.framebuffer({
  width: res[0],
  height: res[1],
  colorFormat: 'rgba',
  colorType: 'float',
});

const copyToScreen = regl({
  vert: `
    precision highp float;
    attribute vec2 xy;
    void main () {
      gl_Position = vec4(xy, 0, 1);
    }`,
  frag: `
    precision highp float;
    uniform vec2 srcRes;
    uniform sampler2D src;
    uniform float gamma;

    vec3 approxLinearToSRGB (vec3 rgb, float gamma) {
      return pow(clamp(rgb, vec3(0), vec3(1)), vec3(1.0 / gamma));
    }

    void main () {
      vec4 color = texture2D(src, gl_FragCoord.xy / srcRes);
      gl_FragColor = vec4(approxLinearToSRGB(color.rgb, gamma), color.a);
    }`,
  attributes: {
    xy: [-4, -4, 4, -4, 0, 4],
  },
  uniforms: {
    src: () => fbo,
    srcRes: () => res,
    gamma: () => 1,
  },
  count: 3,
  depth: { enable: false },
  blend: {
    enable: true,
    func: {
      srcRGB: 'one',
      srcAlpha: 'one',
      dstRGB: 'one minus src alpha',
      dstAlpha: 'one minus src alpha',
    },
  },
});

const drawDots = (color = [1, 0, 0, 1], size = 24.5) => {
  regl({
    blend: {
      enable: true, // This prevents stupid Safari v14 from rendering the points.
   ...