Monday, 12 March 2012

Shader vs. ActionScript

It was pointed out to me that the shader I used as an example last week did something that could be done with ActionScript, in particular a ColorMatrixFilter. This was something I was aware of, as I described how to use a ColorMatrixFilter in exactly that way a month ago in this post. But it's interesting to compare them to see the difference.


Here's the code of the shader again, stripped of comments:


float4 sampleColor = sampleLinear(oImage, outCoord());
float fGrey = 0.3 * sampleColor.r + 0.59 * sampleColor.g + 0.11 * sampleColor.b;
float4 vGrey = float4(fGrey, fGrey, fGrey, 1.0);
outputColor = (1.0 - fAmplitude) * sampleColor + fAmplitude * vGrey;

Only four lines, one of which is concerned with getting the pixel. The ColorMatrixFilter code is about as long


mat = new Array(0.20.60.200,
0.20.60.200,
0.20.60.200,
00010);
cmFilter = new ColorMatrixFilter(mat);
dat.applyFilter(dat, dat.rectnew Point(), cmFilter);

There are a couple of notable differences though. First I use two different sets of numbers to map a colour to greyscale. The ColorMatrixFilter uses


(0.2, 0.6, 0.2)


which I came up with by trial and error while working on Bug Tunnel Defense, as I wrote some code to desaturate sprites once loaded. The shader uses


(0.3, 0.59, 0.11)

which I got from a web search for what looked best applied to the test photos that come with the Pixel Bender Toolkit.


The other difference is the ColorMatrixFilter only does one thing: there's no option to only partially desaturate. This is easy to add though: and for consistency I'll do it using the numbers from the shader


var fR:Number = 0.30 * fAmplitude;
var fG:Number = 0.59 * fAmplitude;
var fB:Number = 0.11 * fAmplitude;
mat = new Array(fR + (1 - fAmplitude), fG, fB00,
fR, fG (1 - fAmplitude), fB00,
fR, fG, fB (1 - fAmplitude)00,
00010);
cmFilter = new ColorMatrixFilter(mat);
dat.applyFilter(dat, dat.rectnew Point(), cmFilter);

This creates a matrix which has the same effect as the shader calculation. The shader code is simpler as it acts directly on the colour of each pixel.


As for which is faster I don't know as I've not tried comparing them. In my so far limited experience Flash shaders are very efficient, but I've not tried using a ColorMatrixFilter in the same way. 


Perhaps the main advantage of shaders is it's easy to add other functionality. The matrix used above is about as much as can be crammed into a ColorMatrixFilter, but the shader barely scratches the surface of what's possible.

No comments:

Post a Comment