PIXI Sepia Filter

Demonstration of Custom PIXI Sepia Filter with intensity control

by adil_invideo

HTML

<script src="https://pixijs.download/dev/pixi.min.js"></script>

<div class="parent">
<h2>PIXI Sepia Filter</h2>
<input type="range" max="1" min="0" step="0.01" id="intensity" value="0"/>
</div>

CSS

body {
  font-family: sans-serif;
}

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

JavaScript

//References:
// https://stackoverflow.com/questions/5830139/how-can-i-do-these-image-processing-tasks-using-opengl-es-2-0-shaders/9402041#9402041
// https://www.shadertoy.com/view/wdccDr
// https://pixijs.download/dev/docs/packages_filters_filter-color-matrix_src_ColorMatrixFilter.ts.html#line316

const imageSrc = "https://c.files.bbci.co.uk/3ED6/production/_106768061_gettyimages-1126199440.jpg";

const frag = `
 varying highp vec2 vTextureCoord;
 uniform sampler2D uSampler;
 uniform lowp float intensity; 
const mat4 colorMatrix = mat4(
 				0.393, 0.769, 0.189, 0.0,
        0.349, 0.686, 0.168, 0.0,
        0.272, 0.534, 0.131, 0.0,
        0.0, 0.0, 0.0, 1.0
);

 void main()
 {
     lowp vec4 textureColor = texture2D(uSampler, vTextureCoord);
     lowp vec4 outputColor = textureColor * colorMatrix;
     gl_FragColor = (intensity * outputColor) + ((1.0 - intensity) * textureColor);
 }
`;

class SepiaFilter extends PIXI.Filter {

  constructor() {
    super(null, frag, {
      intensity: 0.0
    });
  }

  get intensity() {
    return this._intensity;
  }

  set intensity(value) {
    this._intensity = value;
    this._updateTransform();
  }

  _updateTransform() {
    this.uniforms.intensity = this._intensity; 
  }

}

const app = new PIXI.Application({
  width: 400,
  height: 250,
  transparent: true
});

document.body.appendChild(app.view);

const sprite = PIXI.Sprite.fromImage(imageSrc);

sprite.width = app.screen.width;
sprite.height = app.screen.height;

app.stage.addChild(sprite);
const filter = new SepiaFilter();
sprite.filters = [filter];

document.getElementById('intensity').oninput = (event) => {
  filter.intensity = parseFloat(event.target.value);
};