Blend mode + Color Correction

by adil_invideo

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.3.3/pixi.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/pixi-projection.min.js"></script>

CSS

input#slider {
  width: 50%;
}

canvas{
   width: 100%;
   height: 600px;
}

JavaScript

const frag = `
varying highp vec2 vTextureCoord;
uniform sampler2D uSampler;

uniform vec3 color1;
uniform vec3 color2;
uniform vec3 color3;

void main() {
  lowp vec4 textureColor = texture2D(uSampler, vTextureCoord);
  textureColor.rgb /= textureColor.a;

  float grayscaleValue = dot(textureColor.rgb, vec3(0.2126, 0.7152, 0.0722));

  vec3 map = vec3(0);

  if (grayscaleValue < 0.5) {
    float t = grayscaleValue / 0.5;
    map.rgb = mix(color1, color2, t);
  } else {
    float t = (grayscaleValue - 0.5) / 0.5;
    map.rgb = mix(color2, color3, t);
  }
  map.rgb *= textureColor.a;
  gl_FragColor = vec4(map.rgb, textureColor.a);
}
`;

class TritoneFilter extends PIXI.Filter {
  _color1;
  _color2;
  _color3;

  constructor(color1, color2, color3) {
    const c1 = color1.rgba.map((c) => c / 255.0);
    const c2 = color2.rgba.map((c) => c / 255.0);
    const c3 = color3.rgba.map((c) => c / 255.0);
    const uniforms = {
      color1: c1,
      color2: c2,
      color3: c3,
    };
    super(undefined, frag, uniforms);
    this._color1 = c1;
    this._color2 = c2;
    this._color3 = c3;
  }

  updateColors(color1, color2, color3) {
    this._color1 = color1.rgba.map((c) => c / 255.0);
    this._color2 = color2.rgba.map((c) => c / 255.0);
    this._color3 = color3.rgba.map((c) => c / 255.0);
    this._updateTransform();
  }

  _updateTransform() {
    this.uniforms.color1 = this._color1;
    this.uniforms.color2 = this._color2;
    this.uniforms.color3 = this._color3;
  }
}


const url = 'https://invideo-uploads-ap-south-1.s3.ap-south-1.amazonaws.com/ASSET041609130087938.png';

const app = new PIXI.Application({
  width: document.body.clientWidth,
  height: 600,
  backgroundColor: 0xFFCCCC,
  antialias: true,
  resolution: 2
});

document.body.appendChild(app.view);

const container = new PIXI.Container();

app.stage.addChild(container);
const sprite = PIXI.Sprite.from(url);
sprite.width = 300;
sprite.height = 300;
container.addChild(sprite);