Personal tools

Views

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.

<languageVersion : 1.0;> kernel blendmodes <

   namespace : "default";
   vendor : "tvzero";
   version : 1;
   description : "Blendmodes";

> {

   parameter int blendmode <
       minValue:int(0);
       maxValue:int(23);
       defaultValue:int(0);
       description:"Choose Blendmode (0=normal, 1=add, 2=average, ...)";
   >;
   
   input image4 layer1;
   input image4 layer2;
   output pixel4 result;
   
   void evaluatePixel()
   {
       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
       if (blendmode==1) temp = result1;
       // average
       if (blendmode==2) temp = (a+b)/2.0;
       // burn
       if (blendmode==3) temp = 1.0 - (1.0-a)/b;
       // burn soft
       if (blendmode==4) temp = 1.0 - (1.0-b)/a;
       // burn inverse
       if (blendmode==5) temp = 1.0 - (1.0-b)/a;
       // darken
       if (blendmode==6) temp = min(a, b);
       // dodge
       if (blendmode==7) temp = a/(1.0-b);
       // difference
       if (blendmode==8) temp.rgb = abs(a.rgb - b.rgb).rgb;
       // difference exclusion
       if (blendmode==9) temp.rgb = a.rgb + b.rgb - 2.0*a.rgb*b.rgb;
       // dodge inverse
       if (blendmode==10) temp =  a/(1.0-b);
       // difference negation
       if (blendmode==11) temp.rgb = 1.0 - abs(a.rgb - b.rgb);
       // stamp
       if (blendmode==12) temp = a + 2.0*b - 1.0;
       // subtractive
       if (blendmode==13) temp = a+b-1.0;
       // lighten
       if (blendmode==14) temp = max(a, b);
       // multiply
       if (blendmode==15) temp = a*b;
       // screen
       if (blendmode==16) temp = 1.0 - (1.0-a) * (1.0-b);
       // RGB Red
       if (blendmode==17) temp.gb = a.gb;
       // RGB Green
       if (blendmode==18) temp.rb = a.rb;
       // RGB Blue
       if (blendmode==19) temp.rg = a.rg;
       // Overlay (Should actually be componentwise, but seems to work pretty ok using luminance as well):
       if (blendmode==20) {
           if((a.r + a.g + a.b)/3.0 < 0.5 ){
               temp.rgb = float3(2.0,2.0,2.0)*a.rgb*b.rgb;
           }else{
               temp.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).rgb;
           }
       }
       // Soft Light
       if (blendmode==21){
           if(b.r < 0.5){
               temp.r = (2.0 * a.r * b.r) + (a.r * 2.0)*(1.0 - 2.0 * b.r);
           }else{
               temp.r = sqrt(a.r) * (2.0 * b.r - 1.0) + (2.0 * a.r) * (1.0 - b.r);
           }
           
           if(b.g < 0.5){
               temp.g = (2.0 * a.g * b.g) + (a.g * 2.0)*(1.0 - 2.0 * b.g);
           }else{
               temp.g = sqrt(a.g) * (2.0 * b.g - 1.0) + (2.0 * a.g) * (1.0 - b.g);
           }
           if(b.b < 0.5){
               temp.b = (2.0 * a.b * b.b) + (a.b * 2.0)*(1.0 - 2.0 * b.b);
           }else{
               temp.b = sqrt(a.b) * (2.0 * b.b - 1.0) + (2.0 * a.b) * (1.0 - b.b);
           }
       }
       // Hard Light
       if (blendmode==22){
           if(b.r < 0.5){
               temp.r = 2.0*(a.r*b.r);
           }else{
               temp.r =  1.0 - 2.0 * (1.0 - a.r) * (1.0 - b.r);
           }
           
           if(b.g < 0.5){
               temp.g = 2.0*(a.g*b.g);
           }else{
               temp.g = 1.0 - 2.0 * (1.0 - a.g) * (1.0 - b.g);
           }
           if(b.b < 0.5){
               temp.b = 2.0*(a.b*b.b);
           }else{
               temp.b = 1.0 - 2.0 * (1.0 - a.b) * (1.0 - b.b);
           }


       }
       // Dodge Soft
       if (blendmode==23) {
           
           if(a.r+b.r < 1.0){
               temp.r = 0.5*a.r/(1.0 -b.r);
           }else{
               temp.r = 1.0 - 0.5*(1.0 - b.r)/a.r;
           }
           
           if(a.g+b.g < 1.0 ){
               temp.g = 0.5*a.g/(1.0 -b.g);
           }else{
               temp.g = 1.0 - 0.5*(1.0 - b.g)/a.g;
           }
           if(a.b+b.b < 1.0 ){
               temp.b = 0.5*a.b/(1.0 -b.b);
           }else{
               temp.b = 1.0 - 0.5*(1.0 - b.b)/a.b;
           }
           
       }
       result = temp;
   }

}

Retrieved from "http://labs.adobe.com/wiki/index.php/Pixel_Bender_Toolkit:Blendmodes_filter"