Pixel Bender Toolkit:Blendmodes filter
From Adobe Labs
// http://www.pegtop.net/delphi/articles/blendmodes/ // Note: this is just for convenience, each blendmode would normally be contained in a separate .hydro file. kernel blendmodes {
parameter int blendmode <
minValue:int(0);
maxValue:int(23);
defaultValue:int(0);
description:"Choose Blendmode (0=normal, 1=add, 2=average, ...)";
>;
void evaluatePixel(in image4 layer1, in image4 layer2, out pixel4 result)
{
pixel4 a = sampleNearest(layer1, outCoord());
pixel4 b = sampleNearest(layer2, outCoord());
pixel4 temp = b;
// "astro" would require the results to be defined in single variables:
pixel4 result1 = a+b;
// additive
temp = (blendmode==1) ? result1 : temp;
// average
temp = (blendmode==2) ? (a+b)/2.0 : temp;
// burn
temp = (blendmode==3) ? 1.0 - (1.0-a)/b : temp;
// burn soft
temp = (blendmode==4) ? 1.0 - (1.0-b)/a : temp;
// burn inverse
temp = (blendmode==5) ? 1.0 - (1.0-b)/a : temp;
// darken
temp = (blendmode==6) ? min(a, b) : temp;
// dodge
temp = (blendmode==7) ? a/(1.0-b) : temp;
// difference
temp.rgb = (blendmode==8) ? abs(a.rgb - b.rgb) : temp.rgb;
// difference exclusion
temp.rgb = (blendmode==9) ? a.rgb + b.rgb - 2.0*a.rgb*b.rgb : temp.rgb;
// dodge inverse
temp = (blendmode==10) ? a/(1.0-b) : temp;
// difference negation
temp.rgb = (blendmode==11) ? 1.0 - abs(a.rgb - b.rgb) : temp.rgb;
// stamp
temp = (blendmode==12) ? a + 2.0*b - 1.0 : temp;
// subtractive
temp = (blendmode==13) ? a+b-1.0 : temp;
// lighten
temp = (blendmode==14) ? max(a, b) : temp;
// multiply
temp = (blendmode==15) ? a*b : temp;
// screen
temp = (blendmode==16) ? 1.0 - (1.0-a) * (1.0-b) : temp;
// RGB Red
temp.gb = (blendmode==17) ? a.gb : temp.gb;
// RGB Green
temp.rb = (blendmode==18) ? a.rb : temp.rb;
// RGB Blue
temp.rg = (blendmode==19) ? a.rg : temp.rg;
// Overlay (Should actually be componentwise, but seems to work pretty ok using luminance as well):
temp.rgb = (blendmode==20) ? ( (a.r + a.g + a.b)/3.0 < 0.5 ) ? float3(2.0,2.0,2.0)*a.rgb*b.rgb : float3(1.0,1.0,1.0) - float3(2.0,2.0,2.0) * (float3(1.0,1.0,1.0) - a.rgb) * (float3(1.0,1.0,1.0) - b.rgb) : temp.rgb;
// Soft Light
temp.r = (blendmode==21) ? b.r < 0.5 ? (2.0 * a.r * b.r) + (a.r * 2.0)*(1.0 - 2.0 * b.r) : sqrt(a.r) * (2.0 * b.r - 1.0) + (2.0 * a.r) * (1.0 - b.r) : temp.r;
temp.g = (blendmode==21) ? b.g < 0.5 ? (2.0 * a.g * b.g) + (a.g * 2.0)*(1.0 - 2.0 * b.g) : sqrt(a.g) * (2.0 * b.g - 1.0) + (2.0 * a.g) * (1.0 - b.g) : temp.g;
temp.b = (blendmode==21) ? b.b < 0.5 ? (2.0 * a.b * b.b) + (a.b * 2.0)*(1.0 - 2.0 * b.b) : sqrt(a.b) * (2.0 * b.b - 1.0) + (2.0 * a.b) * (1.0 - b.b) : temp.b;
// Hard Light
temp.r = (blendmode==22) ? b.r < 0.5 ? 2.0*(a.r*b.r) : 1.0 - 2.0 * (1.0 - a.r) * (1.0 - b.r) : temp.r;
temp.g = (blendmode==22) ? b.g < 0.5 ? 2.0*(a.g*b.g) : 1.0 - 2.0 * (1.0 - a.g) * (1.0 - b.g) : temp.g;
temp.b = (blendmode==22) ? b.b < 0.5 ? 2.0*(a.b*b.b) : 1.0 - 2.0 * (1.0 - a.b) * (1.0 - b.b) : temp.b;
// Dodge Soft
temp.r = (blendmode==23) ? a.r+b.r < 1.0 ? 0.5*a.r/(1.0 -b.r) : 1.0 - 0.5*(1.0 - b.r)/a.r : temp.r;
temp.g = (blendmode==23) ? a.g+b.g < 1.0 ? 0.5*a.g/(1.0 -b.g) : 1.0 - 0.5*(1.0 - b.g)/a.g : temp.g;
temp.b = (blendmode==23) ? a.b+b.b < 1.0 ? 0.5*a.b/(1.0 -b.b) : 1.0 - 0.5*(1.0 - b.b)/a.b : temp.b;
result = temp; }
}
