Engine.AlphaOutlineFilter = class extends PIXI.Filter {
    constructor(thickness = 1, color = 0x000000, quality = 0.1, alpha = 1) {
        const samples =  Math.max(
            quality * Engine.AlphaOutlineFilter.MAX_SAMPLES,
            Engine.AlphaOutlineFilter.MIN_SAMPLES
        );
        const angleStep = (Math.PI * 2 / samples).toFixed(7);
		
		
		var vertex = "attribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat3 projectionMatrix;\nvarying vec2 vTextureCoord;\nvoid main(void)\n{\n    gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);\n    vTextureCoord = aTextureCoord;\n}";
		var fragment = "varying vec2 vTextureCoord;\nuniform sampler2D uSampler;\n\nuniform vec2 thickness;\nuniform vec4 outlineColor;\nuniform vec4 filterClamp;\n\nconst float DOUBLE_PI = 3.14159265358979323846264 * 2.;\n\nvoid main(void) {\n    vec4 ownColor = texture2D(uSampler, vTextureCoord);\n    vec4 curColor;\n    float maxAlpha = 0.;\n    vec2 displaced;\n    for (float angle = 0.; angle <= DOUBLE_PI; angle += ${angleStep}) {\n        displaced.x = vTextureCoord.x + thickness.x * cos(angle);\n        displaced.y = vTextureCoord.y + thickness.y * sin(angle);\n        curColor = texture2D(uSampler, clamp(displaced, filterClamp.xy, filterClamp.zw));\n        maxAlpha = max(maxAlpha, curColor.a);\n    }\n    float resultAlpha = max(min(outlineColor.a, maxAlpha), ownColor.a);\n    gl_FragColor = vec4((ownColor.rgb + outlineColor.rgb * (1. - ownColor.a)) * resultAlpha, resultAlpha);\n}\n";
		
        super(vertex, fragment.replace(/\$\{angleStep\}/, angleStep));
        this.uniforms.thickness = new Float32Array([0, 0]);
        /**
         * The thickness of the outline.
         * @member {number}
         * @default 1
         */
        this.thickness = thickness;
        this.uniforms.outlineColor = new Float32Array([0, 0, 0, alpha]);
        this.color = color;
        this.quality = quality;
    }
    apply(filterManager, input, output, clear) {
        this.uniforms.thickness[0] = this.thickness / input.width;
        this.uniforms.thickness[1] = this.thickness / input.height;
        filterManager.applyFilter(this, input, output, clear);
    }
    /**
     * The color of the glow.
     * @member {number}
     * @default 0x000000
     */
    get color() {
        return PIXI.utils.rgb2hex(this.uniforms.outlineColor);
    }
    set color(value) {
		if (value instanceof Color)
		{
			this.uniforms.outlineColor[0] = value.r;
			this.uniforms.outlineColor[1] = value.g;
			this.uniforms.outlineColor[2] = value.b;
		}
		else
		{
			PIXI.utils.hex2rgb(value, this.uniforms.outlineColor);
		}
    }
}
/**
 * The minimum number of samples for rendering outline.
 * @static
 * @member {number} MIN_SAMPLES
 * @memberof PIXI.filters.OutlineFilter
 * @default 1
 */
Engine.AlphaOutlineFilter.MIN_SAMPLES = 1;
/**
 * The maximum number of samples for rendering outline.
 * @static
 * @member {number} MAX_SAMPLES
 * @memberof PIXI.filters.OutlineFilter
 * @default 100
 */
Engine.AlphaOutlineFilter.MAX_SAMPLES = 100;