JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/three.js"></script>

<script id="vertexShader" type="glsl">

	varying vec2 vUv;

	void main() {
		vUv = uv;
		gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
	}
</script>

<script id="fragmentShader" type="glsl">

        uniform sampler2D tex;
        uniform float texWidth;
        uniform float texHeight;

        uniform vec3 keyColor;
        uniform float similarity;
        uniform float smoothness;
        uniform float spill;
				
				varying vec2 vUv;

        // From https://github.com/libretro/glsl-shaders/blob/master/nnedi3/shaders/rgb-to-yuv.glsl
        vec2 RGBtoUV(vec3 rgb) {
          return vec2(
            rgb.r * -0.169 + rgb.g * -0.331 + rgb.b *  0.5    + 0.5,
            rgb.r *  0.5   + rgb.g * -0.419 + rgb.b * -0.081  + 0.5
          );
        }

        vec4 ProcessChromaKey(vec2 texCoord) {
          vec4 rgba = texture2D(tex, texCoord);
          float chromaDist = distance(RGBtoUV(texture2D(tex, texCoord).rgb), RGBtoUV(keyColor));

          float baseMask = chromaDist - similarity;
          float fullMask = pow(clamp(baseMask / smoothness, 0., 1.), 1.5);
          rgba.a = fullMask;

          float spillVal = pow(clamp(baseMask / spill, 0., 1.), 1.5);
          float desat = clamp(rgba.r * 0.2126 + rgba.g * 0.7152 + rgba.b * 0.0722, 0., 1.);
          rgba.rgb = mix(vec3(desat, desat, desat), rgba.rgb, spillVal);

          return rgba;
        }

        void main(void) {
          vec2 texCoord = vUv;
          gl_FragColor = ProcessChromaKey(texCoord);
        }
      </script>

JavaScript

ChromaKeyMaterial = function (width, height, keyColor) {

    THREE.ShaderMaterial.call(this);

   this.setValues({

     uniforms: {
       tex: {
         value: new THREE.TextureLoader().load('https://threejs.org/examples/textures/uv_grid_opengl.jpg')
       },
       keyColor: {
         value: new THREE.Color(keyColor)
       },
       texWidth: {
         value: width
       },
       texHeight: {
         value: height
       },
       similarity: {
         value: 0.4
       },
       smoothness: {
         value: 0.08
  		},
       spill: {
         value: 0.1
       }

     },
     vertexShader: document.getElementById('vertexShader').textContent,
     fragmentShader: document.getElementById('fragmentShader').textContent,

     transparent: true
   });

 } // ChromakeyMaterial

 ChromaKeyMaterial.prototype = Object.create(THREE.ShaderMaterial.prototype);


 let camera, scene, renderer;
 let movieMaterial;

 // set the scene size
 var WIDTH = window.innerWidth,
     HEIGHT = window.innerHeight;

 // set some camera attributes
 var VIEW_ANGLE = 75,
     ASPECT = WIDTH / HEIGHT,
     NEAR = 0.1,
     FAR = 1000;

 init();
 animate();

 function init() {

   scene = new THREE.Scene();

   camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR)
   camera.position.z = 2;
	 
	 var geometry = new THREE.PlaneGeometry();
	 var material = new ChromaKeyMaterial(1280, 720, 0xffff00);

   var mesh = new THREE.Mesh(geometry, material);
   scene.add(mesh);

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

   window.addEventListener( 'resize', onWindowResize, false );

 }

 function onWindowResize() {

   camera.aspect = window.innerWidth / window.innerHeight;
   camera.updateProjectionMatrix();

   renderer.setSize( window.innerWidth,...