DEV STUFF

Damien Pegoraro

Old school Text FX in AGAL

As I’m not really used to do stuff with Starling filter’s and more generally with AGAL, here’s my first real contact with the strange world of shaders.

I found my idea in Rocket Knights Adventure credits on Sega Genesis:

The text effect on the staff roll is pretty cool, so let’s try doing this in AGAL.

Here’s the result: (click on the text to do it again)

This movie requires Flash Player 9

You can also try it in a not-to-small page here

Also works on pictures:

This movie requires Flash Player 9

The approach I took is:

Let’s take a value varying from 0 to 1, corresponding to the rate of the object that is properly rendered.
We call it distance.

distance = 0 ; // nothing is displayed
distance = 0.5; // the left half of the object is fully displayed.
distance = 1 ; // object is fully displayed

Every point with x < distance is drawn directly Every point with x > distance is drawn with a color that comes from x2 = distance.

So if ( x < distance ) color is from x, else color is from x - distance. Here’s my pseudocode :

position = v0
test = position.x > distance ? 1 : 0
offset = position.x - distance
offset = offset * test
position.x = position.x - offset
draw color from position

Now let’s convert this to AGAL:


mov ft0, v0 // copy position
sge ft1.z, ft0.x, fc0.x // test if position > distance and put 0 or 1 in ft1.z
sub ft1.x, ft0.x, fc0.x // ft1.x = position.x - distance
mul ft1.x, ft1.x, ft1.z // ft1.x *= ft1.z
sub ft0.x, ft0.x, ft1.x // position.x -= ft1.x
tex oc, ft0, fs0<2d, wrap, linear, mipnone> // draw from position

To use this with Starling, we need to create a class extending FragmentFilter. I really don’t know how to call this effect, so let’s create a class named FromRightFilter. (Yes… because the text comes from the right…)


package starling.filters
{
import flash.display3D.Context3D;
import flash.display3D.Context3DProgramType;
import flash.display3D.Program3D;
import starling.filters.FragmentFilter;
import starling.textures.Texture;

public class FromRightFilter extends FragmentFilter
{
private static const FRAGMENT_SHADER:String =
]]>

private var mVars:Vector. = new [1, 1, 1, 1];
private var mShaderProgram:Program3D;
private var defaultShaderProgram:Program3D;

private var rate : Number = 0 ;
private var speed : Number = 0;

/**
*
*/
public function FromRightFilter()
{
rate = 0 ;
}

public override function dispose():void
{
if (mShaderProgram) mShaderProgram.dispose();
if (defaultShaderProgram) defaultShaderProgram.dispose();
super.dispose();
}

protected override function createPrograms():void
{
mShaderProgram = assembleAgal(FRAGMENT_SHADER);
defaultShaderProgram = assembleAgal(STD_FRAGMENT_SHADER) ;
}

protected override function activate(pass:int, context:Context3D, texture:Texture):void
{

if ( rate < 1 && speed != 0 ) { rate += speed ; mVars[0] = rate ; context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, mVars, 1); context.setProgram(mShaderProgram); } else { context.setProgram(defaultShaderProgram); } } public function start( speed : Number = 0.005 ) : void { this.speed = speed; rate = 0 ; } } }

I added a start() method that begins the render (setting rate from 0 to 1).
The filter also replaces itself by the default fragment shader program when it's done. (Don't know if this is really useful btw...)

Here's how to use it:


var tf : TextField = new TextField(600, 300, "FragmentFilter", "hyper", 80, 0xFF0000) ;
addChild( tf) ;
fil = new FromRightFilter() ;
tf.filter = fil;
fil.start() ;

DOWNLOAD ME

Links to check:

A great FragmentFilter collection that gave me the basic template for a custom filter and lots of crazy samples:

http://blog.onebyonedesign.com/actionscript/starling-filter-collection/

Well and deeply explained tutorials on AGAL:

http://jacksondunstan.com/articles/1661

And of cours, the opcodes list:

http://help.adobe.com/fr_FR/as3/dev/WSd6a006f2eb1dc31e-310b95831324724ec56-8000.html

Leave a Reply

Your email address will not be published. Required fields are marked *