JSFiddle - React, Tailwind, and code Playground
by Cody Bennett
CSS
body {
margin: 0;
}
canvas {
display: block;
}
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 = 1;
const scene = new THREE.Scene();
const url = 'https://krpano.com/releases/1.20.9/viewer/examples/chromakey/video.mp4';
const keyColor = 0x238E54;
const video = document.createElement('video');
video.src = url;
video.load();
const videoTexture = new THREE.Texture(video);
videoTexture.minFilter = THREE.LinearFilter;
videoTexture.magFilter = THREE.LinearFilter;
const chromaKeyMaterial = new THREE.ShaderMaterial({
uniforms: {
texture: {
type: 't',
value: videoTexture
},
color: {
type: 'c',
value: new THREE.Color(keyColor)
}
},
vertexShader: `
varying mediump vec2 vUv;
void main(void) {
vUv = uv;
mediump vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
gl_Position = projectionMatrix * mvPosition;
}
`,
fragmentShader: `
uniform mediump sampler2D texture;
uniform mediump vec3 color;
varying mediump vec2 vUv;
void main(void) {
mediump vec3 tColor = texture2D( texture, vUv ).rgb;
mediump float a = (length(tColor - color) - 0.5) * 7.0;
gl_FragColor = vec4(tColor, a);
}
`,
transparent: true
});
const chromaKeyGeometry = new THREE.PlaneBufferGeometry(5, 5);
const chromaKeyPlane = new THREE.Mesh(chromaKeyGeometry, chromaKeyMaterial);
scene.add(chromaKeyPlane);
renderer.setAnimationLoop(() => {
if (video.readyState === video.HAVE_ENOUGH_DATA) {
videoTexture.needsUpdate = true;
}
renderer.render(scene, camera);
});