{"version":3,"file":"Filter.mjs","sources":["../../src/filters/Filter.ts"],"sourcesContent":["import { MSAA_QUALITY } from '@pixi/constants';\nimport { Program } from '../shader/Program';\nimport { Shader } from '../shader/Shader';\nimport { State } from '../state/State';\nimport defaultFragment from './defaultFilter.frag';\nimport defaultVertex from './defaultFilter.vert';\n\nimport type { BLEND_MODES, CLEAR_MODES } from '@pixi/constants';\nimport type { Dict } from '@pixi/utils';\nimport type { RenderTexture } from '../renderTexture/RenderTexture';\nimport type { FilterState } from './FilterState';\nimport type { FilterSystem } from './FilterSystem';\n\n/**\n * A filter is a special shader that applies post-processing effects to an input texture and writes into an output\n * render-target.\n *\n * {@link https://pixijs.io/examples/#/filters-basic/blur.js Example} of the\n * {@link PIXI.BlurFilter BlurFilter}.\n *\n * ### Usage\n * Filters can be applied to any DisplayObject or Container.\n * PixiJS' `FilterSystem` renders the container into temporary Framebuffer,\n * then filter renders it to the screen.\n * Multiple filters can be added to the `filters` array property and stacked on each other.\n *\n * ```js\n * import { Container, Filter } from 'pixi.js';\n * const filter = new Filter(myShaderVert, myShaderFrag, { myUniform: 0.5 });\n * const container = new Container();\n * container.filters = [filter];\n * ```\n *\n * ### Previous Version Differences\n *\n * In PixiJS **v3**, a filter was always applied to _whole screen_.\n *\n * In PixiJS **v4**, a filter can be applied _only part of the screen_.\n * Developers had to create a set of uniforms to deal with coordinates.\n *\n * In PixiJS **v5** combines _both approaches_.\n * Developers can use normal coordinates of v3 and then allow filter to use partial Framebuffers,\n * bringing those extra uniforms into account.\n *\n * Also be aware that we have changed default vertex shader, please consult\n * {@link https://github.com/pixijs/pixijs/wiki/v5-Creating-filters Wiki}.\n *\n * ### Frames\n *\n * The following table summarizes the coordinate spaces used in the filtering pipeline:\n *\n * <table>\n * <thead>\n *   <tr>\n *     <th>Coordinate Space</th>\n *     <th>Description</th>\n *   </tr>\n * </thead>\n * <tbody>\n *   <tr>\n *     <td>Texture Coordinates</td>\n *     <td>\n *         The texture (or UV) coordinates in the input base-texture's space. These are normalized into the (0,1) range along\n *         both axes.\n *     </td>\n *   </tr>\n *   <tr>\n *     <td>World Space</td>\n *     <td>\n *         A point in the same space as the world bounds of any display-object (i.e. in the scene graph's space).\n *     </td>\n *   </tr>\n *   <tr>\n *     <td>Physical Pixels</td>\n *     <td>\n *         This is base-texture's space with the origin on the top-left. You can calculate these by multiplying the texture\n *         coordinates by the dimensions of the texture.\n *     </td>\n *   </tr>\n * </tbody>\n * </table>\n *\n * ### Built-in Uniforms\n *\n * PixiJS viewport uses screen (CSS) coordinates, `(0, 0, renderer.screen.width, renderer.screen.height)`,\n * and `projectionMatrix` uniform maps it to the gl viewport.\n *\n * **uSampler**\n *\n * The most important uniform is the input texture that container was rendered into.\n * _Important note: as with all Framebuffers in PixiJS, both input and output are\n * premultiplied by alpha._\n *\n * By default, input normalized coordinates are passed to fragment shader with `vTextureCoord`.\n * Use it to sample the input.\n *\n * ```js\n * import { Filter } from 'pixi.js';\n * const fragment = `\n * varying vec2 vTextureCoord;\n * uniform sampler2D uSampler;\n * void main(void)\n * {\n *    gl_FragColor = texture2D(uSampler, vTextureCoord);\n * }\n * `;\n *\n * const myFilter = new Filter(null, fragment);\n * ```\n *\n * This filter is just one uniform less than {@link PIXI.AlphaFilter AlphaFilter}.\n *\n * **outputFrame**\n *\n * The `outputFrame` holds the rectangle where filter is applied in screen (CSS) coordinates.\n * It's the same as `renderer.screen` for a fullscreen filter.\n * Only a part of  `outputFrame.zw` size of temporary Framebuffer is used,\n * `(0, 0, outputFrame.width, outputFrame.height)`,\n *\n * Filters uses this quad to normalized (0-1) space, its passed into `aVertexPosition` attribute.\n * To calculate vertex position in screen space using normalized (0-1) space:\n *\n * ```glsl\n * vec4 filterVertexPosition( void )\n * {\n *     vec2 position = aVertexPosition * max(outputFrame.zw, vec2(0.)) + outputFrame.xy;\n *     return vec4((projectionMatrix * vec3(position, 1.0)).xy, 0.0, 1.0);\n * }\n * ```\n *\n * **inputSize**\n *\n * Temporary framebuffer is different, it can be either the size of screen, either power-of-two.\n * The `inputSize.xy` are size of temporary framebuffer that holds input.\n * The `inputSize.zw` is inverted, it's a shortcut to evade division inside the shader.\n *\n * Set `inputSize.xy = outputFrame.zw` for a fullscreen filter.\n *\n * To calculate input normalized coordinate, you have to map it to filter normalized space.\n * Multiply by `outputFrame.zw` to get input coordinate.\n * Divide by `inputSize.xy` to get input normalized coordinate.\n *\n * ```glsl\n * vec2 filterTextureCoord( void )\n * {\n *     return aVertexPosition * (outputFrame.zw * inputSize.zw); // same as /inputSize.xy\n * }\n * ```\n *\n * **resolution**\n *\n * The `resolution` is the ratio of screen (CSS) pixels to real pixels.\n *\n * **inputPixel**\n *\n * `inputPixel.xy` is the size of framebuffer in real pixels, same as `inputSize.xy * resolution`\n * `inputPixel.zw` is inverted `inputPixel.xy`.\n *\n * It's handy for filters that use neighbour pixels, like {@link PIXI.FXAAFilter FXAAFilter}.\n *\n * **inputClamp**\n *\n * If you try to get info from outside of used part of Framebuffer - you'll get undefined behaviour.\n * For displacements, coordinates has to be clamped.\n *\n * The `inputClamp.xy` is left-top pixel center, you may ignore it, because we use left-top part of Framebuffer\n * `inputClamp.zw` is bottom-right pixel center.\n *\n * ```glsl\n * vec4 color = texture2D(uSampler, clamp(modifiedTextureCoord, inputClamp.xy, inputClamp.zw));\n * ```\n *\n * Or:\n *\n * ```glsl\n * vec4 color = texture2D(uSampler, min(modifigedTextureCoord, inputClamp.zw));\n * ```\n *\n * ### Additional Information\n *\n * Complete documentation on Filter usage is located in the\n * {@link https://github.com/pixijs/pixijs/wiki/v5-Creating-filters Wiki}.\n *\n * Since PixiJS only had a handful of built-in filters, additional filters can be downloaded\n * {@link https://github.com/pixijs/pixi-filters here} from the PixiJS Filters repository.\n * @memberof PIXI\n */\nexport class Filter extends Shader\n{\n    /**\n     * Default filter resolution for any filter.\n     * @static\n     */\n    public static defaultResolution = 1;\n\n    /**\n     * Default filter samples for any filter.\n     * @static\n     * @type {PIXI.MSAA_QUALITY}\n     * @default PIXI.MSAA_QUALITY.NONE\n     */\n    public static defaultMultisample = MSAA_QUALITY.NONE;\n\n    /**\n     * The padding of the filter. Some filters require extra space to breath such as a blur.\n     * Increasing this will add extra width and height to the bounds of the object that the\n     * filter is applied to.\n     */\n    public padding: number;\n\n    /** The samples override of the filter instance. */\n    public multisample: MSAA_QUALITY;\n\n    /** If enabled is true the filter is applied, if false it will not. */\n    public enabled: boolean;\n\n    /**\n     * If enabled, PixiJS will fit the filter area into boundaries for better performance.\n     * Switch it off if it does not work for specific shader.\n     * @default true\n     */\n    public autoFit: boolean;\n\n    /**\n     * Legacy filters use position and uvs from attributes (set by filter system)\n     * @readonly\n     */\n    public legacy: boolean;\n\n    /** The WebGL state the filter requires to render. */\n    state: State;\n\n    protected _resolution: number;\n\n    /**\n     * @param vertexSrc - The source of the vertex shader.\n     * @param fragmentSrc - The source of the fragment shader.\n     * @param uniforms - Custom uniforms to use to augment the built-in ones.\n     */\n    constructor(vertexSrc?: string, fragmentSrc?: string, uniforms?: Dict<any>)\n    {\n        const program = Program.from(vertexSrc || Filter.defaultVertexSrc,\n            fragmentSrc || Filter.defaultFragmentSrc);\n\n        super(program, uniforms);\n\n        this.padding = 0;\n        this.resolution = Filter.defaultResolution;\n        this.multisample = Filter.defaultMultisample;\n        this.enabled = true;\n        this.autoFit = true;\n        this.state = new State();\n    }\n\n    /**\n     * Applies the filter\n     * @param {PIXI.FilterSystem} filterManager - The renderer to retrieve the filter from\n     * @param {PIXI.RenderTexture} input - The input render target.\n     * @param {PIXI.RenderTexture} output - The target to output to.\n     * @param {PIXI.CLEAR_MODES} [clearMode] - Should the output be cleared before rendering to it.\n     * @param {object} [_currentState] - It's current state of filter.\n     *        There are some useful properties in the currentState :\n     *        target, filters, sourceFrame, destinationFrame, renderTarget, resolution\n     */\n    apply(filterManager: FilterSystem, input: RenderTexture, output: RenderTexture, clearMode?: CLEAR_MODES,\n        _currentState?: FilterState): void\n    {\n        // Do as you please!\n\n        filterManager.applyFilter(this, input, output, clearMode);\n\n        // Or just do a regular render..\n    }\n\n    /**\n     * Sets the blend mode of the filter.\n     * @default PIXI.BLEND_MODES.NORMAL\n     */\n    get blendMode(): BLEND_MODES\n    {\n        return this.state.blendMode;\n    }\n\n    set blendMode(value: BLEND_MODES)\n    {\n        this.state.blendMode = value;\n    }\n\n    /**\n     * The resolution of the filter. Setting this to be lower will lower the quality but\n     * increase the performance of the filter.\n     */\n    get resolution(): number\n    {\n        return this._resolution;\n    }\n\n    set resolution(value: number)\n    {\n        this._resolution = value;\n    }\n\n    /**\n     * The default vertex shader source\n     * @readonly\n     */\n    static get defaultVertexSrc(): string\n    {\n        return defaultVertex;\n    }\n\n    /**\n     * The default fragment shader source\n     * @readonly\n     */\n    static get defaultFragmentSrc(): string\n    {\n        return defaultFragment;\n    }\n\n    /** Used for caching shader IDs. */\n    static SOURCE_KEY_MAP: Dict<string>;\n}\n"],"names":[],"mappings":";;;;;;;AA2LO,MAAM,OAAA,GAAN,cAAqB,MAC5B,CAAA;AAAA,EAmDI,WAAA,CAAY,SAAoB,EAAA,WAAA,EAAsB,QACtD,EAAA;AACI,IAAM,MAAA,OAAA,GAAU,QAAQ,IAAK,CAAA,SAAA,IAAa,QAAO,gBAC7C,EAAA,WAAA,IAAe,QAAO,kBAAkB,CAAA,CAAA;AAE5C,IAAA,KAAA,CAAM,SAAS,QAAQ,CAAA,CAAA;AAEvB,IAAA,IAAA,CAAK,OAAU,GAAA,CAAA,CAAA;AACf,IAAA,IAAA,CAAK,aAAa,OAAO,CAAA,iBAAA,CAAA;AACzB,IAAA,IAAA,CAAK,cAAc,OAAO,CAAA,kBAAA,CAAA;AAC1B,IAAA,IAAA,CAAK,OAAU,GAAA,IAAA,CAAA;AACf,IAAA,IAAA,CAAK,OAAU,GAAA,IAAA,CAAA;AACf,IAAK,IAAA,CAAA,KAAA,GAAQ,IAAI,KAAM,EAAA,CAAA;AAAA,GAC3B;AAAA,EAYA,KAAM,CAAA,aAAA,EAA6B,KAAsB,EAAA,MAAA,EAAuB,WAC5E,aACJ,EAAA;AAGI,IAAA,aAAA,CAAc,WAAY,CAAA,IAAA,EAAM,KAAO,EAAA,MAAA,EAAQ,SAAS,CAAA,CAAA;AAAA,GAG5D;AAAA,EAMA,IAAI,SACJ,GAAA;AACI,IAAA,OAAO,KAAK,KAAM,CAAA,SAAA,CAAA;AAAA,GACtB;AAAA,EAEA,IAAI,UAAU,KACd,EAAA;AACI,IAAA,IAAA,CAAK,MAAM,SAAY,GAAA,KAAA,CAAA;AAAA,GAC3B;AAAA,EAMA,IAAI,UACJ,GAAA;AACI,IAAA,OAAO,IAAK,CAAA,WAAA,CAAA;AAAA,GAChB;AAAA,EAEA,IAAI,WAAW,KACf,EAAA;AACI,IAAA,IAAA,CAAK,WAAc,GAAA,KAAA,CAAA;AAAA,GACvB;AAAA,EAMA,WAAW,gBACX,GAAA;AACI,IAAO,OAAA,aAAA,CAAA;AAAA,GACX;AAAA,EAMA,WAAW,kBACX,GAAA;AACI,IAAO,OAAA,eAAA,CAAA;AAAA,GACX;AAIJ,CAAA,CAAA;AAvIO,IAAM,MAAN,GAAA,QAAA;AAAM,OAMK,iBAAoB,GAAA,CAAA,CAAA;AAQlC,MAdS,CAcK,qBAAqB,YAAa,CAAA,IAAA;;;;"}