Blend Modes

Demonstration of Blend Modes. CSS v/s PIXI WebGL

by adil_invideo

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.1.3/pixi.min.js"></script>
<div class="header">
  <div class="title">
    CSS
  </div>
  <div class="title">
    WebGL
  </div>

</div>

CSS

body {
  display: flex;
  flex-direction: column;
  font-family: sans-serif;
  padding-bottom: 30px;
}

.image {
  width: 100%;
  height: 100%;
  position: absolute;
}

.img-container {
  width: 320px;
  height: 100%;
  position: relative;
}

.foreground {
  mix-blend-mode: multiply;
}

.row {
  display: flex;
  height: 300px;
  justify-content: space-evenly;
  margin-bottom: 5px;
}

.text {
  position: absolute;
  bottom: 5px;
  left: 5px;
  color: red;
  font-size: 40px;
  font-weight: 600;
  -webkit-text-fill-color: white;
  -webkit-text-stroke-width: 1px;
  -webkit-text-stroke-color: black;
}

.header {
  display: flex;
  justify-content: space-evenly;
  padding: 10px;
}

.title {
  text-align: center;
  font-size: 30px;
  font-weight: 600;
}

JavaScript

// REFERENCE:
// https://www.pixiplayground.com/#/edit/6c0X5xaWa2MMy6vXfIix0
// http://renderingpipeline.com/2012/06/photoshop-blendmodi-glsl/
// https://github.com/jamieowen/glsl-blend/blob/master/source/PhotoshopMathFP.glsl
// https://github.com/jamieowen/glsl-blend
// http://renderingpipeline.com/2012/06/photoshop-blendmodi-glsl/
// https://forum.libcinder.org/topic/glsl-beginner-photoshop-blending-modes
// https://www.w3.org/TR/compositing-1/#blendingnormal
const bgSrc = "https://cdn.pixabay.com/photo/2016/02/13/12/26/aurora-1197753_150.jpg";
const imgSrc = "https://cdn.pixabay.com/photo/2018/05/07/10/48/husky-3380548_150.jpg";

const frag = `
precision highp float;

uniform sampler2D background;
uniform sampler2D foreground;
uniform int mode;
varying vec2 vTextureCoord;

/*
    Utility Functions
*/
float HueToRGB(float f1, float f2, float hue) {
  if (hue < 0.0)
    hue += 1.0;
  else if (hue > 1.0)
    hue -= 1.0;
  float res;
  if ((6.0 * hue) < 1.0)
    res = f1 + (f2 - f1) * 6.0 * hue;
  else if ((2.0 * hue) < 1.0)
    res = f2;
  else if ((3.0 * hue) < 2.0)
    res = f1 + (f2 - f1) * ((2.0 / 3.0) - hue) * 6.0;
  else
    res = f1;
  return res;
}

vec3 HSLToRGB(vec3 hsl) {
  vec3 rgb;

  if (hsl.y == 0.0)
    rgb = vec3(hsl.z); // Luminance
  else {
    float f2;

    if (hsl.z < 0.5)
      f2 = hsl.z * (1.0 + hsl.y);
    else
      f2 = (hsl.z + hsl.y) - (hsl.y * hsl.z);

    float f1 = 2.0 * hsl.z - f2;

    rgb.r = HueToRGB(f1, f2, hsl.x + (1.0 / 3.0));
    rgb.g = HueToRGB(f1, f2, hsl.x);
    rgb.b = HueToRGB(f1, f2, hsl.x - (1.0 / 3.0));
  }

  return rgb;
}

vec3 RGBToHSL(vec3 color) {
  vec3 hsl; // init to 0 to avoid warnings ? (and reverse if + remove first part)

  float fmin = min(min(color.r, color.g), color.b); //Min. value of RGB
  float fmax = max(max(color.r, color.g), color.b); //Max. value of RGB
  float delta = fmax - fmin; //Delta RGB value

  hsl.z = (fmax + fmin) / 2.0; // Luminance

  if (delta == 0.0) //This is a gray, no...