{"version":3,"file":"BlurFilterPass.mjs","sources":["../../../../src/filters/defaults/blur/BlurFilterPass.ts"],"sourcesContent":["import { TexturePool } from '../../../rendering/renderers/shared/texture/TexturePool';\nimport { RendererType } from '../../../rendering/renderers/types';\nimport { Filter } from '../../Filter';\nimport { generateBlurGlProgram } from './gl/generateBlurGlProgram';\nimport { generateBlurProgram } from './gpu/generateBlurProgram';\n\nimport type { WebGPURenderer } from '../../../rendering/renderers/gpu/WebGPURenderer';\nimport type { RenderSurface } from '../../../rendering/renderers/shared/renderTarget/RenderTargetSystem';\nimport type { UniformGroup } from '../../../rendering/renderers/shared/shader/UniformGroup';\nimport type { Texture } from '../../../rendering/renderers/shared/texture/Texture';\nimport type { FilterSystem } from '../../FilterSystem';\nimport type { BlurFilterOptions } from './BlurFilter';\n\n/**\n * Options for BlurFilterPass\n * @category filters\n * @internal\n */\nexport interface BlurFilterPassOptions extends BlurFilterOptions\n{\n    /** Do pass along the x-axis (`true`) or y-axis (`false`). */\n    horizontal: boolean;\n}\n\n/**\n * The BlurFilterPass applies a horizontal or vertical Gaussian blur to an object.\n * @category filters\n * @advanced\n * @example\n * import { BlurFilterPass } from 'pixi.js';\n *\n * const filter = new BlurFilterPass({ horizontal: true, strength: 8 });\n * sprite.filters = filter;\n *\n * // update blur\n * filter.blur = 16;\n */\nexport class BlurFilterPass extends Filter\n{\n    /** Default blur filter pass options */\n    public static defaultOptions: Partial<BlurFilterPassOptions> = {\n        /** The strength of the blur filter. */\n        strength: 8,\n        /** The quality of the blur filter. */\n        quality: 4,\n        /** The kernelSize of the blur filter.Options: 5, 7, 9, 11, 13, 15. */\n        kernelSize: 5,\n        /** Whether to use legacy blur pass behavior. */\n        legacy: false,\n    };\n\n    /** Do pass along the x-axis (`true`) or y-axis (`false`). */\n    public horizontal: boolean;\n    /** The number of passes to run the filter. */\n    public passes!: number;\n    /** The strength of the blur filter. */\n    public strength!: number;\n    /** Whether to use legacy blur pass behavior. */\n    public legacy: boolean;\n\n    private _quality: number;\n    private readonly _uniforms: any;\n    private readonly _blurUniforms: UniformGroup;\n\n    /**\n     * @param options\n     * @param options.horizontal - Do pass along the x-axis (`true`) or y-axis (`false`).\n     * @param options.strength - The strength of the blur filter.\n     * @param options.quality - The quality of the blur filter.\n     * @param options.kernelSize - The kernelSize of the blur filter.Options: 5, 7, 9, 11, 13, 15.\n     */\n    constructor(options: BlurFilterPassOptions)\n    {\n        options = { ...BlurFilterPass.defaultOptions, ...options };\n\n        const glProgram = generateBlurGlProgram(options.horizontal, options.kernelSize);\n        const gpuProgram = generateBlurProgram(options.horizontal, options.kernelSize);\n\n        super({\n            glProgram,\n            gpuProgram,\n            resources: {\n                blurUniforms: {\n                    uStrength: { value: 0, type: 'f32' },\n                }\n            },\n            ...options\n        });\n\n        this.horizontal = options.horizontal;\n        this.legacy = options.legacy ?? false;\n\n        this._quality = 0;\n\n        this.quality = options.quality;\n\n        this.blur = options.strength;\n\n        // Store reference to the UniformGroup before any resource swapping\n        this._blurUniforms = this.resources.blurUniforms as UniformGroup;\n        this._uniforms = this._blurUniforms.uniforms;\n    }\n\n    /**\n     * Applies the filter.\n     * @param filterManager - The manager.\n     * @param input - The input target.\n     * @param output - The output target.\n     * @param clearMode - How to clear\n     */\n    public apply(\n        filterManager: FilterSystem,\n        input: Texture,\n        output: RenderSurface,\n        clearMode: boolean\n    ): void\n    {\n        if (this.legacy)\n        {\n            this._applyLegacy(filterManager, input, output, clearMode);\n        }\n        else\n        {\n            this._applyOptimized(filterManager, input, output, clearMode);\n        }\n    }\n\n    private _applyLegacy(\n        filterManager: FilterSystem,\n        input: Texture,\n        output: RenderSurface,\n        clearMode: boolean\n    ): void\n    {\n        this._uniforms.uStrength = this.strength / this.passes;\n\n        if (this.passes === 1)\n        {\n            filterManager.applyFilter(this, input, output, clearMode);\n        }\n        else\n        {\n            const tempTexture = TexturePool.getSameSizeTexture(input);\n\n            let flip = input;\n            let flop = tempTexture;\n\n            this._state.blend = false;\n\n            const shouldClear = filterManager.renderer.type === RendererType.WEBGPU;\n\n            for (let i = 0; i < this.passes - 1; i++)\n            {\n                filterManager.applyFilter(this, flip, flop, i === 0 ? true : shouldClear);\n\n                const temp = flop;\n\n                flop = flip;\n                flip = temp;\n            }\n\n            this._state.blend = true;\n            filterManager.applyFilter(this, flip, output, clearMode);\n            TexturePool.returnTexture(tempTexture);\n        }\n    }\n\n    private _applyOptimized(\n        filterManager: FilterSystem,\n        input: Texture,\n        output: RenderSurface,\n        clearMode: boolean\n    ): void\n    {\n        this._uniforms.uStrength = this._calculateInitialStrength();\n\n        if (this.passes === 1)\n        {\n            filterManager.applyFilter(this, input, output, clearMode);\n        }\n        else\n        {\n            const tempTexture = TexturePool.getSameSizeTexture(input);\n\n            let flip = input;\n            let flop = tempTexture;\n\n            this._state.blend = false;\n\n            const renderer = filterManager.renderer;\n\n            const isWebGPU = renderer.type === RendererType.WEBGPU;\n            const uboBatcher = isWebGPU ? (renderer as WebGPURenderer).renderPipes.uniformBatch : null;\n\n            for (let i = 0; i < this.passes - 1; i++)\n            {\n                if (uboBatcher)\n                {\n                    this.groups[1].setResource(uboBatcher.getUboResource(this._blurUniforms), 0);\n                }\n\n                filterManager.applyFilter(this, flip, flop, isWebGPU);\n\n                const temp = flop;\n\n                flop = flip;\n                flip = temp;\n\n                this._uniforms.uStrength *= 0.5;\n            }\n\n            if (uboBatcher)\n            {\n                this.groups[1].setResource(uboBatcher.getUboResource(this._blurUniforms), 0);\n            }\n\n            this._state.blend = true;\n            filterManager.applyFilter(this, flip, output, clearMode);\n            TexturePool.returnTexture(tempTexture);\n        }\n    }\n\n    /**\n     * Calculates the initial strength for the first blur pass so that the combined\n     * effect of all passes matches the filter's target strength.\n     *\n     * Uses variance addition property: for Gaussian blurs, σ_combined² = Σσᵢ²\n     * With halving scheme (s, s/2, s/4, ...), sum of squared coefficients = 4/3\n     */\n    private _calculateInitialStrength(): number\n    {\n        let sumOfSquares = 1;\n        let coefficient = 0.5;\n\n        for (let i = 1; i < this.passes; i++)\n        {\n            sumOfSquares += coefficient * coefficient;\n            coefficient *= 0.5;\n        }\n\n        return this.strength / Math.sqrt(sumOfSquares);\n    }\n\n    /**\n     * Sets the strength of both the blur.\n     * @default 16\n     */\n    get blur(): number\n    {\n        return this.strength;\n    }\n\n    set blur(value: number)\n    {\n        this.padding = 1 + (Math.abs(value) * 2);\n        this.strength = value;\n    }\n\n    /**\n     * Sets the quality of the blur by modifying the number of passes. More passes means higher\n     * quality blurring but the lower the performance.\n     * @default 4\n     */\n    get quality(): number\n    {\n        return this._quality;\n    }\n\n    set quality(value: number)\n    {\n        this._quality = value;\n        this.passes = value;\n    }\n}\n"],"names":[],"mappings":"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"}