JSFiddle - React, Tailwind, and code Playground

by Cody Bennett

CSS

body {
        margin: 0;
      }

      canvas {
        display: block;
      }

      video {
        display: none;
      }

JavaScript

import * as THREE from 'https://unpkg.com/three/build/three.module.js';

const renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(2);
document.body.appendChild(renderer.domElement);

const camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 10);
camera.position.z = 2;

const scene = new THREE.Scene();
scene.background = new THREE.Color(0xFFFFFF);

const video = document.createElement('video');
video.src = 'https://krpano.com/releases/1.20.9/viewer/examples/chromakey/video.mp4';
video.autoplay = true;

const videoTexture = new THREE.VideoTexture(video);

const material = new THREE.ShaderMaterial({
  uniforms: {
    video: {
      type: 't',
      value: videoTexture
    },
    color: {
      type: 'c',
      value: new THREE.Color(0x238E54)
    }
  },
  vertexShader: `
    varying vec2 vUv;

    void main(void) {
      vUv = uv;
      vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);

      gl_Position = projectionMatrix * mvPosition;
    }
  `,
  fragmentShader: `
    uniform sampler2D video;
    uniform vec3 color;

    varying vec2 vUv;

    void main(void) {
      vec3 tColor = texture2D(video, vUv).rgb;
      float a = (length(tColor - color) - 0.2) * 7.0;

      gl_FragColor = vec4(tColor, a);
    }
  `,
  transparent: true
});

const geometry = new THREE.PlaneBufferGeometry(1, 2);
const plane = new THREE.Mesh(geometry, material);
scene.add(plane);

renderer.setAnimationLoop(() => {
  renderer.render(scene, camera);
});