     public static const HORIZONTAL:String   = "horizontal";
     public static const VERTICAL:String     = "vertical";
 
-    private static const DEFAULT_FIRST_PASS_STRENGTH:Number                 = 1.25;
-    private static const DEFAULT_STRENGTH_INCREASE_PER_PASS_RATIO:Number    = 2.5;
+    public static const DEFAULT_FIRST_PASS_STRENGTH:Number                 = 1.25;
+    public static const DEFAULT_STRENGTH_INCREASE_PER_PASS_RATIO:Number    = 2.5;
+
+    protected static const TEXTURE_FLAGS:Array = [TextureFlag.TYPE_2D, TextureFlag.MODE_CLAMP, TextureFlag.FILTER_LINEAR, TextureFlag.MIP_NO];
 
     private static var _verticalOffsets:Vector.<Number>     = new <Number>[0.0, 1.3846153846, 0.0, 3.2307692308];
     private static var _horizontalOffsets:Vector.<Number>   = new <Number>[1.3846153846, 0.0, 3.2307692308, 0.0];

        if(_paramsDirty)
            updateParameters();

        context.setProgramConstantsFromVector(Context3DProgramType.VERTEX,   4, _offsets);

        context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, _weights);
        context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 1, _uv);
        context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 2, _pixelSize);
    }

    public function deactivate(context:Context3D):void {
    }

    override protected function _vertexShader():void {
        comment("Apply a 4x4 matrix to transform vertices to clip-space");
        multiply4x4(OUTPUT, ATTRIBUTE[0], CONST[0]);

        comment("Pass uv coordinates to fragment shader");
        move(VARYING[0], ATTRIBUTE[1]);

        comment("pass 4 additional UVs for sampling neighbours, in order: -2, -1, +1, +2 pixels away");
        subtract(VARYING[1], ATTRIBUTE[1], CONST[4].zw);
        subtract(VARYING[2], ATTRIBUTE[1], CONST[4].xy);
        add(VARYING[3], ATTRIBUTE[1], CONST[4].xy);
        add(VARYING[4], ATTRIBUTE[1], CONST[4].zw);
    }

    override protected function _fragmentShader():void {
        var uvCenter:IRegister          = VARYING[0];
        var uvMinusTwo:IRegister        = VARYING[1];
        var uvMinusOne:IRegister        = VARYING[2];
        var uvPlusOne:IRegister         = VARYING[3];
        var uvPlusTwo:IRegister         = VARYING[4];
        var uv:IRegister                = TEMP[7];
        var weightCenter:IComponent     = CONST[0].x;
        var weightOne:IComponent        = CONST[0].y;
        var weightTwo:IComponent        = CONST[0].z;
        var minU:IComponent             = CONST[1].x;
        var maxU:IComponent             = CONST[1].y;
        var minV:IComponent             = CONST[1].z;
        var maxV:IComponent             = CONST[1].w;
        var halfPixelWidth:IComponent   = CONST[2].z;
        var halfPixelHeight:IComponent  = CONST[2].w;
        var colorCenter:IRegister       = TEMP[0];
        var colorMinusTwo:IRegister     = TEMP[1];
        var colorMinusOne:IRegister     = TEMP[2];
        var colorPlusOne:IRegister      = TEMP[3];
        var colorPlusTwo:IRegister      = TEMP[4];
        var outputColor:IRegister       = TEMP[5];
        var textureFlags:Array          = [TextureFlag.TYPE_2D, TextureFlag.MODE_CLAMP, TextureFlag.FILTER_LINEAR, TextureFlag.MIP_NO];

        sampleTexture(colorCenter, uvCenter, SAMPLER[0], textureFlags);
        multiply(outputColor, colorCenter, weightCenter);

        move(uv, uvMinusTwo);
        ShaderUtil.clamp(uv.x, minU, maxU, halfPixelWidth, TEMP[6]);
        ShaderUtil.clamp(uv.y, minV, maxV, halfPixelHeight, TEMP[6]);
        sampleTexture(colorMinusTwo, uv, SAMPLER[0], textureFlags);
        multiply(colorMinusTwo, colorMinusTwo, weightTwo);
        add(outputColor, outputColor, colorMinusTwo);

        move(uv, uvMinusOne);
        ShaderUtil.clamp(uv.x, minU, maxU, halfPixelWidth, TEMP[6]);
        ShaderUtil.clamp(uv.y, minV, maxV, halfPixelHeight, TEMP[6]);
        sampleTexture(colorMinusOne, uv, SAMPLER[0], textureFlags);
        multiply(colorMinusOne, colorMinusOne, weightOne);
        add(outputColor, outputColor, colorMinusOne);

        move(uv, uvPlusOne);
        ShaderUtil.clamp(uv.x, minU, maxU, halfPixelWidth, TEMP[6]);
        ShaderUtil.clamp(uv.y, minV, maxV, halfPixelHeight, TEMP[6]);
        sampleTexture(colorPlusOne, uv, SAMPLER[0], textureFlags);
        multiply(colorPlusOne, colorPlusOne, weightOne);
        add(outputColor, outputColor, colorPlusOne);

        move(uv, uvPlusTwo);
        ShaderUtil.clamp(uv.x, minU, maxU, halfPixelWidth, TEMP[6]);
        ShaderUtil.clamp(uv.y, minV, maxV, halfPixelHeight, TEMP[6]);
        sampleTexture(colorPlusTwo, uv, SAMPLER[0], textureFlags);
        multiply(colorPlusTwo, colorPlusTwo, weightTwo);
        add(outputColor, outputColor, colorPlusTwo);

        move(OUTPUT, outputColor);
    }

    private function updateParameters():void {

    private var _paramsDirty:Boolean            = true;
    private var _strengthsDirty:Boolean         = true;

    protected var _strengths:Vector.<Number>    = new <Number>[];
    private var _offsets:Vector.<Number>        = new <Number>[0, 0, 0, 0];
    private var _uv:Vector.<Number>             = new <Number>[0, 1, 0, 1];
    private var _pixelSize:Vector.<Number>      = new <Number>[Number.NaN, Number.NaN, Number.NaN, Number.NaN];

    // shader constants
    protected var uvCenter:IRegister            = VARYING[0];
    protected var weightCenter:IComponent       = CONST[0].x;
    protected var weightOne:IComponent          = CONST[0].y;
    protected var weightTwo:IComponent          = CONST[0].z;
    protected var offsetOne:IField              = CONST[1].xy;
    protected var offsetTwo:IField              = CONST[1].zw;
    protected var uMin:IComponent               = CONST[2].x;
    protected var uMax:IComponent               = CONST[2].y;
    protected var vMin:IComponent               = CONST[2].z;
    protected var vMax:IComponent               = CONST[2].w;
    protected var halfPixelWidth:IComponent     = CONST[3].z;
    protected var halfPixelHeight:IComponent    = CONST[3].w;

    public function get type():String { return _type; }
    public function set type(value:String):void {
        if(value == _type)
