Custom blend modes for Flash 10
In the last few months I have been working on a collection of blendmodes for Flash 10 which extend the limited set of blendmodes currently and inconsistently supplied by Adobe applications. This can help to achieve all kinds of motion effects which I won't go into detail here but if you know a little about After Effects you will know that some of these are rather exciting.
If you are familiar with the Adobe product line there is inconsistency between Photoshop/Illustrator/Flash/Fireworks/InDesign and support for various subsets of blendmodes which is rather annoying especially for us Flash guys. This project overzealously named the 'Ultimate Blend Mode Collection' is an attempt to standardize this unofficially on Adobes behalf. So marrying up Photoshop designs and Flash layouts with unsupported blendmodes won't be nearly as annoying as has been previously. Further to this, these custom blendmodes allow for control to exaggerate and undo the blendmode effects. What this means is you do not have to double up the blendmode effect by duplicating the DisplayObject instance with the same blendmode you can just multiply the single blendmode effect - simple and quite effecient.
So far I have completed the following custom blend modes :
- Add
- Hard Mix
- Hardlight
- Glow
- Subtract
- Stencil Luma
- Extrapolate
- Difference
- Average
- Lighter Color
- Lighten
- Color Dodge
- Stencil Alpha
- Stamp
- Softlight
- Silhouette Luma
- Silhouette Alpha
- Screen
- PinLight
- Phoenix
- Overlay
- Negation
- Multiply
- Linear Light
- Linear Dodge
- Linear Burn
- Darken
- Desaturate
- Exclusion
- Color Burn
- Alpha
- Darker Color
These are working though have issues of dirty-ness on alpha channels (explained below) for blending layers :
- Reflect
- Freeze
- Heat
- Vivid Light
These custom blend modes are currently in development :
- Color
- Hue
- Luminosity
- Saturation
- Dissolve
How to use custom blend modes
I have only provided a method to use these custom blend modes included with the 'Ultimate Blendmode Collection' for Flex and CS4 users. This is because the PBJ files are compiled into a SWC so you will need to be able to reference SWCs from your FLA or SWF compiler to use the custom blend modes I have mentioned. The syntax to apply a custom blend mode can be achieved via any of the following approaches :
-
import flash.display.BlendModeShader;
-
-
myDisplayObject.blendShader = BlendModeShader.SOFTLIGHT;
or
-
import flash.display.BlendModeShader;
-
import flash.display.shaders.*;
-
-
myDisplayObject.blendShader = new BlendModeSoftlight();
or you can manipulate the shader
-
import flash.display.BlendModeShader;
-
import flash.display.shaders.*;
-
-
var customBlendMode: BlendModeSoftlight = new BlendModeSoftlight();
-
customBlendMode.multiply = 2;
-
customBlendMode.alpha = 0.5;
-
myDisplayObject.blendShader = customBlendMode;
Tips for writing your own custom blend modes
Here are some potentially huge gotchas and lovely time savers for those wanna be pixel shader writers (like myself) :
- Un-multiply alpha before carrying out your shader algorithm. You might already know that Flash pre-multiplies the alpha channel onto the rgb channels this means that if you want to know what the actual rgb components are you will need to do the following :
Actionscript:
-
void
-
evaluatePixel()
-
{
-
float2 uv = outCoord();
-
-
float4 src1Rgba = sampleLinear(src1, uv);
-
float src1Alpha = src1Rgba.a;
-
if(src1Alpha>0.0) src1Rgba.rgb *= 1.0/src1Alpha; //This line un-multiplies the alpha from the rgb channels
-
}
-
- When your done manipulating your blending layer against the base layer it's more than likely you will need to composite your new blending layer and base layers together while preserving the alpha components. The following should be useful for this :
Actionscript:
-
void
-
evaluatePixel()
-
{
-
......
-
-
interpolateAlpha = src2Rgba.a;
-
inverseAlpha = 1.0-interpolateAlpha;
-
-
dst.rgb = src2Rgba.rgb+src1Rgba.rgb*inverseAlpha;
-
dst.a = min(1.0, src1Alpha+src2Alpha);
-
}
-
- Make sure you clamp the components you are altering between 0.0 and 1.0 outside these will give you unusual results between tests made with the Pixel Bender Toolkit and from a published Flash movie. This bit of code ought to fix this :
Actionscript:
-
void
-
evaluatePixel()
-
{
-
float3 minRgb = float3(0.0, 0.0, 0.0);
-
float3 maxRgb = float3(1.0, 1.0, 1.0);
-
-
......
-
-
dst.rgb = clamp(dst.rgb, minRgb, maxRgb);
-
}
-
- Because Flash premultiplies alpha and I explained earlier about why you may need to un-multiply alpha from the rgb components. It's important to know from this there is a certain degree of losiness and this article by Mario is a great Actionscript explanation (completely unrelated to shaders) of this and is one among many others crying out for help (like me). You may notice in the example below which demonstrates these custom blend modes (or in your own tests) a certain degree of image dirty-ness and this dirty-ness is due to this. I am still working on a way to reduce or get around this - any ideas are certainly welcome - and I've highlighted the shaders above most affected by this.
- When applying a shader the input sources for the blending and base layer are automatically set. This is great but doesn't allow for setting any further image4 inputs. From my tests if I do try to do this then the Flash Player crashes every time. This is bug and generally bugging me because I can't complete other custom blendmodes based on random math like the Dissolve blendmode
How to get the custom blend modes
I have placed my PBJ, PBK and SWC files on a code.google project. I have also put together a brief getting started page. If you want to get an idea of what's possible using these custom blend modes the simple example below should help to demonstrate this. Also make sure you try out a few of the various base and blending layers I have set up to see what does what.
References
If you are interested in writing your own blend modes I used quite a few sources in order to collect the algorithms used in the examples seen above - here are the main sources :
http://www.pegtop.net/delphi/articles/blendmodes/
http://blog.mouaif.org/?p=94
http://www.nathanm.com/photoshop-blending-math/
Export Layers to SWF with JSFL
It's embarrassing but until the other week I hadn't a reason to do anything (beyond tinkering) with JSFL. JSFL can be especially useful for simplifying or automating tasks in the Flash IDE and that isn't breaking news. I think I understand why I haven't been using JSFL too much until recently. The major problem I discovered is the documentation is very poor, if you search JSFL you get exactly diddly squat on how to use JSFL. And alas Googling JSFL aint much better with the term "JSFL Reference" the only adobe link is this one. Considering this help reference is 5 years old doesn't inflate confidence in learning the latest and greatest JSFL has to offer - this is really pathetic Adobe. If someone can find an official decent resource on JSFL it would be appreciated, SURELY that isn't it :) So despite not being able to find a great JSFL reference Eventually I was referred to this great JSFL reference. The JSFL script I needed to write was really quite basic and for Actionscript developers writing JSFL it is very familiar territory so I was somehow blindly confident.
So I will describe the usefulness of this JSFL script by first explaining the task or problem at hand it solved for me and hopefully you find it useful also.
The Problem
I had a rather complex vector map (12 MB) in a SWF. Embedding the whole map would be obviously be a BAD idea for loading times but fortunately only very small portions of this map had to be used at any time. Though the suker punch to this idea is that the map isn't grouped to these portions - sigh.
The Solution
So I started with some unavoidable and rather laborious instance naming grinding which I did within Flash. Once I had completed this I had literally 100's of Movieclips associated to Classes that needed to be published and when I hit this I realised - JSFL I love you! So I distributed these MovieClips to layers then ran this script and viola all the layers are published as swfs using the layer name as the published SWF name - ba da boom ching :)
The way this script works is that publishes any layer that isn't a folder or a guide on the main timeline. Then sets all the layers to guides, then loops through the layers desired to be outputted to SWF then changes them to a normal layer so that only this layer is the only one in the published SWF. Once the publish loop is completed all layers are then set back to their original states.
Rather simple I thought and a huge time saver for mindless SWF publishing. To run this JSFL simply double click it or drag it onto Flash then you will be prompted to select the output directory. Then sit back, relax or even take the evening off and tell your project manager you're hard at work!
You can view the source or download this script here - get it while it's hot!
FITC Pixel Bender Source Code
In my efficiency FITC talk I covered some topics regarding programmatically rendering to the DisplayList - efficiently and practically. This covered some simple examples showing what can be done in PixelBender with Shaders including blendModes, lighting effects and transitions. If you would like the source code for these examples you can get them from my code.google repository.
These shader examples only represent a taste of what's possible using Shaders but I think what's most important is to note these shader examples are really practical unlike a lot of the psychedelic effects you may of seen. For me I especially found that introducing more blend modes has made the process of matching designs in Flash a whole lot easier. I will shortly post a complete list of brand spanking new blend modes for Flash via Shaders with open source code so that everyone can take advantage of these blend modes.
Compiling Shader SWCs with ANT build-files
In my talk I briefly introduced the concept of using Flex to compile to a SWC containing Shaders. If you've used Shaders it's rather annoying you have to load in an exported Shader .pbj file at runtime before you can use a Shader. I really like the idea of having my shaders in a SWC to get around this problem. But this is also useful as a means to distribute your Shaders especially for the Shaders I use often like custom blendModes and some filter effects.
I usually compile SWCs via an ANT buildfile in Eclipse and I will provide this handy script to you as open source code. I like using ANT because it makes it very easy for me to automate the task of creating SWCs then even carrying out other tasks like FTPing.
As well as compiling SWCs and SWFs using ANT I also often publish documentation using these build-files and as my FITC talk briefly covered Javadoc in regard to 'coding conventions' I will also include the source code for how to convert your Javadoc notation to HTML documentation using Flex with asdoc via an ANT build-file.
But before you use these ANT build-files it's important to mention you will need to setup up the appropriate .prefs file to match particular variables to your system.
Here is an example which demonstrates the .prefs file for the SWC ANT build-file
-
compc =/Applications/Flex SDK 4/bin/compc
-
src =/classes
-
outputFile =/swc/TheSWC.swc
Here is the code you may like to use as a reference to compiling your Shader files into a swc
-
package {
-
import flash.display.Shader;
-
import flash.utils.ByteArray;
-
-
public class Shaders {
-
-
[Embed("RippleTransition.pbj", mimeType="application/octet-stream")]
-
private static var RippleTransitionData : Class;
-
-
[Embed("Bloom.pbj", mimeType="application/octet-stream")]
-
private static var BloomData : Class;
-
-
[Embed("BlendModeSoftlight.pbj", mimeType="application/octet-stream")]
-
private static var SoftLightBlendModeData : Class;
-
-
// Transitions
-
public static var rippleTransition : Shader;
-
-
//Lighting
-
public static var bloom : Shader;
-
-
//BlendModes
-
public static var softLightBlendMode : Shader;
-
-
protected static var inited : Boolean = init();
-
-
private static function init() : Boolean {
-
rippleTransition = new Shader(new RippleTransitionData() as ByteArray);
-
-
bloom = new Shader(new BloomData() as ByteArray);
-
-
softLightBlendMode = new Shader(new SoftLightBlendModeData() as ByteArray);
-
-
return true;
-
}
-
}
-
}
Download the handy ANT buildfiles here
If you are interested in writing your own ANT build files read up about this here
FITC Amsterdam Presentation
Thanks for all those who attended my FITC talk 'Efficient Programming Practices for AS3'. I had nightmares hardly anyone would show up but instead the venue was packed with a special mention to the support from the lads at Agency Republic crew - much appreciated!
Despite some early nerves (which I thank you for baring with) the talk covered a lot of practical information regarding efficiency and Actionscript. It's actually the first time I've attended an exclusively Flash conference and 'god damn' I talked at it - pretty cool or terrifying.
If you would like to ask me questions regarding my presentation feel free to do so by email. You can also find out more about my presentation here including references and source code examples.
Lastly I would like to thank Shawn Pucknell the organizer of the FITC. I think everyone who attended would agree that him and his crew have done a fantastic job. He even had time to give me some presentation pointers just before I went up - so thanks mate for going an extra mile. Maybe next time I won't drop the microphone ;)


