diff --git a/bundles/pixi.js/src/deprecated.js b/bundles/pixi.js/src/deprecated.js index 4bf8beb..9e30b01 100644 --- a/bundles/pixi.js/src/deprecated.js +++ b/bundles/pixi.js/src/deprecated.js @@ -787,4 +787,41 @@ }, }, }); + + /** + * @class BlurXFilter + * @memberof PIXI.filters + * @deprecated since 5.0.0 + * @see PIXI.filters.BlurFilterPass + */ + class BlurXFilter extends PIXI.filters.BlurFilterPass + { + constructor(strength, quality, resolution, kernelSize) + { + warn('PIXI.filters.BlurXFilter is deprecated, use PIXI.filters.BlurFilterPass'); + + super(true, strength, quality, resolution, kernelSize); + } + } + + /** + * @class BlurYFilter + * @memberof PIXI.filters + * @deprecated since 5.0.0 + * @see PIXI.filters.BlurFilterPass + */ + class BlurYFilter extends PIXI.filters.BlurFilterPass + { + constructor(strength, quality, resolution, kernelSize) + { + warn('PIXI.filters.BlurYFilter is deprecated, use PIXI.filters.BlurFilterPass'); + + super(false, strength, quality, resolution, kernelSize); + } + } + + Object.assign(PIXI.filters, { + BlurXFilter, + BlurYFilter, + }); } diff --git a/bundles/pixi.js/src/deprecated.js b/bundles/pixi.js/src/deprecated.js index 4bf8beb..9e30b01 100644 --- a/bundles/pixi.js/src/deprecated.js +++ b/bundles/pixi.js/src/deprecated.js @@ -787,4 +787,41 @@ }, }, }); + + /** + * @class BlurXFilter + * @memberof PIXI.filters + * @deprecated since 5.0.0 + * @see PIXI.filters.BlurFilterPass + */ + class BlurXFilter extends PIXI.filters.BlurFilterPass + { + constructor(strength, quality, resolution, kernelSize) + { + warn('PIXI.filters.BlurXFilter is deprecated, use PIXI.filters.BlurFilterPass'); + + super(true, strength, quality, resolution, kernelSize); + } + } + + /** + * @class BlurYFilter + * @memberof PIXI.filters + * @deprecated since 5.0.0 + * @see PIXI.filters.BlurFilterPass + */ + class BlurYFilter extends PIXI.filters.BlurFilterPass + { + constructor(strength, quality, resolution, kernelSize) + { + warn('PIXI.filters.BlurYFilter is deprecated, use PIXI.filters.BlurFilterPass'); + + super(false, strength, quality, resolution, kernelSize); + } + } + + Object.assign(PIXI.filters, { + BlurXFilter, + BlurYFilter, + }); } diff --git a/bundles/pixi.js/src/index.js b/bundles/pixi.js/src/index.js index fb839a0..262b0b1 100644 --- a/bundles/pixi.js/src/index.js +++ b/bundles/pixi.js/src/index.js @@ -21,7 +21,7 @@ import * as utils from '@pixi/utils'; import { settings } from '@pixi/settings'; import { AlphaFilter } from '@pixi/filter-alpha'; -import { BlurFilter, BlurXFilter, BlurYFilter } from '@pixi/filter-blur'; +import { BlurFilter, BlurFilterPass } from '@pixi/filter-blur'; import { ColorMatrixFilter } from '@pixi/filter-color-matrix'; import { DisplacementFilter } from '@pixi/filter-displacement'; import { FXAAFilter } from '@pixi/filter-fxaa'; @@ -88,8 +88,7 @@ const filters = { AlphaFilter, BlurFilter, - BlurXFilter, - BlurYFilter, + BlurFilterPass, ColorMatrixFilter, DisplacementFilter, FXAAFilter, diff --git a/bundles/pixi.js/src/deprecated.js b/bundles/pixi.js/src/deprecated.js index 4bf8beb..9e30b01 100644 --- a/bundles/pixi.js/src/deprecated.js +++ b/bundles/pixi.js/src/deprecated.js @@ -787,4 +787,41 @@ }, }, }); + + /** + * @class BlurXFilter + * @memberof PIXI.filters + * @deprecated since 5.0.0 + * @see PIXI.filters.BlurFilterPass + */ + class BlurXFilter extends PIXI.filters.BlurFilterPass + { + constructor(strength, quality, resolution, kernelSize) + { + warn('PIXI.filters.BlurXFilter is deprecated, use PIXI.filters.BlurFilterPass'); + + super(true, strength, quality, resolution, kernelSize); + } + } + + /** + * @class BlurYFilter + * @memberof PIXI.filters + * @deprecated since 5.0.0 + * @see PIXI.filters.BlurFilterPass + */ + class BlurYFilter extends PIXI.filters.BlurFilterPass + { + constructor(strength, quality, resolution, kernelSize) + { + warn('PIXI.filters.BlurYFilter is deprecated, use PIXI.filters.BlurFilterPass'); + + super(false, strength, quality, resolution, kernelSize); + } + } + + Object.assign(PIXI.filters, { + BlurXFilter, + BlurYFilter, + }); } diff --git a/bundles/pixi.js/src/index.js b/bundles/pixi.js/src/index.js index fb839a0..262b0b1 100644 --- a/bundles/pixi.js/src/index.js +++ b/bundles/pixi.js/src/index.js @@ -21,7 +21,7 @@ import * as utils from '@pixi/utils'; import { settings } from '@pixi/settings'; import { AlphaFilter } from '@pixi/filter-alpha'; -import { BlurFilter, BlurXFilter, BlurYFilter } from '@pixi/filter-blur'; +import { BlurFilter, BlurFilterPass } from '@pixi/filter-blur'; import { ColorMatrixFilter } from '@pixi/filter-color-matrix'; import { DisplacementFilter } from '@pixi/filter-displacement'; import { FXAAFilter } from '@pixi/filter-fxaa'; @@ -88,8 +88,7 @@ const filters = { AlphaFilter, BlurFilter, - BlurXFilter, - BlurYFilter, + BlurFilterPass, ColorMatrixFilter, DisplacementFilter, FXAAFilter, diff --git a/packages/filters/filter-blur/src/BlurFilter.js b/packages/filters/filter-blur/src/BlurFilter.js index 43906dc..c5bb586 100644 --- a/packages/filters/filter-blur/src/BlurFilter.js +++ b/packages/filters/filter-blur/src/BlurFilter.js @@ -1,7 +1,6 @@ import { Filter } from '@pixi/core'; import { settings } from '@pixi/settings'; -import BlurXFilter from './BlurXFilter'; -import BlurYFilter from './BlurYFilter'; +import BlurFilterPass from './BlurFilterPass'; /** * The BlurFilter applies a Gaussian blur to an object. @@ -23,13 +22,15 @@ { super(); - this.blurXFilter = new BlurXFilter(strength, quality, resolution, kernelSize); - this.blurYFilter = new BlurYFilter(strength, quality, resolution, kernelSize); + this.blurXFilter = new BlurFilterPass(true, strength, quality, resolution, kernelSize); + this.blurYFilter = new BlurFilterPass(false, strength, quality, resolution, kernelSize); - this.padding = 0; + this._padding = 0; this.resolution = resolution || settings.RESOLUTION; this.quality = quality || 4; this.blur = strength || 8; + + this.repeatEdgePixels = false; } /** @@ -41,12 +42,38 @@ */ apply(filterManager, input, output) { - const renderTarget = filterManager.getFilterTexture(true); + const xStrength = Math.abs(this.blurXFilter.strength); + const yStrength = Math.abs(this.blurYFilter.strength); - this.blurXFilter.apply(filterManager, input, renderTarget, true); - this.blurYFilter.apply(filterManager, renderTarget, output, false); + if (xStrength && yStrength) + { + const renderTarget = filterManager.getFilterTexture(true); - filterManager.returnFilterTexture(renderTarget); + this.blurXFilter.apply(filterManager, input, renderTarget, true); + this.blurYFilter.apply(filterManager, renderTarget, output, false); + + filterManager.returnFilterTexture(renderTarget); + } + else if (yStrength) + { + this.blurYFilter.apply(filterManager, input, output, false); + } + else + { + this.blurXFilter.apply(filterManager, input, output, false); + } + } + + updatePadding() + { + if (this._repeatEdgePixels) + { + this.padding = 0; + } + else + { + this.padding = Math.max(Math.abs(this.blurXFilter.strength), Math.abs(this.blurYFilter.strength)) * 2; + } } /** @@ -63,7 +90,7 @@ set blur(value) // eslint-disable-line require-jsdoc { this.blurXFilter.blur = this.blurYFilter.blur = value; - this.padding = Math.max(Math.abs(this.blurXFilter.strength), Math.abs(this.blurYFilter.strength)) * 2; + this.updatePadding(); } /** @@ -96,7 +123,7 @@ set blurX(value) // eslint-disable-line require-jsdoc { this.blurXFilter.blur = value; - this.padding = Math.max(Math.abs(this.blurXFilter.strength), Math.abs(this.blurYFilter.strength)) * 2; + this.updatePadding(); } /** @@ -113,7 +140,7 @@ set blurY(value) // eslint-disable-line require-jsdoc { this.blurYFilter.blur = value; - this.padding = Math.max(Math.abs(this.blurXFilter.strength), Math.abs(this.blurYFilter.strength)) * 2; + this.updatePadding(); } /** @@ -131,4 +158,21 @@ { this.blurYFilter._blendMode = value; } + + /** + * If set to true the edge of the target will be clamped + * + * @member {bool} + * @default false + */ + get repeatEdgePixels() + { + return this._repeatEdgePixels; + } + + set repeatEdgePixels(value) + { + this._repeatEdgePixels = value; + this.updatePadding(); + } } diff --git a/bundles/pixi.js/src/deprecated.js b/bundles/pixi.js/src/deprecated.js index 4bf8beb..9e30b01 100644 --- a/bundles/pixi.js/src/deprecated.js +++ b/bundles/pixi.js/src/deprecated.js @@ -787,4 +787,41 @@ }, }, }); + + /** + * @class BlurXFilter + * @memberof PIXI.filters + * @deprecated since 5.0.0 + * @see PIXI.filters.BlurFilterPass + */ + class BlurXFilter extends PIXI.filters.BlurFilterPass + { + constructor(strength, quality, resolution, kernelSize) + { + warn('PIXI.filters.BlurXFilter is deprecated, use PIXI.filters.BlurFilterPass'); + + super(true, strength, quality, resolution, kernelSize); + } + } + + /** + * @class BlurYFilter + * @memberof PIXI.filters + * @deprecated since 5.0.0 + * @see PIXI.filters.BlurFilterPass + */ + class BlurYFilter extends PIXI.filters.BlurFilterPass + { + constructor(strength, quality, resolution, kernelSize) + { + warn('PIXI.filters.BlurYFilter is deprecated, use PIXI.filters.BlurFilterPass'); + + super(false, strength, quality, resolution, kernelSize); + } + } + + Object.assign(PIXI.filters, { + BlurXFilter, + BlurYFilter, + }); } diff --git a/bundles/pixi.js/src/index.js b/bundles/pixi.js/src/index.js index fb839a0..262b0b1 100644 --- a/bundles/pixi.js/src/index.js +++ b/bundles/pixi.js/src/index.js @@ -21,7 +21,7 @@ import * as utils from '@pixi/utils'; import { settings } from '@pixi/settings'; import { AlphaFilter } from '@pixi/filter-alpha'; -import { BlurFilter, BlurXFilter, BlurYFilter } from '@pixi/filter-blur'; +import { BlurFilter, BlurFilterPass } from '@pixi/filter-blur'; import { ColorMatrixFilter } from '@pixi/filter-color-matrix'; import { DisplacementFilter } from '@pixi/filter-displacement'; import { FXAAFilter } from '@pixi/filter-fxaa'; @@ -88,8 +88,7 @@ const filters = { AlphaFilter, BlurFilter, - BlurXFilter, - BlurYFilter, + BlurFilterPass, ColorMatrixFilter, DisplacementFilter, FXAAFilter, diff --git a/packages/filters/filter-blur/src/BlurFilter.js b/packages/filters/filter-blur/src/BlurFilter.js index 43906dc..c5bb586 100644 --- a/packages/filters/filter-blur/src/BlurFilter.js +++ b/packages/filters/filter-blur/src/BlurFilter.js @@ -1,7 +1,6 @@ import { Filter } from '@pixi/core'; import { settings } from '@pixi/settings'; -import BlurXFilter from './BlurXFilter'; -import BlurYFilter from './BlurYFilter'; +import BlurFilterPass from './BlurFilterPass'; /** * The BlurFilter applies a Gaussian blur to an object. @@ -23,13 +22,15 @@ { super(); - this.blurXFilter = new BlurXFilter(strength, quality, resolution, kernelSize); - this.blurYFilter = new BlurYFilter(strength, quality, resolution, kernelSize); + this.blurXFilter = new BlurFilterPass(true, strength, quality, resolution, kernelSize); + this.blurYFilter = new BlurFilterPass(false, strength, quality, resolution, kernelSize); - this.padding = 0; + this._padding = 0; this.resolution = resolution || settings.RESOLUTION; this.quality = quality || 4; this.blur = strength || 8; + + this.repeatEdgePixels = false; } /** @@ -41,12 +42,38 @@ */ apply(filterManager, input, output) { - const renderTarget = filterManager.getFilterTexture(true); + const xStrength = Math.abs(this.blurXFilter.strength); + const yStrength = Math.abs(this.blurYFilter.strength); - this.blurXFilter.apply(filterManager, input, renderTarget, true); - this.blurYFilter.apply(filterManager, renderTarget, output, false); + if (xStrength && yStrength) + { + const renderTarget = filterManager.getFilterTexture(true); - filterManager.returnFilterTexture(renderTarget); + this.blurXFilter.apply(filterManager, input, renderTarget, true); + this.blurYFilter.apply(filterManager, renderTarget, output, false); + + filterManager.returnFilterTexture(renderTarget); + } + else if (yStrength) + { + this.blurYFilter.apply(filterManager, input, output, false); + } + else + { + this.blurXFilter.apply(filterManager, input, output, false); + } + } + + updatePadding() + { + if (this._repeatEdgePixels) + { + this.padding = 0; + } + else + { + this.padding = Math.max(Math.abs(this.blurXFilter.strength), Math.abs(this.blurYFilter.strength)) * 2; + } } /** @@ -63,7 +90,7 @@ set blur(value) // eslint-disable-line require-jsdoc { this.blurXFilter.blur = this.blurYFilter.blur = value; - this.padding = Math.max(Math.abs(this.blurXFilter.strength), Math.abs(this.blurYFilter.strength)) * 2; + this.updatePadding(); } /** @@ -96,7 +123,7 @@ set blurX(value) // eslint-disable-line require-jsdoc { this.blurXFilter.blur = value; - this.padding = Math.max(Math.abs(this.blurXFilter.strength), Math.abs(this.blurYFilter.strength)) * 2; + this.updatePadding(); } /** @@ -113,7 +140,7 @@ set blurY(value) // eslint-disable-line require-jsdoc { this.blurYFilter.blur = value; - this.padding = Math.max(Math.abs(this.blurXFilter.strength), Math.abs(this.blurYFilter.strength)) * 2; + this.updatePadding(); } /** @@ -131,4 +158,21 @@ { this.blurYFilter._blendMode = value; } + + /** + * If set to true the edge of the target will be clamped + * + * @member {bool} + * @default false + */ + get repeatEdgePixels() + { + return this._repeatEdgePixels; + } + + set repeatEdgePixels(value) + { + this._repeatEdgePixels = value; + this.updatePadding(); + } } diff --git a/packages/filters/filter-blur/src/BlurFilterPass.js b/packages/filters/filter-blur/src/BlurFilterPass.js new file mode 100644 index 0000000..85b030c --- /dev/null +++ b/packages/filters/filter-blur/src/BlurFilterPass.js @@ -0,0 +1,158 @@ +import { Filter } from '@pixi/core'; +import { settings } from '@pixi/settings'; +import generateBlurVertSource from './generateBlurVertSource'; +import generateBlurFragSource from './generateBlurFragSource'; +import getMaxBlurKernelSize from './getMaxBlurKernelSize'; + +/** + * The BlurFilterPass applies a horizontal or vertical Gaussian blur to an object. + * + * @class + * @extends PIXI.Filter + * @memberof PIXI.filters + */ +export default class BlurFilterPass extends Filter +{ + /** + * @param {boolean} horizontal - Do pass along the x-axis (`true`) or y-axis (`false`). + * @param {number} strength - The strength of the blur filter. + * @param {number} quality - The quality of the blur filter. + * @param {number} resolution - The resolution of the blur filter. + * @param {number} [kernelSize=5] - The kernelSize of the blur filter.Options: 5, 7, 9, 11, 13, 15. + */ + constructor(horizontal, strength, quality, resolution, kernelSize) + { + kernelSize = kernelSize || 5; + const vertSrc = generateBlurVertSource(kernelSize, horizontal); + const fragSrc = generateBlurFragSource(kernelSize); + + super( + // vertex shader + vertSrc, + // fragment shader + fragSrc + ); + + this.horizontal = horizontal; + + this.resolution = resolution || settings.RESOLUTION; + + this._quality = 0; + + this.quality = quality || 4; + + this.blur = strength || 8; + + this.firstRun = true; + } + + apply(filterManager, input, output, clear) + { + if (this.firstRun) + { + const gl = filterManager.renderer.gl; + const kernelSize = getMaxBlurKernelSize(gl); + + this.vertexSrc = generateBlurVertSource(kernelSize, true); + this.fragmentSrc = generateBlurFragSource(kernelSize); + + this.firstRun = false; + } + + if (output) + { + if (this.horizontal) + { + this.uniforms.strength = (1 / output.width) * (output.width / input.width); + } + else + { + this.uniforms.strength = (1 / output.height) * (output.height / input.height); + } + } + else + { + if (this.horizontal) // eslint-disable-line + { + this.uniforms.strength = (1 / filterManager.renderer.width) * (filterManager.renderer.width / input.width); + } + else + { + this.uniforms.strength = (1 / filterManager.renderer.height) * (filterManager.renderer.height / input.height); // eslint-disable-line + } + } + + // screen space! + this.uniforms.strength *= this.strength; + this.uniforms.strength /= this.passes; + + if (this.passes === 1) + { + filterManager.applyFilter(this, input, output, clear); + } + else + { + const renderTarget = filterManager.getFilterTexture(); + const renderer = filterManager.renderer; + + let flip = input; + let flop = renderTarget; + + this.state.blend = false; + filterManager.applyFilter(this, flip, flop, false); + + for (let i = 1; i < this.passes - 1; i++) + { + renderer.renderTexture.bind(flip, flip.filterFrame); + + this.uniforms.uSampler = flop; + + const temp = flop; + + flop = flip; + flip = temp; + + renderer.shader.bind(this); + renderer.geometry.draw(5); + } + + this.state.blend = true; + filterManager.applyFilter(this, flop, output, clear); + filterManager.returnFilterTexture(renderTarget); + } + } + /** + * Sets the strength of both the blur. + * + * @member {number} + * @default 16 + */ + get blur() + { + return this.strength; + } + + set blur(value) // eslint-disable-line require-jsdoc + { + this.padding = 1 + (Math.abs(value) * 2); + this.strength = value; + } + + /** + * Sets the quality of the blur by modifying the number of passes. More passes means higher + * quaility bluring but the lower the performance. + * + * @member {number} + * @default 4 + */ + get quality() + { + return this._quality; + } + + set quality(value) // eslint-disable-line require-jsdoc + { + this._quality = value; + this.passes = value; + } +} diff --git a/bundles/pixi.js/src/deprecated.js b/bundles/pixi.js/src/deprecated.js index 4bf8beb..9e30b01 100644 --- a/bundles/pixi.js/src/deprecated.js +++ b/bundles/pixi.js/src/deprecated.js @@ -787,4 +787,41 @@ }, }, }); + + /** + * @class BlurXFilter + * @memberof PIXI.filters + * @deprecated since 5.0.0 + * @see PIXI.filters.BlurFilterPass + */ + class BlurXFilter extends PIXI.filters.BlurFilterPass + { + constructor(strength, quality, resolution, kernelSize) + { + warn('PIXI.filters.BlurXFilter is deprecated, use PIXI.filters.BlurFilterPass'); + + super(true, strength, quality, resolution, kernelSize); + } + } + + /** + * @class BlurYFilter + * @memberof PIXI.filters + * @deprecated since 5.0.0 + * @see PIXI.filters.BlurFilterPass + */ + class BlurYFilter extends PIXI.filters.BlurFilterPass + { + constructor(strength, quality, resolution, kernelSize) + { + warn('PIXI.filters.BlurYFilter is deprecated, use PIXI.filters.BlurFilterPass'); + + super(false, strength, quality, resolution, kernelSize); + } + } + + Object.assign(PIXI.filters, { + BlurXFilter, + BlurYFilter, + }); } diff --git a/bundles/pixi.js/src/index.js b/bundles/pixi.js/src/index.js index fb839a0..262b0b1 100644 --- a/bundles/pixi.js/src/index.js +++ b/bundles/pixi.js/src/index.js @@ -21,7 +21,7 @@ import * as utils from '@pixi/utils'; import { settings } from '@pixi/settings'; import { AlphaFilter } from '@pixi/filter-alpha'; -import { BlurFilter, BlurXFilter, BlurYFilter } from '@pixi/filter-blur'; +import { BlurFilter, BlurFilterPass } from '@pixi/filter-blur'; import { ColorMatrixFilter } from '@pixi/filter-color-matrix'; import { DisplacementFilter } from '@pixi/filter-displacement'; import { FXAAFilter } from '@pixi/filter-fxaa'; @@ -88,8 +88,7 @@ const filters = { AlphaFilter, BlurFilter, - BlurXFilter, - BlurYFilter, + BlurFilterPass, ColorMatrixFilter, DisplacementFilter, FXAAFilter, diff --git a/packages/filters/filter-blur/src/BlurFilter.js b/packages/filters/filter-blur/src/BlurFilter.js index 43906dc..c5bb586 100644 --- a/packages/filters/filter-blur/src/BlurFilter.js +++ b/packages/filters/filter-blur/src/BlurFilter.js @@ -1,7 +1,6 @@ import { Filter } from '@pixi/core'; import { settings } from '@pixi/settings'; -import BlurXFilter from './BlurXFilter'; -import BlurYFilter from './BlurYFilter'; +import BlurFilterPass from './BlurFilterPass'; /** * The BlurFilter applies a Gaussian blur to an object. @@ -23,13 +22,15 @@ { super(); - this.blurXFilter = new BlurXFilter(strength, quality, resolution, kernelSize); - this.blurYFilter = new BlurYFilter(strength, quality, resolution, kernelSize); + this.blurXFilter = new BlurFilterPass(true, strength, quality, resolution, kernelSize); + this.blurYFilter = new BlurFilterPass(false, strength, quality, resolution, kernelSize); - this.padding = 0; + this._padding = 0; this.resolution = resolution || settings.RESOLUTION; this.quality = quality || 4; this.blur = strength || 8; + + this.repeatEdgePixels = false; } /** @@ -41,12 +42,38 @@ */ apply(filterManager, input, output) { - const renderTarget = filterManager.getFilterTexture(true); + const xStrength = Math.abs(this.blurXFilter.strength); + const yStrength = Math.abs(this.blurYFilter.strength); - this.blurXFilter.apply(filterManager, input, renderTarget, true); - this.blurYFilter.apply(filterManager, renderTarget, output, false); + if (xStrength && yStrength) + { + const renderTarget = filterManager.getFilterTexture(true); - filterManager.returnFilterTexture(renderTarget); + this.blurXFilter.apply(filterManager, input, renderTarget, true); + this.blurYFilter.apply(filterManager, renderTarget, output, false); + + filterManager.returnFilterTexture(renderTarget); + } + else if (yStrength) + { + this.blurYFilter.apply(filterManager, input, output, false); + } + else + { + this.blurXFilter.apply(filterManager, input, output, false); + } + } + + updatePadding() + { + if (this._repeatEdgePixels) + { + this.padding = 0; + } + else + { + this.padding = Math.max(Math.abs(this.blurXFilter.strength), Math.abs(this.blurYFilter.strength)) * 2; + } } /** @@ -63,7 +90,7 @@ set blur(value) // eslint-disable-line require-jsdoc { this.blurXFilter.blur = this.blurYFilter.blur = value; - this.padding = Math.max(Math.abs(this.blurXFilter.strength), Math.abs(this.blurYFilter.strength)) * 2; + this.updatePadding(); } /** @@ -96,7 +123,7 @@ set blurX(value) // eslint-disable-line require-jsdoc { this.blurXFilter.blur = value; - this.padding = Math.max(Math.abs(this.blurXFilter.strength), Math.abs(this.blurYFilter.strength)) * 2; + this.updatePadding(); } /** @@ -113,7 +140,7 @@ set blurY(value) // eslint-disable-line require-jsdoc { this.blurYFilter.blur = value; - this.padding = Math.max(Math.abs(this.blurXFilter.strength), Math.abs(this.blurYFilter.strength)) * 2; + this.updatePadding(); } /** @@ -131,4 +158,21 @@ { this.blurYFilter._blendMode = value; } + + /** + * If set to true the edge of the target will be clamped + * + * @member {bool} + * @default false + */ + get repeatEdgePixels() + { + return this._repeatEdgePixels; + } + + set repeatEdgePixels(value) + { + this._repeatEdgePixels = value; + this.updatePadding(); + } } diff --git a/packages/filters/filter-blur/src/BlurFilterPass.js b/packages/filters/filter-blur/src/BlurFilterPass.js new file mode 100644 index 0000000..85b030c --- /dev/null +++ b/packages/filters/filter-blur/src/BlurFilterPass.js @@ -0,0 +1,158 @@ +import { Filter } from '@pixi/core'; +import { settings } from '@pixi/settings'; +import generateBlurVertSource from './generateBlurVertSource'; +import generateBlurFragSource from './generateBlurFragSource'; +import getMaxBlurKernelSize from './getMaxBlurKernelSize'; + +/** + * The BlurFilterPass applies a horizontal or vertical Gaussian blur to an object. + * + * @class + * @extends PIXI.Filter + * @memberof PIXI.filters + */ +export default class BlurFilterPass extends Filter +{ + /** + * @param {boolean} horizontal - Do pass along the x-axis (`true`) or y-axis (`false`). + * @param {number} strength - The strength of the blur filter. + * @param {number} quality - The quality of the blur filter. + * @param {number} resolution - The resolution of the blur filter. + * @param {number} [kernelSize=5] - The kernelSize of the blur filter.Options: 5, 7, 9, 11, 13, 15. + */ + constructor(horizontal, strength, quality, resolution, kernelSize) + { + kernelSize = kernelSize || 5; + const vertSrc = generateBlurVertSource(kernelSize, horizontal); + const fragSrc = generateBlurFragSource(kernelSize); + + super( + // vertex shader + vertSrc, + // fragment shader + fragSrc + ); + + this.horizontal = horizontal; + + this.resolution = resolution || settings.RESOLUTION; + + this._quality = 0; + + this.quality = quality || 4; + + this.blur = strength || 8; + + this.firstRun = true; + } + + apply(filterManager, input, output, clear) + { + if (this.firstRun) + { + const gl = filterManager.renderer.gl; + const kernelSize = getMaxBlurKernelSize(gl); + + this.vertexSrc = generateBlurVertSource(kernelSize, true); + this.fragmentSrc = generateBlurFragSource(kernelSize); + + this.firstRun = false; + } + + if (output) + { + if (this.horizontal) + { + this.uniforms.strength = (1 / output.width) * (output.width / input.width); + } + else + { + this.uniforms.strength = (1 / output.height) * (output.height / input.height); + } + } + else + { + if (this.horizontal) // eslint-disable-line + { + this.uniforms.strength = (1 / filterManager.renderer.width) * (filterManager.renderer.width / input.width); + } + else + { + this.uniforms.strength = (1 / filterManager.renderer.height) * (filterManager.renderer.height / input.height); // eslint-disable-line + } + } + + // screen space! + this.uniforms.strength *= this.strength; + this.uniforms.strength /= this.passes; + + if (this.passes === 1) + { + filterManager.applyFilter(this, input, output, clear); + } + else + { + const renderTarget = filterManager.getFilterTexture(); + const renderer = filterManager.renderer; + + let flip = input; + let flop = renderTarget; + + this.state.blend = false; + filterManager.applyFilter(this, flip, flop, false); + + for (let i = 1; i < this.passes - 1; i++) + { + renderer.renderTexture.bind(flip, flip.filterFrame); + + this.uniforms.uSampler = flop; + + const temp = flop; + + flop = flip; + flip = temp; + + renderer.shader.bind(this); + renderer.geometry.draw(5); + } + + this.state.blend = true; + filterManager.applyFilter(this, flop, output, clear); + filterManager.returnFilterTexture(renderTarget); + } + } + /** + * Sets the strength of both the blur. + * + * @member {number} + * @default 16 + */ + get blur() + { + return this.strength; + } + + set blur(value) // eslint-disable-line require-jsdoc + { + this.padding = 1 + (Math.abs(value) * 2); + this.strength = value; + } + + /** + * Sets the quality of the blur by modifying the number of passes. More passes means higher + * quaility bluring but the lower the performance. + * + * @member {number} + * @default 4 + */ + get quality() + { + return this._quality; + } + + set quality(value) // eslint-disable-line require-jsdoc + { + this._quality = value; + this.passes = value; + } +} diff --git a/packages/filters/filter-blur/src/BlurXFilter.js b/packages/filters/filter-blur/src/BlurXFilter.js deleted file mode 100644 index af46e16..0000000 --- a/packages/filters/filter-blur/src/BlurXFilter.js +++ /dev/null @@ -1,141 +0,0 @@ -import { Filter } from '@pixi/core'; -import { settings } from '@pixi/settings'; -import generateBlurVertSource from './generateBlurVertSource'; -import generateBlurFragSource from './generateBlurFragSource'; -import getMaxBlurKernelSize from './getMaxBlurKernelSize'; - -/** - * The BlurXFilter applies a horizontal Gaussian blur to an object. - * - * @class - * @extends PIXI.Filter - * @memberof PIXI.filters - */ -export default class BlurXFilter extends Filter -{ - /** - * @param {number} strength - The strength of the blur filter. - * @param {number} quality - The quality of the blur filter. - * @param {number} resolution - The resolution of the blur filter. - * @param {number} [kernelSize=5] - The kernelSize of the blur filter.Options: 5, 7, 9, 11, 13, 15. - */ - constructor(strength, quality, resolution, kernelSize) - { - kernelSize = kernelSize || 5; - const vertSrc = generateBlurVertSource(kernelSize, true); - const fragSrc = generateBlurFragSource(kernelSize); - - super( - // vertex shader - vertSrc, - // fragment shader - fragSrc - ); - - this.resolution = resolution || settings.RESOLUTION; - - this._quality = 0; - - this.quality = quality || 4; - - this.blur = strength || 8; - - this.firstRun = true; - } - - apply(filterManager, input, output, clear) - { - if (this.firstRun) - { - const gl = filterManager.renderer.gl; - const kernelSize = getMaxBlurKernelSize(gl); - - this.vertexSrc = generateBlurVertSource(kernelSize, true); - this.fragmentSrc = generateBlurFragSource(kernelSize); - - this.firstRun = false; - } - - if (output) - { - this.uniforms.strength = (1 / output.width) * (output.width / input.width); - } - else - { - this.uniforms.strength = (1 / filterManager.renderer.width) * (filterManager.renderer.width / input.width); - } - - // screen space! - this.uniforms.strength *= this.strength; - this.uniforms.strength /= this.passes; - - if (this.passes === 1) - { - filterManager.applyFilter(this, input, output, clear); - } - else - { - const renderTarget = filterManager.getFilterTexture(); - const renderer = filterManager.renderer; - - let flip = input; - let flop = renderTarget; - - this.state.blend = false; - filterManager.applyFilter(this, flip, flop, false); - - for (let i = 1; i < this.passes - 1; i++) - { - renderer.renderTexture.bind(flip, flip.filterFrame); - - this.uniforms.uSampler = flop; - - const temp = flop; - - flop = flip; - flip = temp; - - renderer.shader.bind(this); - renderer.geometry.draw(5); - } - - this.state.blend = true; - filterManager.applyFilter(this, flop, output, clear); - filterManager.returnFilterTexture(renderTarget); - } - } - /** - * Sets the strength of both the blur. - * - * @member {number} - * @default 16 - */ - get blur() - { - return this.strength; - } - - set blur(value) // eslint-disable-line require-jsdoc - { - this.padding = 1 + (Math.abs(value) * 2); - this.strength = value; - } - - /** - * Sets the quality of the blur by modifying the number of passes. More passes means higher - * quaility bluring but the lower the performance. - * - * @member {number} - * @default 4 - */ - get quality() - { - return this._quality; - } - - set quality(value) // eslint-disable-line require-jsdoc - { - this._quality = value; - this.passes = value; - } -} diff --git a/bundles/pixi.js/src/deprecated.js b/bundles/pixi.js/src/deprecated.js index 4bf8beb..9e30b01 100644 --- a/bundles/pixi.js/src/deprecated.js +++ b/bundles/pixi.js/src/deprecated.js @@ -787,4 +787,41 @@ }, }, }); + + /** + * @class BlurXFilter + * @memberof PIXI.filters + * @deprecated since 5.0.0 + * @see PIXI.filters.BlurFilterPass + */ + class BlurXFilter extends PIXI.filters.BlurFilterPass + { + constructor(strength, quality, resolution, kernelSize) + { + warn('PIXI.filters.BlurXFilter is deprecated, use PIXI.filters.BlurFilterPass'); + + super(true, strength, quality, resolution, kernelSize); + } + } + + /** + * @class BlurYFilter + * @memberof PIXI.filters + * @deprecated since 5.0.0 + * @see PIXI.filters.BlurFilterPass + */ + class BlurYFilter extends PIXI.filters.BlurFilterPass + { + constructor(strength, quality, resolution, kernelSize) + { + warn('PIXI.filters.BlurYFilter is deprecated, use PIXI.filters.BlurFilterPass'); + + super(false, strength, quality, resolution, kernelSize); + } + } + + Object.assign(PIXI.filters, { + BlurXFilter, + BlurYFilter, + }); } diff --git a/bundles/pixi.js/src/index.js b/bundles/pixi.js/src/index.js index fb839a0..262b0b1 100644 --- a/bundles/pixi.js/src/index.js +++ b/bundles/pixi.js/src/index.js @@ -21,7 +21,7 @@ import * as utils from '@pixi/utils'; import { settings } from '@pixi/settings'; import { AlphaFilter } from '@pixi/filter-alpha'; -import { BlurFilter, BlurXFilter, BlurYFilter } from '@pixi/filter-blur'; +import { BlurFilter, BlurFilterPass } from '@pixi/filter-blur'; import { ColorMatrixFilter } from '@pixi/filter-color-matrix'; import { DisplacementFilter } from '@pixi/filter-displacement'; import { FXAAFilter } from '@pixi/filter-fxaa'; @@ -88,8 +88,7 @@ const filters = { AlphaFilter, BlurFilter, - BlurXFilter, - BlurYFilter, + BlurFilterPass, ColorMatrixFilter, DisplacementFilter, FXAAFilter, diff --git a/packages/filters/filter-blur/src/BlurFilter.js b/packages/filters/filter-blur/src/BlurFilter.js index 43906dc..c5bb586 100644 --- a/packages/filters/filter-blur/src/BlurFilter.js +++ b/packages/filters/filter-blur/src/BlurFilter.js @@ -1,7 +1,6 @@ import { Filter } from '@pixi/core'; import { settings } from '@pixi/settings'; -import BlurXFilter from './BlurXFilter'; -import BlurYFilter from './BlurYFilter'; +import BlurFilterPass from './BlurFilterPass'; /** * The BlurFilter applies a Gaussian blur to an object. @@ -23,13 +22,15 @@ { super(); - this.blurXFilter = new BlurXFilter(strength, quality, resolution, kernelSize); - this.blurYFilter = new BlurYFilter(strength, quality, resolution, kernelSize); + this.blurXFilter = new BlurFilterPass(true, strength, quality, resolution, kernelSize); + this.blurYFilter = new BlurFilterPass(false, strength, quality, resolution, kernelSize); - this.padding = 0; + this._padding = 0; this.resolution = resolution || settings.RESOLUTION; this.quality = quality || 4; this.blur = strength || 8; + + this.repeatEdgePixels = false; } /** @@ -41,12 +42,38 @@ */ apply(filterManager, input, output) { - const renderTarget = filterManager.getFilterTexture(true); + const xStrength = Math.abs(this.blurXFilter.strength); + const yStrength = Math.abs(this.blurYFilter.strength); - this.blurXFilter.apply(filterManager, input, renderTarget, true); - this.blurYFilter.apply(filterManager, renderTarget, output, false); + if (xStrength && yStrength) + { + const renderTarget = filterManager.getFilterTexture(true); - filterManager.returnFilterTexture(renderTarget); + this.blurXFilter.apply(filterManager, input, renderTarget, true); + this.blurYFilter.apply(filterManager, renderTarget, output, false); + + filterManager.returnFilterTexture(renderTarget); + } + else if (yStrength) + { + this.blurYFilter.apply(filterManager, input, output, false); + } + else + { + this.blurXFilter.apply(filterManager, input, output, false); + } + } + + updatePadding() + { + if (this._repeatEdgePixels) + { + this.padding = 0; + } + else + { + this.padding = Math.max(Math.abs(this.blurXFilter.strength), Math.abs(this.blurYFilter.strength)) * 2; + } } /** @@ -63,7 +90,7 @@ set blur(value) // eslint-disable-line require-jsdoc { this.blurXFilter.blur = this.blurYFilter.blur = value; - this.padding = Math.max(Math.abs(this.blurXFilter.strength), Math.abs(this.blurYFilter.strength)) * 2; + this.updatePadding(); } /** @@ -96,7 +123,7 @@ set blurX(value) // eslint-disable-line require-jsdoc { this.blurXFilter.blur = value; - this.padding = Math.max(Math.abs(this.blurXFilter.strength), Math.abs(this.blurYFilter.strength)) * 2; + this.updatePadding(); } /** @@ -113,7 +140,7 @@ set blurY(value) // eslint-disable-line require-jsdoc { this.blurYFilter.blur = value; - this.padding = Math.max(Math.abs(this.blurXFilter.strength), Math.abs(this.blurYFilter.strength)) * 2; + this.updatePadding(); } /** @@ -131,4 +158,21 @@ { this.blurYFilter._blendMode = value; } + + /** + * If set to true the edge of the target will be clamped + * + * @member {bool} + * @default false + */ + get repeatEdgePixels() + { + return this._repeatEdgePixels; + } + + set repeatEdgePixels(value) + { + this._repeatEdgePixels = value; + this.updatePadding(); + } } diff --git a/packages/filters/filter-blur/src/BlurFilterPass.js b/packages/filters/filter-blur/src/BlurFilterPass.js new file mode 100644 index 0000000..85b030c --- /dev/null +++ b/packages/filters/filter-blur/src/BlurFilterPass.js @@ -0,0 +1,158 @@ +import { Filter } from '@pixi/core'; +import { settings } from '@pixi/settings'; +import generateBlurVertSource from './generateBlurVertSource'; +import generateBlurFragSource from './generateBlurFragSource'; +import getMaxBlurKernelSize from './getMaxBlurKernelSize'; + +/** + * The BlurFilterPass applies a horizontal or vertical Gaussian blur to an object. + * + * @class + * @extends PIXI.Filter + * @memberof PIXI.filters + */ +export default class BlurFilterPass extends Filter +{ + /** + * @param {boolean} horizontal - Do pass along the x-axis (`true`) or y-axis (`false`). + * @param {number} strength - The strength of the blur filter. + * @param {number} quality - The quality of the blur filter. + * @param {number} resolution - The resolution of the blur filter. + * @param {number} [kernelSize=5] - The kernelSize of the blur filter.Options: 5, 7, 9, 11, 13, 15. + */ + constructor(horizontal, strength, quality, resolution, kernelSize) + { + kernelSize = kernelSize || 5; + const vertSrc = generateBlurVertSource(kernelSize, horizontal); + const fragSrc = generateBlurFragSource(kernelSize); + + super( + // vertex shader + vertSrc, + // fragment shader + fragSrc + ); + + this.horizontal = horizontal; + + this.resolution = resolution || settings.RESOLUTION; + + this._quality = 0; + + this.quality = quality || 4; + + this.blur = strength || 8; + + this.firstRun = true; + } + + apply(filterManager, input, output, clear) + { + if (this.firstRun) + { + const gl = filterManager.renderer.gl; + const kernelSize = getMaxBlurKernelSize(gl); + + this.vertexSrc = generateBlurVertSource(kernelSize, true); + this.fragmentSrc = generateBlurFragSource(kernelSize); + + this.firstRun = false; + } + + if (output) + { + if (this.horizontal) + { + this.uniforms.strength = (1 / output.width) * (output.width / input.width); + } + else + { + this.uniforms.strength = (1 / output.height) * (output.height / input.height); + } + } + else + { + if (this.horizontal) // eslint-disable-line + { + this.uniforms.strength = (1 / filterManager.renderer.width) * (filterManager.renderer.width / input.width); + } + else + { + this.uniforms.strength = (1 / filterManager.renderer.height) * (filterManager.renderer.height / input.height); // eslint-disable-line + } + } + + // screen space! + this.uniforms.strength *= this.strength; + this.uniforms.strength /= this.passes; + + if (this.passes === 1) + { + filterManager.applyFilter(this, input, output, clear); + } + else + { + const renderTarget = filterManager.getFilterTexture(); + const renderer = filterManager.renderer; + + let flip = input; + let flop = renderTarget; + + this.state.blend = false; + filterManager.applyFilter(this, flip, flop, false); + + for (let i = 1; i < this.passes - 1; i++) + { + renderer.renderTexture.bind(flip, flip.filterFrame); + + this.uniforms.uSampler = flop; + + const temp = flop; + + flop = flip; + flip = temp; + + renderer.shader.bind(this); + renderer.geometry.draw(5); + } + + this.state.blend = true; + filterManager.applyFilter(this, flop, output, clear); + filterManager.returnFilterTexture(renderTarget); + } + } + /** + * Sets the strength of both the blur. + * + * @member {number} + * @default 16 + */ + get blur() + { + return this.strength; + } + + set blur(value) // eslint-disable-line require-jsdoc + { + this.padding = 1 + (Math.abs(value) * 2); + this.strength = value; + } + + /** + * Sets the quality of the blur by modifying the number of passes. More passes means higher + * quaility bluring but the lower the performance. + * + * @member {number} + * @default 4 + */ + get quality() + { + return this._quality; + } + + set quality(value) // eslint-disable-line require-jsdoc + { + this._quality = value; + this.passes = value; + } +} diff --git a/packages/filters/filter-blur/src/BlurXFilter.js b/packages/filters/filter-blur/src/BlurXFilter.js deleted file mode 100644 index af46e16..0000000 --- a/packages/filters/filter-blur/src/BlurXFilter.js +++ /dev/null @@ -1,141 +0,0 @@ -import { Filter } from '@pixi/core'; -import { settings } from '@pixi/settings'; -import generateBlurVertSource from './generateBlurVertSource'; -import generateBlurFragSource from './generateBlurFragSource'; -import getMaxBlurKernelSize from './getMaxBlurKernelSize'; - -/** - * The BlurXFilter applies a horizontal Gaussian blur to an object. - * - * @class - * @extends PIXI.Filter - * @memberof PIXI.filters - */ -export default class BlurXFilter extends Filter -{ - /** - * @param {number} strength - The strength of the blur filter. - * @param {number} quality - The quality of the blur filter. - * @param {number} resolution - The resolution of the blur filter. - * @param {number} [kernelSize=5] - The kernelSize of the blur filter.Options: 5, 7, 9, 11, 13, 15. - */ - constructor(strength, quality, resolution, kernelSize) - { - kernelSize = kernelSize || 5; - const vertSrc = generateBlurVertSource(kernelSize, true); - const fragSrc = generateBlurFragSource(kernelSize); - - super( - // vertex shader - vertSrc, - // fragment shader - fragSrc - ); - - this.resolution = resolution || settings.RESOLUTION; - - this._quality = 0; - - this.quality = quality || 4; - - this.blur = strength || 8; - - this.firstRun = true; - } - - apply(filterManager, input, output, clear) - { - if (this.firstRun) - { - const gl = filterManager.renderer.gl; - const kernelSize = getMaxBlurKernelSize(gl); - - this.vertexSrc = generateBlurVertSource(kernelSize, true); - this.fragmentSrc = generateBlurFragSource(kernelSize); - - this.firstRun = false; - } - - if (output) - { - this.uniforms.strength = (1 / output.width) * (output.width / input.width); - } - else - { - this.uniforms.strength = (1 / filterManager.renderer.width) * (filterManager.renderer.width / input.width); - } - - // screen space! - this.uniforms.strength *= this.strength; - this.uniforms.strength /= this.passes; - - if (this.passes === 1) - { - filterManager.applyFilter(this, input, output, clear); - } - else - { - const renderTarget = filterManager.getFilterTexture(); - const renderer = filterManager.renderer; - - let flip = input; - let flop = renderTarget; - - this.state.blend = false; - filterManager.applyFilter(this, flip, flop, false); - - for (let i = 1; i < this.passes - 1; i++) - { - renderer.renderTexture.bind(flip, flip.filterFrame); - - this.uniforms.uSampler = flop; - - const temp = flop; - - flop = flip; - flip = temp; - - renderer.shader.bind(this); - renderer.geometry.draw(5); - } - - this.state.blend = true; - filterManager.applyFilter(this, flop, output, clear); - filterManager.returnFilterTexture(renderTarget); - } - } - /** - * Sets the strength of both the blur. - * - * @member {number} - * @default 16 - */ - get blur() - { - return this.strength; - } - - set blur(value) // eslint-disable-line require-jsdoc - { - this.padding = 1 + (Math.abs(value) * 2); - this.strength = value; - } - - /** - * Sets the quality of the blur by modifying the number of passes. More passes means higher - * quaility bluring but the lower the performance. - * - * @member {number} - * @default 4 - */ - get quality() - { - return this._quality; - } - - set quality(value) // eslint-disable-line require-jsdoc - { - this._quality = value; - this.passes = value; - } -} diff --git a/packages/filters/filter-blur/src/BlurYFilter.js b/packages/filters/filter-blur/src/BlurYFilter.js deleted file mode 100644 index 2d337a4..0000000 --- a/packages/filters/filter-blur/src/BlurYFilter.js +++ /dev/null @@ -1,158 +0,0 @@ -import { Filter } from '@pixi/core'; -import { settings } from '@pixi/settings'; -import generateBlurVertSource from './generateBlurVertSource'; -import generateBlurFragSource from './generateBlurFragSource'; -import getMaxBlurKernelSize from './getMaxBlurKernelSize'; - -/** - * The BlurYFilter applies a horizontal Gaussian blur to an object. - * - * @class - * @extends PIXI.Filter - * @memberof PIXI.filters - */ -export default class BlurYFilter extends Filter -{ - /** - * @param {number} strength - The strength of the blur filter. - * @param {number} quality - The quality of the blur filter. - * @param {number} resolution - The resolution of the blur filter. - * @param {number} [kernelSize=5] - The kernelSize of the blur filter.Options: 5, 7, 9, 11, 13, 15. - */ - constructor(strength, quality, resolution, kernelSize) - { - kernelSize = kernelSize || 5; - const vertSrc = generateBlurVertSource(kernelSize, false); - const fragSrc = generateBlurFragSource(kernelSize); - - super( - // vertex shader - vertSrc, - // fragment shader - fragSrc - ); - - this.resolution = resolution || settings.RESOLUTION; - - this._quality = 0; - - this.quality = quality || 4; - - this.blur = strength || 8; - - this.firstRun = true; - } - - /** - * Applies the filter. - * - * @param {PIXI.FilterManager} filterManager - The manager. - * @param {PIXI.RenderTarget} input - The input target. - * @param {PIXI.RenderTarget} output - The output target. - * @param {boolean} clear - Should the output be cleared before rendering? - */ - /** - * Applies the filter. - * - * @param {PIXI.FilterManager} filterManager - The manager. - * @param {PIXI.RenderTarget} input - The input target. - * @param {PIXI.RenderTarget} output - The output target. - * @param {boolean} clear - Should the output be cleared before rendering? - */ - apply(filterManager, input, output, clear) - { - if (this.firstRun) - { - const gl = filterManager.renderer.gl; - const kernelSize = getMaxBlurKernelSize(gl); - - this.vertexSrc = generateBlurVertSource(kernelSize, true); - this.fragmentSrc = generateBlurFragSource(kernelSize); - - this.firstRun = false; - } - - if (output) - { - this.uniforms.strength = (1 / output.height) * (output.height / input.height); - } - else - { - this.uniforms.strength = (1 / filterManager.renderer.height) * (filterManager.renderer.height / input.height); - } - - // screen space! - this.uniforms.strength *= this.strength; - this.uniforms.strength /= this.passes; - - if (this.passes === 1) - { - filterManager.applyFilter(this, input, output, clear); - } - else - { - const renderTarget = filterManager.getFilterTexture(); - const renderer = filterManager.renderer; - - let flip = input; - let flop = renderTarget; - - this.state.blend = false; - filterManager.applyFilter(this, flip, flop, false); - - for (let i = 1; i < this.passes - 1; i++) - { - renderer.renderTexture.bind(flip, flip.filterFrame); - - this.uniforms.uSampler = flop; - - const temp = flop; - - flop = flip; - flip = temp; - - renderer.shader.bind(this); - renderer.geometry.draw(5); - } - - this.state.blend = true; - filterManager.applyFilter(this, flop, output, clear); - filterManager.returnFilterTexture(renderTarget); - } - } - - /** - * Sets the strength of both the blur. - * - * @member {number} - * @default 2 - */ - get blur() - { - return this.strength; - } - - set blur(value) // eslint-disable-line require-jsdoc - { - this.padding = 1 + (Math.abs(value) * 2); - this.strength = value; - } - - /** - * Sets the quality of the blur by modifying the number of passes. More passes means higher - * quaility bluring but the lower the performance. - * - * @member {number} - * @default 4 - */ - get quality() - { - return this._quality; - } - - set quality(value) // eslint-disable-line require-jsdoc - { - this._quality = value; - this.passes = value; - } -} diff --git a/bundles/pixi.js/src/deprecated.js b/bundles/pixi.js/src/deprecated.js index 4bf8beb..9e30b01 100644 --- a/bundles/pixi.js/src/deprecated.js +++ b/bundles/pixi.js/src/deprecated.js @@ -787,4 +787,41 @@ }, }, }); + + /** + * @class BlurXFilter + * @memberof PIXI.filters + * @deprecated since 5.0.0 + * @see PIXI.filters.BlurFilterPass + */ + class BlurXFilter extends PIXI.filters.BlurFilterPass + { + constructor(strength, quality, resolution, kernelSize) + { + warn('PIXI.filters.BlurXFilter is deprecated, use PIXI.filters.BlurFilterPass'); + + super(true, strength, quality, resolution, kernelSize); + } + } + + /** + * @class BlurYFilter + * @memberof PIXI.filters + * @deprecated since 5.0.0 + * @see PIXI.filters.BlurFilterPass + */ + class BlurYFilter extends PIXI.filters.BlurFilterPass + { + constructor(strength, quality, resolution, kernelSize) + { + warn('PIXI.filters.BlurYFilter is deprecated, use PIXI.filters.BlurFilterPass'); + + super(false, strength, quality, resolution, kernelSize); + } + } + + Object.assign(PIXI.filters, { + BlurXFilter, + BlurYFilter, + }); } diff --git a/bundles/pixi.js/src/index.js b/bundles/pixi.js/src/index.js index fb839a0..262b0b1 100644 --- a/bundles/pixi.js/src/index.js +++ b/bundles/pixi.js/src/index.js @@ -21,7 +21,7 @@ import * as utils from '@pixi/utils'; import { settings } from '@pixi/settings'; import { AlphaFilter } from '@pixi/filter-alpha'; -import { BlurFilter, BlurXFilter, BlurYFilter } from '@pixi/filter-blur'; +import { BlurFilter, BlurFilterPass } from '@pixi/filter-blur'; import { ColorMatrixFilter } from '@pixi/filter-color-matrix'; import { DisplacementFilter } from '@pixi/filter-displacement'; import { FXAAFilter } from '@pixi/filter-fxaa'; @@ -88,8 +88,7 @@ const filters = { AlphaFilter, BlurFilter, - BlurXFilter, - BlurYFilter, + BlurFilterPass, ColorMatrixFilter, DisplacementFilter, FXAAFilter, diff --git a/packages/filters/filter-blur/src/BlurFilter.js b/packages/filters/filter-blur/src/BlurFilter.js index 43906dc..c5bb586 100644 --- a/packages/filters/filter-blur/src/BlurFilter.js +++ b/packages/filters/filter-blur/src/BlurFilter.js @@ -1,7 +1,6 @@ import { Filter } from '@pixi/core'; import { settings } from '@pixi/settings'; -import BlurXFilter from './BlurXFilter'; -import BlurYFilter from './BlurYFilter'; +import BlurFilterPass from './BlurFilterPass'; /** * The BlurFilter applies a Gaussian blur to an object. @@ -23,13 +22,15 @@ { super(); - this.blurXFilter = new BlurXFilter(strength, quality, resolution, kernelSize); - this.blurYFilter = new BlurYFilter(strength, quality, resolution, kernelSize); + this.blurXFilter = new BlurFilterPass(true, strength, quality, resolution, kernelSize); + this.blurYFilter = new BlurFilterPass(false, strength, quality, resolution, kernelSize); - this.padding = 0; + this._padding = 0; this.resolution = resolution || settings.RESOLUTION; this.quality = quality || 4; this.blur = strength || 8; + + this.repeatEdgePixels = false; } /** @@ -41,12 +42,38 @@ */ apply(filterManager, input, output) { - const renderTarget = filterManager.getFilterTexture(true); + const xStrength = Math.abs(this.blurXFilter.strength); + const yStrength = Math.abs(this.blurYFilter.strength); - this.blurXFilter.apply(filterManager, input, renderTarget, true); - this.blurYFilter.apply(filterManager, renderTarget, output, false); + if (xStrength && yStrength) + { + const renderTarget = filterManager.getFilterTexture(true); - filterManager.returnFilterTexture(renderTarget); + this.blurXFilter.apply(filterManager, input, renderTarget, true); + this.blurYFilter.apply(filterManager, renderTarget, output, false); + + filterManager.returnFilterTexture(renderTarget); + } + else if (yStrength) + { + this.blurYFilter.apply(filterManager, input, output, false); + } + else + { + this.blurXFilter.apply(filterManager, input, output, false); + } + } + + updatePadding() + { + if (this._repeatEdgePixels) + { + this.padding = 0; + } + else + { + this.padding = Math.max(Math.abs(this.blurXFilter.strength), Math.abs(this.blurYFilter.strength)) * 2; + } } /** @@ -63,7 +90,7 @@ set blur(value) // eslint-disable-line require-jsdoc { this.blurXFilter.blur = this.blurYFilter.blur = value; - this.padding = Math.max(Math.abs(this.blurXFilter.strength), Math.abs(this.blurYFilter.strength)) * 2; + this.updatePadding(); } /** @@ -96,7 +123,7 @@ set blurX(value) // eslint-disable-line require-jsdoc { this.blurXFilter.blur = value; - this.padding = Math.max(Math.abs(this.blurXFilter.strength), Math.abs(this.blurYFilter.strength)) * 2; + this.updatePadding(); } /** @@ -113,7 +140,7 @@ set blurY(value) // eslint-disable-line require-jsdoc { this.blurYFilter.blur = value; - this.padding = Math.max(Math.abs(this.blurXFilter.strength), Math.abs(this.blurYFilter.strength)) * 2; + this.updatePadding(); } /** @@ -131,4 +158,21 @@ { this.blurYFilter._blendMode = value; } + + /** + * If set to true the edge of the target will be clamped + * + * @member {bool} + * @default false + */ + get repeatEdgePixels() + { + return this._repeatEdgePixels; + } + + set repeatEdgePixels(value) + { + this._repeatEdgePixels = value; + this.updatePadding(); + } } diff --git a/packages/filters/filter-blur/src/BlurFilterPass.js b/packages/filters/filter-blur/src/BlurFilterPass.js new file mode 100644 index 0000000..85b030c --- /dev/null +++ b/packages/filters/filter-blur/src/BlurFilterPass.js @@ -0,0 +1,158 @@ +import { Filter } from '@pixi/core'; +import { settings } from '@pixi/settings'; +import generateBlurVertSource from './generateBlurVertSource'; +import generateBlurFragSource from './generateBlurFragSource'; +import getMaxBlurKernelSize from './getMaxBlurKernelSize'; + +/** + * The BlurFilterPass applies a horizontal or vertical Gaussian blur to an object. + * + * @class + * @extends PIXI.Filter + * @memberof PIXI.filters + */ +export default class BlurFilterPass extends Filter +{ + /** + * @param {boolean} horizontal - Do pass along the x-axis (`true`) or y-axis (`false`). + * @param {number} strength - The strength of the blur filter. + * @param {number} quality - The quality of the blur filter. + * @param {number} resolution - The resolution of the blur filter. + * @param {number} [kernelSize=5] - The kernelSize of the blur filter.Options: 5, 7, 9, 11, 13, 15. + */ + constructor(horizontal, strength, quality, resolution, kernelSize) + { + kernelSize = kernelSize || 5; + const vertSrc = generateBlurVertSource(kernelSize, horizontal); + const fragSrc = generateBlurFragSource(kernelSize); + + super( + // vertex shader + vertSrc, + // fragment shader + fragSrc + ); + + this.horizontal = horizontal; + + this.resolution = resolution || settings.RESOLUTION; + + this._quality = 0; + + this.quality = quality || 4; + + this.blur = strength || 8; + + this.firstRun = true; + } + + apply(filterManager, input, output, clear) + { + if (this.firstRun) + { + const gl = filterManager.renderer.gl; + const kernelSize = getMaxBlurKernelSize(gl); + + this.vertexSrc = generateBlurVertSource(kernelSize, true); + this.fragmentSrc = generateBlurFragSource(kernelSize); + + this.firstRun = false; + } + + if (output) + { + if (this.horizontal) + { + this.uniforms.strength = (1 / output.width) * (output.width / input.width); + } + else + { + this.uniforms.strength = (1 / output.height) * (output.height / input.height); + } + } + else + { + if (this.horizontal) // eslint-disable-line + { + this.uniforms.strength = (1 / filterManager.renderer.width) * (filterManager.renderer.width / input.width); + } + else + { + this.uniforms.strength = (1 / filterManager.renderer.height) * (filterManager.renderer.height / input.height); // eslint-disable-line + } + } + + // screen space! + this.uniforms.strength *= this.strength; + this.uniforms.strength /= this.passes; + + if (this.passes === 1) + { + filterManager.applyFilter(this, input, output, clear); + } + else + { + const renderTarget = filterManager.getFilterTexture(); + const renderer = filterManager.renderer; + + let flip = input; + let flop = renderTarget; + + this.state.blend = false; + filterManager.applyFilter(this, flip, flop, false); + + for (let i = 1; i < this.passes - 1; i++) + { + renderer.renderTexture.bind(flip, flip.filterFrame); + + this.uniforms.uSampler = flop; + + const temp = flop; + + flop = flip; + flip = temp; + + renderer.shader.bind(this); + renderer.geometry.draw(5); + } + + this.state.blend = true; + filterManager.applyFilter(this, flop, output, clear); + filterManager.returnFilterTexture(renderTarget); + } + } + /** + * Sets the strength of both the blur. + * + * @member {number} + * @default 16 + */ + get blur() + { + return this.strength; + } + + set blur(value) // eslint-disable-line require-jsdoc + { + this.padding = 1 + (Math.abs(value) * 2); + this.strength = value; + } + + /** + * Sets the quality of the blur by modifying the number of passes. More passes means higher + * quaility bluring but the lower the performance. + * + * @member {number} + * @default 4 + */ + get quality() + { + return this._quality; + } + + set quality(value) // eslint-disable-line require-jsdoc + { + this._quality = value; + this.passes = value; + } +} diff --git a/packages/filters/filter-blur/src/BlurXFilter.js b/packages/filters/filter-blur/src/BlurXFilter.js deleted file mode 100644 index af46e16..0000000 --- a/packages/filters/filter-blur/src/BlurXFilter.js +++ /dev/null @@ -1,141 +0,0 @@ -import { Filter } from '@pixi/core'; -import { settings } from '@pixi/settings'; -import generateBlurVertSource from './generateBlurVertSource'; -import generateBlurFragSource from './generateBlurFragSource'; -import getMaxBlurKernelSize from './getMaxBlurKernelSize'; - -/** - * The BlurXFilter applies a horizontal Gaussian blur to an object. - * - * @class - * @extends PIXI.Filter - * @memberof PIXI.filters - */ -export default class BlurXFilter extends Filter -{ - /** - * @param {number} strength - The strength of the blur filter. - * @param {number} quality - The quality of the blur filter. - * @param {number} resolution - The resolution of the blur filter. - * @param {number} [kernelSize=5] - The kernelSize of the blur filter.Options: 5, 7, 9, 11, 13, 15. - */ - constructor(strength, quality, resolution, kernelSize) - { - kernelSize = kernelSize || 5; - const vertSrc = generateBlurVertSource(kernelSize, true); - const fragSrc = generateBlurFragSource(kernelSize); - - super( - // vertex shader - vertSrc, - // fragment shader - fragSrc - ); - - this.resolution = resolution || settings.RESOLUTION; - - this._quality = 0; - - this.quality = quality || 4; - - this.blur = strength || 8; - - this.firstRun = true; - } - - apply(filterManager, input, output, clear) - { - if (this.firstRun) - { - const gl = filterManager.renderer.gl; - const kernelSize = getMaxBlurKernelSize(gl); - - this.vertexSrc = generateBlurVertSource(kernelSize, true); - this.fragmentSrc = generateBlurFragSource(kernelSize); - - this.firstRun = false; - } - - if (output) - { - this.uniforms.strength = (1 / output.width) * (output.width / input.width); - } - else - { - this.uniforms.strength = (1 / filterManager.renderer.width) * (filterManager.renderer.width / input.width); - } - - // screen space! - this.uniforms.strength *= this.strength; - this.uniforms.strength /= this.passes; - - if (this.passes === 1) - { - filterManager.applyFilter(this, input, output, clear); - } - else - { - const renderTarget = filterManager.getFilterTexture(); - const renderer = filterManager.renderer; - - let flip = input; - let flop = renderTarget; - - this.state.blend = false; - filterManager.applyFilter(this, flip, flop, false); - - for (let i = 1; i < this.passes - 1; i++) - { - renderer.renderTexture.bind(flip, flip.filterFrame); - - this.uniforms.uSampler = flop; - - const temp = flop; - - flop = flip; - flip = temp; - - renderer.shader.bind(this); - renderer.geometry.draw(5); - } - - this.state.blend = true; - filterManager.applyFilter(this, flop, output, clear); - filterManager.returnFilterTexture(renderTarget); - } - } - /** - * Sets the strength of both the blur. - * - * @member {number} - * @default 16 - */ - get blur() - { - return this.strength; - } - - set blur(value) // eslint-disable-line require-jsdoc - { - this.padding = 1 + (Math.abs(value) * 2); - this.strength = value; - } - - /** - * Sets the quality of the blur by modifying the number of passes. More passes means higher - * quaility bluring but the lower the performance. - * - * @member {number} - * @default 4 - */ - get quality() - { - return this._quality; - } - - set quality(value) // eslint-disable-line require-jsdoc - { - this._quality = value; - this.passes = value; - } -} diff --git a/packages/filters/filter-blur/src/BlurYFilter.js b/packages/filters/filter-blur/src/BlurYFilter.js deleted file mode 100644 index 2d337a4..0000000 --- a/packages/filters/filter-blur/src/BlurYFilter.js +++ /dev/null @@ -1,158 +0,0 @@ -import { Filter } from '@pixi/core'; -import { settings } from '@pixi/settings'; -import generateBlurVertSource from './generateBlurVertSource'; -import generateBlurFragSource from './generateBlurFragSource'; -import getMaxBlurKernelSize from './getMaxBlurKernelSize'; - -/** - * The BlurYFilter applies a horizontal Gaussian blur to an object. - * - * @class - * @extends PIXI.Filter - * @memberof PIXI.filters - */ -export default class BlurYFilter extends Filter -{ - /** - * @param {number} strength - The strength of the blur filter. - * @param {number} quality - The quality of the blur filter. - * @param {number} resolution - The resolution of the blur filter. - * @param {number} [kernelSize=5] - The kernelSize of the blur filter.Options: 5, 7, 9, 11, 13, 15. - */ - constructor(strength, quality, resolution, kernelSize) - { - kernelSize = kernelSize || 5; - const vertSrc = generateBlurVertSource(kernelSize, false); - const fragSrc = generateBlurFragSource(kernelSize); - - super( - // vertex shader - vertSrc, - // fragment shader - fragSrc - ); - - this.resolution = resolution || settings.RESOLUTION; - - this._quality = 0; - - this.quality = quality || 4; - - this.blur = strength || 8; - - this.firstRun = true; - } - - /** - * Applies the filter. - * - * @param {PIXI.FilterManager} filterManager - The manager. - * @param {PIXI.RenderTarget} input - The input target. - * @param {PIXI.RenderTarget} output - The output target. - * @param {boolean} clear - Should the output be cleared before rendering? - */ - /** - * Applies the filter. - * - * @param {PIXI.FilterManager} filterManager - The manager. - * @param {PIXI.RenderTarget} input - The input target. - * @param {PIXI.RenderTarget} output - The output target. - * @param {boolean} clear - Should the output be cleared before rendering? - */ - apply(filterManager, input, output, clear) - { - if (this.firstRun) - { - const gl = filterManager.renderer.gl; - const kernelSize = getMaxBlurKernelSize(gl); - - this.vertexSrc = generateBlurVertSource(kernelSize, true); - this.fragmentSrc = generateBlurFragSource(kernelSize); - - this.firstRun = false; - } - - if (output) - { - this.uniforms.strength = (1 / output.height) * (output.height / input.height); - } - else - { - this.uniforms.strength = (1 / filterManager.renderer.height) * (filterManager.renderer.height / input.height); - } - - // screen space! - this.uniforms.strength *= this.strength; - this.uniforms.strength /= this.passes; - - if (this.passes === 1) - { - filterManager.applyFilter(this, input, output, clear); - } - else - { - const renderTarget = filterManager.getFilterTexture(); - const renderer = filterManager.renderer; - - let flip = input; - let flop = renderTarget; - - this.state.blend = false; - filterManager.applyFilter(this, flip, flop, false); - - for (let i = 1; i < this.passes - 1; i++) - { - renderer.renderTexture.bind(flip, flip.filterFrame); - - this.uniforms.uSampler = flop; - - const temp = flop; - - flop = flip; - flip = temp; - - renderer.shader.bind(this); - renderer.geometry.draw(5); - } - - this.state.blend = true; - filterManager.applyFilter(this, flop, output, clear); - filterManager.returnFilterTexture(renderTarget); - } - } - - /** - * Sets the strength of both the blur. - * - * @member {number} - * @default 2 - */ - get blur() - { - return this.strength; - } - - set blur(value) // eslint-disable-line require-jsdoc - { - this.padding = 1 + (Math.abs(value) * 2); - this.strength = value; - } - - /** - * Sets the quality of the blur by modifying the number of passes. More passes means higher - * quaility bluring but the lower the performance. - * - * @member {number} - * @default 4 - */ - get quality() - { - return this._quality; - } - - set quality(value) // eslint-disable-line require-jsdoc - { - this._quality = value; - this.passes = value; - } -} diff --git a/packages/filters/filter-blur/src/index.js b/packages/filters/filter-blur/src/index.js index 5ff22b2..14d486f 100644 --- a/packages/filters/filter-blur/src/index.js +++ b/packages/filters/filter-blur/src/index.js @@ -1,3 +1,2 @@ export { default as BlurFilter } from './BlurFilter'; -export { default as BlurXFilter } from './BlurXFilter'; -export { default as BlurYFilter } from './BlurYFilter'; +export { default as BlurFilterPass } from './BlurFilterPass';