Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebGL filters #599

Closed
privyreza opened this issue May 26, 2021 · 5 comments
Closed

WebGL filters #599

privyreza opened this issue May 26, 2021 · 5 comments

Comments

@privyreza
Copy link

Hello guys,

I am trying to implement an Ink filter based on Ivanw WebGL Ink Filter, but I am failing to make it work.

I added the shader using fragmentSource function , the send the parameter using the sendUniformData function and returned the returned a map of attribute names to WebGLAttributeLocation objects using getUniformLocations

While changing the ink strength parameter, nothing is changing. I added the code below, kindly assist if I am missing anything

const fabric = global.fabric || (global.fabric = {});

/**
 * MyFilter filter class
 * @class fabric.Image.filters.MyFilter
 * @memberOf fabric.Image.filters
 * @extends fabric.Image.filters.BaseFilter
 * @see {@link fabric.Image.filters.MyFilter#initialize} for constructor definition
 * @see {@link https://fabricjs.com/image-filters|ImageFilters demo}
 * @example
 * var filter = new fabric.Image.filters.MyFilter({
 *   add here an example of how to use your filter
 * });
 * object.filters.push(filter);
 * object.applyFilters();
 */
const Ink = fabric.util.createClass(
  fabric.Image.filters.BaseFilter,
  /** @lends fabric.Image.filters.MyFilter.prototype */ {
    /**
     * Filter type
     * @param {String} type
     * @default
     */
    type: 'Ink',

    /**
     * Fragment source for the myParameter program
     */
    fragmentSource:
      'uniform sampler2D texture;\n' +
      'uniform float strength;\n' +
      'uniform vec2 texSize;\n' +
      'varying vec2 texCoord;\n' +
      'void main() {\n' +
      'vec2 dx = vec2(1.0 / texSize.x, 0.0);\n' +
      'vec2 dy = vec2(0.0, 1.0 / texSize.y);\n' +
      'vec4 color = texture2D(texture, texCoord);\n' +
      'float bigTotal = 0.0;\n' +
      'float smallTotal = 0.0;\n' +
      'vec3 bigAverage = vec3(0.0);\n' +
      'vec3 smallAverage = vec3(0.0);\n' +
      'for (float x = -2.0; x <= 2.0; x += 1.0) {\n' +
      'for (float y = -2.0; y <= 2.0; y += 1.0) {\n' +
      'vec3 sample = texture2D(texture, texCoord + dx * x + dy * y).rgb;\n' +
      'bigAverage += sample;\n' +
      'bigTotal += 1.0;\n' +
      'if (abs(x) + abs(y) < 2.0) {\n' +
      'smallAverage += sample;\n' +
      'smallTotal += 1.0;\n' +
      '}\n' +
      '}\n' +
      '}\n' +
      'vec3 edge = max(vec3(0.0), bigAverage / bigTotal - smallAverage / smallTotal);\n' +
      'gl_FragColor = vec4(color.rgb - dot(edge, edge) * strength * 100000.0, color.a);\n' +
      '}',
    /**
     * MyFilter value, from -1 to 1.
     * translated to -255 to 255 for 2d
     * 0.0039215686 is the part of 1 that get translated to 1 in 2d
     * @param {Number} myParameter
     * @default
     */
    ink: 0,

    initialize(options) {
      if (!options) {
        options = {};
      }
      this.ink = options.ink;
    },

    /**
     * Describe the property that is the filter parameter
     * @param {String} m
     * @default
     */
    mainParameter: 'ink',

    /**
     * Apply the MyFilter operation to a Uint8ClampedArray representing the pixels of an image.
     *
     * @param {Object} options canvas
     * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.
     */
    applyTo2d(options) {
      if (this.ink === 0) {
        // early return if the parameter value has a neutral value
        return;
      }
      const { data } = options.imageData;
      let i;
      const len = data.length;
      for (i = 0; i < len; i += 4) {
        // data[i] = this.ink;
        // data[i + 1] = this.ink;
        // data[i + 2] = this.ink;
      }
    },

    /**
     * Return WebGL uniform locations for this filter's shader.
     *
     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
     * @param {WebGLShaderProgram} program This filter's compiled shader program.
     * @returns {gl}
     * @private
     */
    getUniformLocations(gl, program) {
      return {
        strength: gl.getUniformLocation(program, 'strength'),
      };
    },

    /**
     * Send data from this filter to its shader program's uniforms.
     *
     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects
     */
    sendUniformData(gl, uniformLocations) {
      gl.uniform1f(uniformLocations.strength, this.ink);
    },
  }
);

export default Ink;
@lja1018
Copy link
Contributor

lja1018 commented Jun 2, 2021

@privyreza
Thank you for asking.
Does the Ink filter change with the strength property? I will reply after checking.

@stale
Copy link

stale bot commented Jul 2, 2021

This issue has been automatically marked as inactive because there hasn’t been much going on it lately. It is going to be closed after 7 days. Thanks!

@stale stale bot added the inactive label Jul 2, 2021
@privyreza
Copy link
Author

privyreza commented Jul 2, 2021 via email

@stale stale bot removed the inactive label Jul 2, 2021
@stale
Copy link

stale bot commented Aug 2, 2021

This issue has been automatically marked as inactive because there hasn’t been much going on it lately. It is going to be closed after 7 days. Thanks!

@stale stale bot added the inactive label Aug 2, 2021
@stale
Copy link

stale bot commented Aug 10, 2021

This issue will be closed due to inactivity. Thanks for your contribution!

@stale stale bot closed this as completed Aug 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants