Filters

This page will contain a detailed reference about fragment filters in the future. At the moment, it is just a placeholder.

Here's the simplest possible filter: a filter that displays the object in exactly the way it was rendered in the first place.

public class IdentityFilter extends FragmentFilter
{
    private var mShaderProgram:Program3D;
 
    public function IdentityFilter()
    {
        super();
    }
 
    public override function dispose():void
    {
        if (mShaderProgram) mShaderProgram.dispose();
        super.dispose();
    }
 
    protected override function createPrograms():void
    {
        var fragmentProgramCode:String =
            "tex oc, v0, fs0 <2d, clamp, linear, mipnone>"; // just forward texture color
 
        mShaderProgram = assembleAgal(fragmentProgramCode);
    }
 
    protected override function activate(pass:int, context:Context3D, texture:Texture):void
    {
        // already set by super class:
        // 
        // vertex constants 0-3: mvpMatrix (3D)
        // vertex attribute 0:   vertex position (FLOAT_2)
        // vertex attribute 1:   texture coordinates (FLOAT_2)
        // texture 0:            input texture
 
        context.setProgram(mShaderProgram);
    }
}

This one does a little more: it converts a colored object into its grayscale version, using specific quantifiers for each color.

public class GrayscaleFilter extends FragmentFilter
{
    private var mQuantifiers:Vector.<Number>;
    private var mShaderProgram:Program3D;
 
    public function GrayscaleFilter(red:Number=0.299, green:Number=0.587, blue:Number=0.114)
    {
        mQuantifiers = new <Number>[red, green, blue, 0.0];
    }
 
    public override function dispose():void
    {
        if (mShaderProgram) mShaderProgram.dispose();
        super.dispose();
    }
 
    protected override function createPrograms():void
    {
        var fragmentProgramCode:String =
            "tex ft0, v0, fs0 <2d, clamp, linear, mipnone>  \n" + // read texture color
            "dp3 ft0.xyz, ft0.xyz, fc0.xyz \n" +  // dot product color with quantifiers
            "mov oc, ft0                   \n";   // output color
 
        mShaderProgram = assembleAgal(fragmentProgramCode);
    }
 
    protected override function activate(pass:int, context:Context3D, texture:Texture):void
    {
        context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, mQuantifiers, 1);
        context.setProgram(mShaderProgram);
    }
}

And another one: an InverseFilter.

public class InverseFilter extends FragmentFilter
{
    private var mShaderProgram:Program3D;
    private var mOnes:Vector.<Number> = new <Number>[1.0, 1.0, 1.0, 1.0];
    private var mMinColor:Vector.<Number> = new <Number>[0, 0, 0, 0.0001];
 
    public function InverseFilter()
    {
        super();
    }
 
    public override function dispose():void
    {
        if (mShaderProgram) mShaderProgram.dispose();
        super.dispose();
    }
 
    protected override function createPrograms():void
    {
        // One might expect that we could just subtract the RGB values from 1, right?
        // The problem is that the input arrives with premultiplied alpha values, and the
        // output is expected in the same form. So we first have to restore the original RGB
        // values, subtract them from one, and then multiply with the original alpha again.
 
        var fragmentProgramCode:String =
            "tex ft0, v0, fs0 <2d, clamp, linear, mipnone>  \n" + // read texture color
            "max ft0, ft0, fc1              \n" + // avoid division through zero in next step
            "div ft0.xyz, ft0.xyz, ft0.www  \n" + // restore original (non-PMA) RGB values
            "sub ft0.xyz, fc0.xyz, ft0.xyz  \n" + // subtract rgb values from '1'
            "mul ft0.xyz, ft0.xyz, ft0.www  \n" + // multiply with alpha again (PMA)
            "mov oc, ft0                    \n";  // copy to output
 
        mShaderProgram = assembleAgal(fragmentProgramCode);
    }
 
    protected override function activate(pass:int, context:Context3D, texture:Texture):void
    {
        context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, mOnes, 1);
        context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 1, mMinColor, 1);
        context.setProgram(mShaderProgram);
    }
}

Those filters are no longer a part of Starling, because you can achieve all three effects with the more flexible “ColorMatrixFilter” class.

  manual/filters.txt · Last modified: 2012/12/11 15:12 by daniel
 
Powered by DokuWiki