PIXI Chroma Filter

Demonstration of a custom Chroma key Filter with intensity control

by adil_invideo

HTML

<script src="https://pixijs.download/dev/pixi.min.js"></script>
<div class="parent">
<input type="range" max="1" min="0" step="0.01" id="distance" value="0"/>

</div>

CSS

.parent{
  display : flex;
  flex-direction: column;
  width: 200px;
}

JavaScript

const imageSrc = "https://images.unsplash.com/photo-1504537103742-67c282f65f24?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&ixid=eyJhcHBfaWQiOjIxMjgxfQ";

/* const imageSrc = 'https://fiverr-res.cloudinary.com/images/q_auto,f_auto/gigs2/8779252/original/9d47bde40d1f4aad1afa59c5e1a604b08f6d38ab/record-a-green-screen-video-9f3a2a27-6cda-4327-a050-7ec5aa3e87df.jpg'; */

/* const imageSrc = 'https://lh3.googleusercontent.com/3f0A7wku8KOEaOAT9fZOKrw3wKZyCmbAJM1ulQU3Lj41tXIhWngaHgDZK59a2htSu4k'; */
const frag1 = `
varying vec2 vTextureCoord;
uniform sampler2D uTexture;


void main() {
  vec4 uLow = vec4(1.0,1.0,1.0,1.0);
  vec4 uHigh = vec4(1.0,1.0,1.0,1.0);
   gl_FragColor = texture2D(uTexture, vTextureCoord);
   gl_FragColor.a = 0.1;
 }
`;

const frag = `
precision highp float;
      uniform sampler2D uTexture;      
      uniform vec4 uLow;
      uniform vec4 uHigh;
      varying vec2 vTextureCoord;
      uniform vec4 color;
      void main() {
        gl_FragColor = texture2D(uTexture, vTextureCoord);
        if(all(greaterThan(gl_FragColor.rgb,uLow.rgb)) && all(greaterThan(uHigh.rgb,gl_FragColor.rgb))) {
          gl_FragColor.a = 0.0;
        }
      }
`;

class ChromaFilter extends PIXI.Filter {

  constructor(src = [0, 0, 0, 1]) {
    super(null, frag, {
      uLow: [
        src[0] - 0.0,
        src[1] - 0.0,
        src[2] - 0.0,
        1
      ],
      uHigh: [
        src[0] + 0.0,
        src[1] + 0.0,
        src[2] + 0.0,
        1
      ]
    });
    this._source = src;
  }

  get distance() {
    return this._distance;
  }

  set distance(value) {
    this._distance = value;
    this._updateTransform();
  }

  get source() {
    return this._source;
  }

  set source(value) {
    this._source = value;
    this._updateTransform();
  }

  _updateTransform() {
    const lowC = [
      0 + (this.source[0] / 255) - this.distance,
      0 + (this.source[1] / 255) - this.distance,
      0 + (this.source[2] / 255) - this.distance,
     ...