evanw / glfx.js

An image effects library for JavaScript using WebGL
https://evanw.github.io/glfx.js/
MIT License
3.26k stars 402 forks source link

Vignette: support for colors #51

Open av01d opened 5 years ago

av01d commented 5 years ago

I'd like to be able to apply the vignette effect in more colors than black (only black is currently supoported). Does anybody have enough webGL skills to change the vignette shader so that is supports color? I'd propose to add a 3rd color argument to the vignette function, that accepts either a HEX or a RGB(A) color.

function vignette(size, amount /* , color */) {
   gl.vignette = gl.vignette || new Shader(null, `
      uniform sampler2D texture;
      uniform float size;
      uniform float amount;
      varying vec2 texCoord;
      void main() {
         vec4 color = texture2D(texture, texCoord);

         float dist = distance(texCoord, vec2(0.5, 0.5));
         color.rgb *= smoothstep(0.8, size * 0.799, dist * (amount + size));
         gl_FragColor = color;
      }
   `);

   simpleShader.call(this, gl.vignette, {
      size: clamp(0, size, 1),
      amount: clamp(0, amount, 1)
   });

   return this;
}
av01d commented 5 years ago

To answer my own question:

function vignette(size, amount, color) {
   color = color || '#000000';

   gl.vignette = gl.vignette || new Shader(null, `
      uniform sampler2D texture;
      uniform float size;
      uniform float amount;
      uniform float r;
      uniform float g;
      uniform float b;
      varying vec2 texCoord;
      void main() {
         vec4 color = texture2D(texture, texCoord);
         vec3 vignetteColor = vec3(r, g, b); //red;

         float dist = distance(texCoord, vec2(0.5, 0.5));
         float vignetteOpacity = 1.0-smoothstep(0.8, size * 0.799, dist * (amount + size));
         color.rgb = mix(color.rgb, vignetteColor, vignetteOpacity);
         gl_FragColor = color;
      }
   `);

   function hexToRgb(hex) {
      hex = hex.replace(/^#/,'');
      var bigint = parseInt(hex, 16);
      return {r:(bigint >> 16) & 255, g:(bigint >> 8) & 255, b:bigint & 255};
   }
   var rgb = hexToRgb(color);

   simpleShader.call(this, gl.vignette, {
      size: clamp(0, size, 1),
      amount: clamp(0, amount, 1),
      r: rgb.r/255,
      g: rgb.g/255,
      b: rgb.b/255
   });

   return this;
}