JSFiddle - React, Tailwind, and code Playground

HTML

<canvas id="gl"></canvas>

<div id="info">
  <b>Mesh volume via x-flux</b><br>
  Hover over a triangle.<br><br>

  <span class="red">Red</span> = positive contribution<br>
  <span class="blue">Blue</span> = negative contribution

  <div id="face">No triangle selected</div>
</div>

CSS

html, body {
  margin: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: #101216;
  font-family: system-ui, sans-serif;
}

#gl {
  width: 100%;
  height: 100%;
  display: block;
}

#info {
  position: absolute;
  top: 14px;
  left: 14px;

  padding: 12px 15px;

  color: white;
  background: rgba(0,0,0,.72);
  border-radius: 8px;

  font-size: 14px;
  line-height: 1.45;

  pointer-events: none;
}

#face {
  margin-top: 12px;
  font-family: monospace;
  white-space: pre;
}

.red  { color: #ff6666; }
.blue { color: #66aaff; }

JavaScript

"use strict";

const canvas = document.getElementById("gl");
const info = document.getElementById("face");

const gl = canvas.getContext("webgl", {
  antialias: true,
  alpha: false
});

if (!gl) throw new Error("WebGL not supported");

// ============================================================
// SHADERS
// ============================================================

function compileShader(type, source) {
  const s = gl.createShader(type);
  gl.shaderSource(s, source);
  gl.compileShader(s);

  if (!gl.getShaderParameter(s, gl.COMPILE_STATUS)) {
    throw new Error(gl.getShaderInfoLog(s));
  }

  return s;
}

function createProgram(vsSource, fsSource) {
  const p = gl.createProgram();

  gl.attachShader(p, compileShader(gl.VERTEX_SHADER, vsSource));
  gl.attachShader(p, compileShader(gl.FRAGMENT_SHADER, fsSource));

  gl.linkProgram(p);

  if (!gl.getProgramParameter(p, gl.LINK_STATUS)) {
    throw new Error(gl.getProgramInfoLog(p));
  }

  return p;
}

const program = createProgram(
`
attribute vec3 position;
uniform mat4 matrix;

void main() {
  gl_Position = matrix * vec4(position, 1.0);
}
`,
`
precision mediump float;
uniform vec4 color;

void main() {
  gl_FragColor = color;
}
`
);

const aPosition = gl.getAttribLocation(program, "position");
const uMatrix   = gl.getUniformLocation(program, "matrix");
const uColor    = gl.getUniformLocation(program, "color");

gl.useProgram(program);

// ============================================================
// MATH
// ============================================================

const sub = (a,b) => [
  a[0]-b[0],
  a[1]-b[1],
  a[2]-b[2]
];

const add = (a,b) => [
  a[0]+b[0],
  a[1]+b[1],
  a[2]+b[2]
];

const mul = (a,s) => [
  a[0]*s,
  a[1]*s,
  a[2]*s
];

const dot = (a,b) =>
  a[0]*b[0] +
  a[1]*b[1] +
  a[2]*b[2];

const cross = (a,b) => [
  a[1]*b[2] - a[2]*b[1],
  a[2]*b[0] - a[0]*b[2],
  a[0]*b[1] -...