守望者--AIR技术交流

标题: 学习一下 Pixel Bender [打印本页]

作者: 破晓    时间: 2014-12-31 09:15
标题: 学习一下 Pixel Bender
Adobe Pixel Bender 是一种编程语言,用于创建或操作图像内容。您可以使用 Pixel Bender 创建一个内核(在本文档中亦称之为着色器)。着色器定义了一个可对图像的每个像素单独执行的单一函数。对该函数的每次调用都将得到图像中该像素坐标处的输 出颜色。可通过指定输入图像和参数值来自定义该操作。在着色器的单次执行中,输入值和参数值是不变的。唯一发生变化的是像素(其颜色是函数调用的结果)的 坐标。
对多个输出像素坐标调用着色器函数时,将尽可能采用并行方式。这样会改进着色器性能,提供高性能的处理能力。
在 Flash Player 和 Adobe AIR 中,使用着色器可轻松创建三种类型的效果:
着色器也可以按独立模式执行。使用独立模式时,将直接访问着色器的结果,而非预先指定着色器的用途。结果可以按图像数据或者二进制或数值数据的形式 访问。该数据完全不必是图像数据。这样一来,您可以为着色器输入一组数据。着色器将处理该数据,然后您可以访问着色器返回的结果数据。

以下是您可能会在 ActionScript 中使用滤镜完成的任务:


首先去下个Pixel BenerToolkit 。界面如下:

[attach]97[/attach]

图2为,代码编辑区:
看一下,Kernel Language 的语法结构:

  1. <languageVersion : 1.0;>  
  2.    
  3.   kernel DoNothing  // 头信息
  4.   
  5.   <  
  6.       namespace: "Adobe::Example";  
  7.       vendor: "Adobe examples";  
  8.       version: 1;  
  9.       description: "A shader that does nothing, but does it well.";   //版本信息
  10.   >  
  11.   {  
  12.       input image4 src; //输入图片源

  13.       output pixel4 dst;  //输出

  14.       parameter float3 color //定义一个float4,输入参数

  15.       <  
  16.           description: "......................";  
  17.       >;  
  18.         
  19.       parameter float alpha  
  20.       <  
  21.           description: "......................";  
  22.       >;  
  23.    
  24.       void evaluatePixel()   // kernel的像素计算
  25.       {  
  26.           dst = sampleNearest(src, outCoord());  
  27.           dst.rgb = color;  
  28.           dst.a = alpha;  
  29.       }  
  30.   }  
复制代码
在 ActionScript 中使用 Pixel Bender 着色器的第一步是在 ActionScript 代码中访问着色器。因为着色器是用 Adobe Pixel Bender 工具包创建并以 Pixel Bender 语言编写的,所以不能在 ActionScript 中直接访问。您需要创建 Shader 类的一个实例,用于向 ActionScript 表示 Pixel Bender 着色器。通过 Shader 对象可以查明着色器的有关信息,如着色器是否需要参数或输入图像值。将 Shader 对象传递给其它对象即可实际使用着色器。例如,若要将着色器用作滤镜,可将 Shader 对象分配给 ShaderFilter 对象的 shader 属性。若要将着色器用作绘制填充,可将 Shader 对象作为参数传递给 Graphics.beginShaderFill() 方法。
ActionScript 代码可以通过两种方式访问由 Adobe Pixel Bender 工具包创建的着色器(.pbj 文件):
在运行时加载:可以使用 URLLoader 对象将着色器文件作为外部资源进行加载。这种方法类似于加载外部资源(如文本文件)。下面的示例演示如何在运行时加载着色器字节码文件并将其链接到一个 Shader 实例:
  1. var loader:URLLoader = new URLLoader();   
  2. loader.dataFormat = URLLoaderDataFormat.BINARY;   
  3. loader.addEventListener(Event.COMPLETE, onLoadComplete);   
  4. loader.load(new URLRequest("myShader.pbj"));   
  5.    
  6. var shader:Shader;   
  7.    
  8. function onLoadComplete(event:Event):void {   
  9.     // Create a new shader and set the loaded data as its bytecode   
  10.     shader = new Shader();   
  11.     shader.byteCode = loader.data;   
  12.       
  13.     // You can also pass the bytecode to the Shader() constructor like this:   
  14.     // shader = new Shader(loader.data);   
  15.       
  16.      // do something with the shader   
  17. }  
复制代码
嵌入在 SWF 文件中:使用 [Embed] 元数据标签可以在编译时将着色器文件嵌入在 SWF 文件中。只有在使用 Flex SDK 编译 SWF 文件时,[Embed] 元数据标签才可用。[Embed] 标签的 source 参数指向着色器文件,其mimeType 参数为"application/octet-stream"
,如此例中所示:

  1. [Embed(source="myShader.pbj", mimeType="application/octet-stream")]   
  2. var MyShaderClass:Class;   
  3.    
  4. // ...   
  5.    
  6. // create a shader and set the embedded shader as its bytecode   
  7. var shaderShader = new Shader();   
  8. shader.byteCode = new MyShaderClass();   
  9.    
  10. // You can also pass the bytecode to the Shader() constructor like this:   
  11. // var shader:Shader = new Shader(new MyShaderClass());   
  12.    
  13. // do something with the shader  
复制代码
在任何一种情况下,都可以将原始着色器字节码(URLLoader.data 属性或 [Embed] 数据类的实例)链接到 Shader 实例。如以上示例所示,可以通过两种方式将字节码分配给 Shader 实例。可以将着色器字节代码作为参数传递到Shader() 构造函数。或者,可以将其设置为 Shader 实例的 byteCode 属性。在创建 Pixel Bender 着色器并将其链接到 Shader 对象后,即可使用着色器以多种方式创建效果。您可以将着色器用作滤镜、混合模式、位图填充,也可以用于位图或其它数据的独立处理。您还可以使用 Shader 对象的 data属性访问着色器的元数据、指定输入图像以及设置参数值。 使用着色器作为绘制填充在使用着色器创建绘制填充时,您将使用绘图 API 方法来创建矢量形状。正如使用绘图 API 可将任何位图图像用作位图填充一样,着色器的输出将用于填充该形状。若要创建着色器填充,可在代码中开始绘制形状的位置处,调用 Graphics 对象的 beginShaderFill() 方法。将 Shader 对象作为第一个参数传递给 beginShaderFill()方法,如以下清单所示:
  1. var canvas:Sprite = new Sprite();   
  2. canvas.graphics.beginShaderFill(myShader);   
  3. canvas.graphics.drawRect(10, 10, 150, 150);   
  4. canvas.graphics.endFill();   
  5. // add canvas  
复制代码
[attach]98[/attach]
  1. <languageVersion : 1.0;>   
  2. kernel ThreePointGradient   
  3. <   
  4.     namespace : "Petri Leskinen::Example";   
  5.     vendor : "Petri Leskinen";   
  6.     version : 1;   
  7.     description : "Creates a gradient fill using three specified points and colors.";   
  8. >   
  9. {   
  10.     parameter float2 point1 // coordinates of the first point   
  11.     <   
  12.         minValue:float2(0, 0);   
  13.         maxValue:float2(4000, 4000);   
  14.         defaultValue:float2(0, 0);   
  15.     >;   
  16.       
  17.     parameter float4 color1 // color at the first point, opaque red by default   
  18.     <   
  19.         defaultValue:float4(1.0, 0.0, 0.0, 1.0);   
  20.     >;   
  21.       
  22.     parameter float2 point2 // coordinates of the second point   
  23.     <   
  24.         minValue:float2(0, 0);   
  25.         maxValue:float2(4000, 4000);   
  26.         defaultValue:float2(0, 500);   
  27.     >;   
  28.       
  29.     parameter float4 color2 // color at the second point, opaque green by default   
  30.     <   
  31.         defaultValue:float4(0.0, 1.0, 0.0, 1.0);   
  32.     >;   
  33.       
  34.     parameter float2 point3 // coordinates of the third point   
  35.     <   
  36.         minValue:float2(0, 0);   
  37.         maxValue:float2(4000, 4000);   
  38.         defaultValue:float2(0, 500);   
  39.     >;   
  40.       
  41.     parameter float4 color3 // color at the third point, opaque blue by default   
  42.     <   
  43.         defaultValue:float4(0.0, 0.0, 1.0, 1.0);   
  44.     >;   
  45.       
  46.     output pixel4 dst;   
  47.       
  48.     void evaluatePixel()   
  49.     {   
  50.         float2 d2 = point2 - point1;   
  51.         float2 d3 = point3 - point1;   
  52.            
  53.         // transformation to a new coordinate system   
  54.         // transforms point 1 to origin, point2 to (1, 0), and point3 to (0, 1)   
  55.         float2x2 mtrx = float2x2(d3.y, -d2.y, -d3.x, d2.x) / (d2.x * d3.y - d3.x * d2.y);   
  56.         float2 pNew = mtrx * (outCoord() - point1);   
  57.            
  58.         // repeat the edge colors on the outside   
  59.         pNew.xy = clamp(pNew.xy, 0.0, 1.0); // set the range to 0.0 ... 1.0   
  60.            
  61.         // interpolating the output color or alpha value   
  62.         dst = mix(mix(color1, color2, pNew.x), color3, pNew.y);   
  63.     }   
  64. }  
复制代码
  1. package   
  2. {   
  3.     import flash.display.Shader;   
  4.     import flash.display.Sprite;   
  5.     import flash.events.Event;   
  6.     import flash.geom.Point;   
  7.     import flash.net.URLLoader;   
  8.     import flash.net.URLLoaderDataFormat;   
  9.     import flash.net.URLRequest;   
  10.       
  11.     public class ThreePointGradient extends Sprite   
  12.     {   
  13.         private var canvas:Sprite;   
  14.         private var shader:Shader;   
  15.         private var loader:URLLoader;   
  16.            
  17.         private var topMiddle:Point;   
  18.         private var bottomLeft:Point;   
  19.         private var bottomRight:Point;   
  20.            
  21.         private var colorAngle:Number = 0.0;   
  22.         private const d120:Number = 120 / 180 * Math.PI; // 120 degrees in radians   
  23.            
  24.            
  25.         public function ThreePointGradient()   
  26.         {   
  27.             init();   
  28.         }   
  29.            
  30.         private function init():void   
  31.         {   
  32.             canvas = new Sprite();   
  33.             addChild(canvas);   
  34.                
  35.             var size:int = 400;   
  36.             topMiddle = new Point(size / 2, 10);   
  37.             bottomLeft = new Point(0, size - 10);   
  38.             bottomRight = new Point(size, size - 10);   
  39.                
  40.             loader = new URLLoader();   
  41.             loader.dataFormat = URLLoaderDataFormat.BINARY;   
  42.             loader.addEventListener(Event.COMPLETE, onLoadComplete);   
  43.             loader.load(new URLRequest("ThreePointGradient.pbj"));   
  44.         }   
  45.            
  46.         private function onLoadComplete(event:Event):void   
  47.         {   
  48.             shader = new Shader(loader.data);   
  49.                
  50.             shader.data.point1.value = [topMiddle.x, topMiddle,y];   
  51.             shader.data.point2.value = [bottomLeft.x, bottomLeft.y];   
  52.             shader.data.point3.value = [bottomRight.x, bottomRight.y];   
  53.                
  54.             addEventListener.Event.ENTER_FRAME, updateShaderFill);   
  55.         }   
  56.            
  57.         private function updateShaderFill(event:Event):void   
  58.         {   
  59.             colorAngle += .06;   
  60.                
  61.             var c1:Number = 1 / 3 + 2 / 3 * Math.cos(colorAngle);   
  62.             var c2:Number = 1 / 3 + 2 / 3 * Math.cos(colorAngle + d120);   
  63.             var c3:Number = 1 / 3 + 2 / 3 * Math.cos(colorAngle - d120;   
  64.                
  65.             shader.data.color1.value = [c1, c2, c3, 1.0];   
  66.             shader.data.color2.value = [c3, c1, c2, 1.0];   
  67.             shader.data.color3.value = [c2, c3, c1, 1.0];   
  68.                
  69.             canvas.graphics.clear();   
  70.             canvas.graphics.beginShaderFill(shader);   
  71.                
  72.             canvas.graphics.moveTo(topMiddle.x, topMiddle.y);   
  73.             canvas.graphics.lineTo(bottomLeft.x, bottomLeft.y);   
  74.             canvas.graphics.lineTo(bottomRight.x, bottomLeft.y);   
  75.                
  76.             canvas.graphics.endFill();   
  77.         }   
  78.     }   
  79. }  
复制代码
使用着色器作为混合模式 使用着色器作为混和模式与使用其它混和模式类似。着色器定义的外观取决于将两个显示对象混和在一起的视觉效果。若要将着色器用于混和模式,请将 Shader 对象指派给前景显示对象的 blendShader 属性。如果为blendShader 属性指定非 null 值,显示对象的 blendMode 属性将自动设置为 BlendMode.SHADER 。下面的清单演示如何使用着色器作为混和模式。注意,此示例假定存在名为 foreground 的显示对象。该对象与其它显示内容包含在显示列表的同一父级中,而 foreground与其它内容重叠: foreground.blendShader = myShader; 使用着色器作为混和模式时,着色器必须由至少两个输入定义。如示例所示,您未在代码中设置输入值。而是将两个混和后的图像自动用作着色器的输入。前 景图像设置为第二个图像。(此显示对象便是要对其应用混和模式的对象。)背景图像由前景图像边框后的所有像素组合而成。背景图像设置为第一个输入图像。如 果所用着色器要求两个以上的输入,则还需为前两个之外的其它输入提供值。下面的示例演示如何使用着色器作为混和模式。此示例使用基于亮度的加亮混和模式。混和的结果是以任一混和对象中最亮的像素值显示该像素。注: 此示例的代码由 Mario Klingemann 编写。感谢 Mario 分享此示例。若要查看 Mario 的更多作品及阅读他的文章,请访问 www.quasimondo.com/ 。
这段重要的 ActionScript 代码用到下面两个方法:






欢迎光临 守望者--AIR技术交流 (http://www.airmyth.com/)