Source: tiny/core/renderers/webgl/filters/Filter.js

import extractUniformsFromSrc from './extractUniformsFromSrc';
import { uid } from '../../../utils';
import { BLEND_MODES } from '../../../const';
import settings from '../../../settings';

const SOURCE_KEY_MAP = {};

/**
 * @class
 * @memberof Tiny
 * @extends Tiny.Shader
 */
export default class Filter {
  /**
   * @param {string} [vertexSrc] - The source of the vertex shader.
   * @param {string} [fragmentSrc] - The source of the fragment shader.
   * @param {object} [uniformData] - Custom uniforms to use to augment the built-in ones.
   */
  constructor(vertexSrc, fragmentSrc, uniformData) {
    /**
     * The vertex shader.
     *
     * @member {string}
     */
    this.vertexSrc = vertexSrc || Filter.defaultVertexSrc;

    /**
     * The fragment shader.
     *
     * @member {string}
     */
    this.fragmentSrc = fragmentSrc || Filter.defaultFragmentSrc;

    this._blendMode = BLEND_MODES.NORMAL;

    this.uniformData = uniformData || extractUniformsFromSrc(
      this.vertexSrc,
      this.fragmentSrc,
      'projectionMatrix|uSampler'
    );

    /**
     * An object containing the current values of custom uniforms.
     *
     * @example <caption>Updating the value of a custom uniform</caption>
     * filter.uniforms.time = performance.now();
     *
     * @member {object}
     */
    this.uniforms = {};

    for (const i in this.uniformData) {
      this.uniforms[i] = this.uniformData[i].value;
      if (this.uniformData[i].type) {
        this.uniformData[i].type = this.uniformData[i].type.toLowerCase();
      }
    }

    // this is where we store shader references..
    // TODO we could cache this!
    this.glShaders = {};

    // used for caching.. sure there is a better way!
    if (!SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc]) {
      SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc] = uid();
    }

    this.glShaderKey = SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc];

    /**
     * The padding of the filter. Some filters require extra space to breath such as a blur.
     * Increasing this will add extra width and height to the bounds of the object that the filter is applied to.
     *
     * @member {number}
     */
    this.padding = 4;

    /**
     * The resolution of the filter. Setting this to be lower will lower the quality but increase the performance of the filter.
     *
     * @member {number}
     */
    this.resolution = settings.FILTER_RESOLUTION;

    /**
     * If enabled is true the filter is applied, if false it will not.
     *
     * @member {boolean}
     */
    this.enabled = true;

    /**
     * If enabled, will fit the filter area into boundaries for better performance.
     * Switch it off if it does not work for specific shader.
     *
     * @member {boolean}
     */
    this.autoFit = true;
  }

  /**
   * Applies the filter
   *
   * @param {Tiny.FilterManager} filterManager - The renderer to retrieve the filter from
   * @param {Tiny.RenderTarget} input - The input render target.
   * @param {Tiny.RenderTarget} output - The target to output to.
   * @param {boolean} clear - Should the output be cleared before rendering to it
   * @param {object} [currentState] - It's current state of filter. There are some useful properties in the currentState: target, filters, sourceFrame, destinationFrame, renderTarget, resolution
   */
  apply(filterManager, input, output, clear, currentState) {
    // --- //
    //  this.uniforms.filterMatrix = filterManager.calculateSpriteMatrix(tempMatrix, window.panda );

    // do as you please!

    filterManager.applyFilter(this, input, output, clear);

    // or just do a regular render..
  }

  /**
   * Sets the blendmode of the filter
   *
   * @version 1.2.0
   * @member {number}
   * @default Tiny.BLEND_MODES.NORMAL
   */
  get blendMode() {
    return this._blendMode;
  }
  set blendMode(value) {
    this._blendMode = value;
  }

  /**
   * The default vertex shader source
   *
   * @static
   * @constant
   */
  static get defaultVertexSrc() {
    return `
attribute vec2 aVertexPosition;
attribute vec2 aTextureCoord;

uniform mat3 projectionMatrix;
uniform mat3 filterMatrix;

varying vec2 vTextureCoord;
varying vec2 vFilterCoord;

void main(void){
  gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);
  vFilterCoord = (filterMatrix * vec3(aTextureCoord, 1.0)).xy;
  vTextureCoord = aTextureCoord;
}
`;
  }

  /**
   * The default fragment shader source
   *
   * @static
   * @constant
   */
  static get defaultFragmentSrc() {
    return `
varying vec2 vTextureCoord;
varying vec2 vFilterCoord;

uniform sampler2D uSampler;
uniform sampler2D filterSampler;

void main(void){
  vec4 masky = texture2D(filterSampler, vFilterCoord);
  vec4 sample = texture2D(uSampler, vTextureCoord);
  vec4 color;
  if(mod(vFilterCoord.x, 1.0) > 0.5) {
    color = vec4(1.0, 0.0, 0.0, 1.0);
  } else {
    color = vec4(0.0, 1.0, 0.0, 1.0);
  }
  gl_FragColor = mix(sample, masky, 0.5);
  gl_FragColor *= sample.a;
}
`;
  }
}
Documentation generated by JSDoc 3.4.3 on Fri Jul 09 2021 19:32:25 GMT+0800 (CST)