第四章 Basic Shaders

来源:互联网 发布:极米投影仪怎么样 知乎 编辑:程序博客网 时间:2024/05/17 03:02
1、AGAL: Adobe Graphics Assembly Language

    在3D图形中,术语shader被普遍使用,通常我们把vertex program称为顶点着色器,    fragment program称为像素着色器或片段着色器。Vertex and fragment
    programs 执行效率非常快,每秒执百万次,是因为它们运行于显卡上(GPU),
    vertex program 会把模型上的每个顶点都执行一次,fragment program 则是每个
    像素都执行一次。

2、AGAL是什么样子的

    <opcode> <destination> <source 1> <source 2>
    <opcode>操作码
    <destination>目标,计算结果存放处
     <source1><source2>需要计算的源对像

    AGAL只有大约30个不同的操作码,下面是几个常用的命令:

    mov  (copies data from source1 to destination)  
    add  (destination = source1 plus source2)  
    sub  (destination = source1 minus source2)  
    mul  (destination = source1 multiplied by source2)  
    div  (destination = source1 divided by source2)

    一般加减乘除可以这样 add source1 source2 意为source1 += source2

3、什么是寄存器

    前面的例子中的destination和source称为寄存器,你可以把它当成是用来存放数据的变
    量。
    在AGAL,寄存器是有限的,如果你创建的着色器较多,寄存器将会被用完,所以必须要
    重复使用有限的寄存器。
    寄存器都是128位的,可以存放4个32位浮点数(Number类型)。
    不同的寄存器负责不同的工作,例如:va寄存器有8个,v0,v1,v2,v3,v4,v5,v6,v7.

    mov v0,va1    就是把va1的值复制到v0,v0是8个varying寄存器中的一个。

4、什么是分量

    每个寄存器都有4个值,叫分量,可以通过xyzw或rgba访问,例如:va1.x等同于va1.r,
    都是访问寄存器的第一个分量。
    顶点着色器的寄存器分量用xyzw访问,片段着色器的寄存器分量用rgba访问。

    例如:so1 = vector3D (10,100,50,0)
            so2 = vector3D (5,1,3,0)
            add so1,so2

    结果:so1 的值为(15,101,53,0),就是把so1与so2的xyzw对应相加,赋值给so1.

5、Vertex attribute registers: va0..va7

    顶点属性寄存器
    这些寄存器分配到VertexBuffer里的特定位置,它们只是顶点着色器的变量。当你要上传你
    的模型数据时,可以包括xyz坐标
    和其他的Number型数据,一般这些数据包括UV坐标,法线,rgb颜色和其他你想分配到每
    个顶点的数据。
    使用带适当索引的函数Context3D:setVertexBufferAt(),可以把VertexBuffer分配到指
    定的属性寄存器,例如,在字节数组中
    前面的3个数是xyz值,访问属性寄存器语法,va<n>,n就是属性寄存器的索引号,那么
    va0就指向每个顶点的位置xyz值。

    在顶点着色器中,总共有8个属性寄存器,分别为va0,va1,va2,va3,va4,va5,va6,va7。

6、Constant registers: vc0..vc127 and fc0..fc27

    常量寄存器
    这些寄存器是由AS3的Context3D::setProgramConstants方法把参数发送到着色器。
    在顶点着色器中有128个常量寄存器
    ,用vc<n>访问,像素着色器中有28个常量寄存器,用fc<n>访问,n是常量寄存器的索引,
   例如在设定灯光方向或雾的颜色等需要用到。

    7、Temporary registers: vt0..vt7 and ft0..ft7
    临时寄存器
    顶点和像素着色器各有8个临时寄存器,以用于存储临时计算结果,顶点访问vt0~vt7,像素
    访问ft0~ft7。

    8、Output registers: op and oc
    输出寄存器
    op for output position and  oc for output color
    存放顶点和像素着色器的最终计算结果,顶点着色器输出的是顶点的空间坐标位置,像素
   着色器输出的是像素的颜色,它们都只有一个输出寄存器。

    9、Varying registers: v0..v7
    变量寄存器
    这些寄存器是把数据从顶点着色器传递到像素着色器,这些数据会经过GPU插值,因此,
    像素着色器收到的是被处理过的正确的值。典型的数据包括顶点的颜色与纹理的UV坐标,
    可通过v<n>访问,n是索引,总共有8个变量寄存器。
    例如:在顶点着色器中,通过摄像机与雾的距离计算顶点的颜色,把这些数据传递给
    像素着色器,像素着色器会把这些数据插值处理,以使这些颜色能够平滑过渡。

    10、Texture samplers: fs0..fs7
    纹理采样器
    这8个纹理采样寄存器是基于UV坐标从纹理中拾取颜色值的,有自己的设置规则,仅用于像
    素着色器,通过 Context3D::setTextureAt()来指定纹理。
    例如一个标准的2D贴图 没有 mip mapping 加入了线性滤镜 linear filtering ,会取样到
    临时寄存器 ft1,变量寄存器v0是存放经过插值的纹理UV坐标:

    tex ft1, v0, fs0 <2d,linear,nomip>
    使用语法:ft<n> <flags>,n是索引值,<flags>则是通过字符串来设置如何取样。
   
    纹理尺寸:2d, 3d, or cube
        2d就不用说了,3d是带深度,cube则是由6矩形位图编码成一组,通常用于反光
        (reflections,不知道怎么翻译),每张图片都有特定的方向,类似一个盒子的内部的面一样。

    mip mapping:  nomip,  mipnone,  mipnearest, or  miplinear
        使用mip maps时,stage3D会把纹理进行平滑插值,把位图变成2的n次方大小的多张
        图组成的金字塔状,用于复杂的渲染。
        详细可以百度或谷歌 mipmap。

    纹理滤镜:nearest or  linear
        使用 nearest ,当你近距离观看时,stage3D不会对其进行平滑插值,以生成4角形
        的纹理;
        使用 linear ,当对其进行缩放时,stage3D会对其进行模糊和平滑边界。

    纹理重复:repeat,  wrap, or  clamp

        使用 repeat ,可以使纹理平铺;
        使用 clamp , 当你不想使用纹理平铺,并且在运行中遇到边缘像素变成背面边缘的
        颜色的问题时,(通常在透明粒子和在渲染3d中的位图字体时会发生),会强制
        stage3D不对相邻的边缘像素进行模糊。

11、A basic AGAL shader example
    (1)The vertex program
    每个顶点运行一次
    Here is your first taste of AGAL: a simple vertex program.
        // the simplest possible vertex program
        m44 op, va0, vc0       // pos to clipspace
        mov v0, va1           // copy uv

    第一行代码,是一个4x4矩阵乘法,由有4个分量的Vector3D va0乘以一个 4x4 Matrix3D
   vc0(vc0定义了顶点位置与摄像机的
    关系,由 setProgramConstantsFromMatrix 方法设置),计算结果存放到op。 第二行
   代码,是把存放UV坐标的va1 复制到v0

    (2)The fragment program
      每个像素运行一次  
      This is an example of a very simple fragment program:
        // a simple fragment program
        tex ft1, v0, fs0 <2d,linear,nomip>
        mov oc, ft1

    第一行代码,操作码 tex 执行纹理查找, fs0由setTextureAt()设置,v0存放了UV坐标,
    用于查找纹理中最近的像素,并经过线性插值,不使用mipmaps 来得到像素的r,g,b,a颜色,
    存放在临时寄存器ft1中。
    第二行代码,就是把ft1 复制到 oc 以输出。

12、Compiling the AGAL source code
    在写的a vertex program and a fragment program 时需要用到adobe的类
   AGALMiniAssembler 来把AGAL编译成字节码上传到显卡,接下来都是说代码的,省略,
   直接在详细代码中说好了。

13、Creating a shader demo
都是比较基础的英文,就不翻译了
  1. package
  2. {
  3.         import com.adobe.utils.AGALMiniAssembler;
  4.         import com.adobe.utils.PerspectiveMatrix3D;
  5.         import flash.display.Bitmap;
  6.         import flash.display.BitmapData;
  7.         import flash.display.Sprite;
  8.         import flash.display.Stage3D;
  9.         import flash.display.StageAlign;
  10.         import flash.display.StageScaleMode;
  11.         import flash.display3D.Context3D;
  12.         import flash.display3D.Context3DProgramType;
  13.         import flash.display3D.Context3DTextureFormat;
  14.         import flash.display3D.Context3DVertexBufferFormat;
  15.         import flash.display3D.IndexBuffer3D;
  16.         import flash.display3D.Program3D;
  17.         import flash.display3D.textures.Texture;
  18.         import flash.display3D.VertexBuffer3D;
  19.         import flash.events.Event;
  20.         import flash.geom.Matrix;
  21.         import flash.geom.Matrix3D;
  22.         import flash.geom.Vector3D;
  23.         import flash.text.TextField;
  24.         import flash.text.TextFieldAutoSize;
  25.         import flash.text.TextFormat;
  26.         import flash.utils.getTimer;
  27.         
  28.         /**
  29.          * ...
  30.          * @author lanphone
  31.          */
  32.         [SWF(width=&quot;640&quot;, height=&quot;480&quot;, frameRate=&quot;60&quot;)]
  33.         public class Main extends Sprite
  34.         {
  35.                 //用于显示fps
  36.                 private var fpsLast:uint = getTimer();
  37.                 private var fpsTicks:uint = 0;
  38.                 private var fpsTf:TextField;
  39.                
  40.                 private const swfWidth:int = 640;
  41.                 private const swfHeight:int = 480;
  42.                 private const textureSize:int = 512;
  43.                
  44.                 private var context3D:Context3D;
  45.                 //编译shader用于渲染
  46.                 private var shaderProgram1:Program3D;
  47.                 private var shaderProgram2:Program3D;
  48.                 private var shaderProgram3:Program3D;
  49.                 private var shaderProgram4:Program3D;
  50.                 //顶点缓冲
  51.                 private var vertexBuffer:VertexBuffer3D;
  52.                 //索引缓冲
  53.                 private var indexBuffer:IndexBuffer3D;
  54.                 //顶点数据
  55.                 private var meshVertexData:Vector.&lt;Number&gt;;
  56.                 //索引数据
  57.                 private var meshIndexData:Vector.&lt;uint&gt;;
  58.                 //影响顶点位置与摄像机角度的矩阵
  59.                 private var projectionmatrix:PerspectiveMatrix3D = new PerspectiveMatrix3D();
  60.                 private var modelmatrix:Matrix3D = new Matrix3D();
  61.                 private var viewmatrix:Matrix3D = new Matrix3D();
  62.                 private var modelViewmatrix:Matrix3D = new Matrix3D();
  63.                 //计数器
  64.                 private var t:Number = 0;
  65.                 private var looptemp:int = 0;
  66.                
  67.                 [Embed(source = &quot;bit.jpg&quot;)] private const myTextureBitmap:Class;
  68.                 private var myTextureData:Bitmap = new myTextureBitmap();
  69.                 private var myTexture:Texture;
  70.                
  71.                
  72.                 public function Main():void
  73.                 {
  74.                         if (stage) init();
  75.                         else addEventListener(Event.ADDED_TO_STAGE, init);
  76.                 }
  77.                
  78.                 private function init(e:Event = null):void
  79.                 {
  80.                         removeEventListener(Event.ADDED_TO_STAGE, init);
  81.                         stage.scaleMode = StageScaleMode.NO_SCALE;
  82.                         stage.align = StageAlign.TOP_LEFT;
  83.                         initGUI();
  84.                         stage.stage3Ds[0].addEventListener(Event.CONTEXT3D_CREATE, onContext3DCreate);
  85.                         stage.stage3Ds[0].requestContext3D();
  86.                 }
  87.                
  88.                 private function initGUI():void
  89.                 {
  90.                         // a text format descriptor used by all gui labels
  91.                           var myFormat:TextFormat = new TextFormat();  
  92.                           myFormat.color = 0xFFFFFF;
  93.                           myFormat.size = 13;
  94.                           // create an FPSCounter that displays the framerate on screen
  95.                           fpsTf = new TextField();
  96.                           fpsTf.x = 0;
  97.                           fpsTf.y = 0;
  98.                           fpsTf.selectable = false;
  99.                           fpsTf.autoSize = TextFieldAutoSize.LEFT;
  100.                           fpsTf.defaultTextFormat = myFormat;
  101.                           fpsTf.text = &quot;Initializing Stage3d...&quot;;
  102.                           addChild(fpsTf);
  103.                           // add some labels to describe each shader
  104.                           var label1:TextField = new TextField();
  105.                           label1.x = 100;
  106.                           label1.y = 180;
  107.                           label1.selectable = false;  
  108.                           label1.autoSize = TextFieldAutoSize.LEFT;  
  109.                           label1.defaultTextFormat = myFormat;
  110.                           label1.text = &quot;Shader 1: Textured&quot;;
  111.                           addChild(label1);
  112.                           
  113.                           var label2:TextField = new TextField();
  114.                           label2.x = 400;
  115.                           label2.y = 180;
  116.                
  117.                           label2.selectable = false;
  118.                           label2.autoSize = TextFieldAutoSize.LEFT;  
  119.                           label2.defaultTextFormat = myFormat;
  120.                           label2.text = &quot;Shader 2: Vertex RGB&quot;;
  121.                           addChild(label2);
  122.                           
  123.                           var label3:TextField = new TextField();
  124.                           label3.x = 80;
  125.                           label3.y = 440;
  126.                           label3.selectable = false;  
  127.                           label3.autoSize = TextFieldAutoSize.LEFT;  
  128.                           label3.defaultTextFormat = myFormat;
  129.                           label3.text = &quot;Shader 3: Vertex RGB + Textured&quot;;
  130.                           addChild(label3);
  131.                           
  132.                           var label4:TextField = new TextField();
  133.                           label4.x = 340;
  134.                           label4.y = 440;
  135.                           label4.selectable = false;  
  136.                           label4.autoSize = TextFieldAutoSize.LEFT;  
  137.                           label4.defaultTextFormat = myFormat;
  138.                           label4.text = &quot;Shader 4: Textured + setProgramConstants&quot;;
  139.                           addChild(label4);
  140.                 }
  141.                
  142.                 private function onContext3DCreate(event:Event):void
  143.                 {
  144.                         // Remove existing frame handler. Note that a context
  145.                         // loss can occur at any time which will force you
  146.                         // to recreate all objects we create here.
  147.                         // A context loss occurs for instance if you hit
  148.                         // CTRL-ALT-DELETE on Windows.      
  149.                         // It takes a while before a new context is available
  150.                         // hence removing the enterFrame handler is important!
  151.                          removeEventListener(Event.ENTER_FRAME,enterFrame);
  152.                           
  153.                          // Obtain the current context
  154.                          var t:Stage3D = event.target as Stage3D;         
  155.                          context3D = t.context3D;   
  156.                          if (context3D == null)
  157.                          {
  158.                                 // Currently no 3d context is available (error!)
  159.                                 return;
  160.                          }
  161.                         // Disabling error checking will drastically improve performance.
  162.                         // If set to true, Flash sends helpful error messages regarding
  163.                         // AGAL compilation errors, uninitialized program constants, etc.
  164.                         context3D.enableErrorChecking = true;
  165.                          // Initialize our mesh data
  166.                           initData();                          
  167.                           // The 3d back buffer size is in pixels
  168.                           context3D.configureBackBuffer(swfWidth, swfHeight, 0, true);
  169.                           // assemble all the shaders we need
  170.                           initShaders();
  171.                           // upload the mesh indexes
  172.                           indexBuffer = context3D.createIndexBuffer(meshIndexData.length);
  173.                           indexBuffer.uploadFromVector(meshIndexData, 0, meshIndexData.length);
  174.                           // upload the mesh vertex data
  175.                           // since our particular data is
  176.                           // x, y, z, u, v, nx, ny, nz, r, g, b, a
  177.                           // each vertex uses 12 array elements
  178.                           vertexBuffer = context3D.createVertexBuffer(meshVertexData.length / 12, 12);
  179.                           vertexBuffer.uploadFromVector(meshVertexData, 0, meshVertexData.length / 12);
  180.                           // Generate mipmaps
  181.                           myTexture = context3D.createTexture(textureSize, textureSize, Context3DTextureFormat.BGRA, false);
  182.                          uploadTextureWithMipmaps(myTexture, myTextureData.bitmapData);
  183.                           // create projection matrix for our 3D scene
  184.                           projectionmatrix.identity();
  185.                           // 45 degrees FOV, 640/480 aspect ratio, 0.01=near, 100=far
  186.                           projectionmatrix.perspectiveFieldOfViewRH(45, swfWidth / swfHeight, 0.01, 100);
  187.                           // create a matrix that defines the camera location
  188.                                 viewmatrix.identity();
  189.                           // move the camera back a little so we can see the mesh
  190.                           viewmatrix.appendTranslation(0, 0, -10);                          
  191.                           // start animating
  192.                           addEventListener(Event.ENTER_FRAME,enterFrame);
  193.                 }
  194.                 public function uploadTextureWithMipmaps(dest:Texture, src:BitmapData):void
  195.                 {
  196.                         var ws:int = src.width;
  197.                         var hs:int = src.height;
  198.                         var level:int = 0;
  199.                         var tmp:BitmapData;
  200.                         var transform:Matrix = new Matrix();
  201.                  
  202.                         tmp = new BitmapData(src.width, src.height, true, 0x00000000);
  203.                  
  204.                         while ( ws &gt;= 1 &amp;&amp; hs &gt;= 1 )
  205.                         {
  206.                                 tmp.draw(src, transform, null, null, null, true);
  207.                                 dest.uploadFromBitmapData(tmp, level);
  208.                                 transform.scale(0.5, 0.5);
  209.                                 level++;
  210.                                 ws &gt;&gt;= 1;
  211.                                 hs &gt;&gt;= 1;
  212.                                 if (hs &amp;&amp; ws)
  213.                                 {
  214.                                         tmp.dispose();
  215.                                         tmp = new BitmapData(ws, hs, true, 0x00000000);
  216.                                 }
  217.                         }
  218.                         tmp.dispose();
  219.                 }
  220.                 private function enterFrame(e:Event):void
  221.                 {
  222.                         // clear scene before rendering is mandatory
  223.                         context3D.clear(0, 0, 0);
  224.                         // rotate more next frame
  225.                         t += 2.0;
  226.                           
  227.                         // loop through each mesh we want to draw
  228.                         for (looptemp = 0; looptemp &lt; 4; looptemp ++)
  229.                         {
  230.                                 // clear the transformation matrix to 0,0,0
  231.                                 modelmatrix.identity();
  232.                                 
  233.                                 // each mesh has a different texture,
  234.                                 // shader, position and spin speed        
  235.                                 switch (looptemp)
  236.                                 {
  237.                                         case 0:
  238.                                                 context3D.setTextureAt(0, myTexture);
  239.                                                 context3D.setProgram ( shaderProgram1 );
  240.                                                 modelmatrix.appendRotation(t*0.7, Vector3D.Y_AXIS);
  241.                                                 modelmatrix.appendRotation(t*0.6, Vector3D.X_AXIS);
  242.                                                 modelmatrix.appendRotation(t*1.0, Vector3D.Y_AXIS);
  243.                                                 modelmatrix.appendTranslation(-3, 3, 0);
  244.                                                 break;
  245.                                         case 1:
  246.                                                 context3D.setTextureAt(0, null);
  247.                                                 context3D.setProgram ( shaderProgram2 );
  248.                                                 modelmatrix.appendRotation(t*-0.2, Vector3D.Y_AXIS);
  249.                                                 modelmatrix.appendRotation(t*0.4, Vector3D.X_AXIS);
  250.                                                 modelmatrix.appendRotation(t*0.7, Vector3D.Y_AXIS);
  251.                                                 modelmatrix.appendTranslation(3, 3, 0);
  252.                                                 break;
  253.                                         case 2:
  254.                                                 context3D.setTextureAt(0, myTexture);
  255.                                                 context3D.setProgram ( shaderProgram3 );
  256.                                                 modelmatrix.appendRotation(t*1.0, Vector3D.Y_AXIS);
  257.                                                 modelmatrix.appendRotation(t*-0.2, Vector3D.X_AXIS);
  258.                                                 modelmatrix.appendRotation(t*0.3, Vector3D.Y_AXIS);
  259.                                                 modelmatrix.appendTranslation(-3, -3, 0);
  260.                                                 break;
  261.                                         case 3:
  262.                                                 context3D.setProgramConstantsFromVector(
  263.                                                   Context3DProgramType.FRAGMENT, 0, Vector.&lt;Number&gt;
  264.                                                   ([ 1, Math.abs(Math.cos(t/50)), 0, 1 ]) );
  265.                                                 context3D.setTextureAt(0, myTexture);
  266.                                                 context3D.setProgram ( shaderProgram4 );
  267.                                                 modelmatrix.appendRotation(t*0.3, Vector3D.Y_AXIS);
  268.                                                 modelmatrix.appendRotation(t*0.3, Vector3D.X_AXIS);
  269.                                                 modelmatrix.appendRotation(t*-0.3, Vector3D.Y_AXIS);
  270.                                                 modelmatrix.appendTranslation(3, -3, 0);
  271.                                                 break;
  272.                                 }
  273.                                  // clear the matrix and append new angles
  274.                                  modelViewmatrix.identity();
  275.                                  modelViewmatrix.append(modelmatrix);
  276.                                  modelViewmatrix.append(viewmatrix);
  277.                                  modelViewmatrix.append(projectionmatrix);
  278.                                  
  279.                                  // pass our matrix data to the shader program
  280.                                  context3D.setProgramConstantsFromMatrix(
  281.                                    Context3DProgramType.VERTEX,
  282.                                    0, modelViewmatrix, true );
  283.                                 // associate the vertex data with current shader program
  284.                                 // position
  285.                                 context3D.setVertexBufferAt(0, vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);   
  286.                                 // tex coord
  287.                                 context3D.setVertexBufferAt(1, vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);  
  288.                                 // vertex rgba
  289.                                 context3D.setVertexBufferAt(2, vertexBuffer, 8, Context3DVertexBufferFormat.FLOAT_4);  
  290.                                 // finally draw the triangles
  291.                                 context3D.drawTriangles(indexBuffer, 0, meshIndexData.length / 3);
  292.                         }
  293.                         // present/flip back buffer
  294.                         // now that all meshes have been drawn
  295.                         context3D.present();
  296.                         //update the fps display
  297.                         fpsTicks ++;
  298.                         var now:uint = getTimer();
  299.                         var delta:uint = now - fpsLast;
  300.                         if (delta &gt;= 1000)
  301.                         {
  302.                                 var fps:Number = fpsTicks / delta * 1000;
  303.                                 fpsTf.text = fps.toFixed(1) + &quot; fps&quot;;
  304.                                 fpsTicks  = 0;
  305.                                 fpsLast = now;
  306.                         }
  307.                 }
  308.                
  309.                 private function initShaders():void
  310.                 {
  311.                         // A simple vertex shader which does a 3D transformation
  312.                         // for simplicity, it is used by all four shaders
  313.                         var vertexShaderAssembler:AGALMiniAssembler = new AGALMiniAssembler();
  314.                         vertexShaderAssembler.assemble
  315.                         (
  316.                                 Context3DProgramType.VERTEX,
  317.                                 // 4x4 matrix multiply to get camera angle
  318.                                 &quot;m44 op, va0, vc0\n&quot; +
  319.                                 // tell fragment shader about XYZ
  320.                                 &quot;mov v0, va0\n&quot; +
  321.                                 // tell fragment shader about UV
  322.                                 &quot;mov v1, va1\n&quot; +
  323.                                 // tell fragment shader about RGBA
  324.                                 &quot;mov v2, va2\n&quot;
  325.                         );
  326.                         // textured using UV coordinates
  327.                         var fragmentShaderAssembler1:AGALMiniAssembler = new AGALMiniAssembler();
  328.                         fragmentShaderAssembler1.assemble
  329.                         (
  330.                                 Context3DProgramType.FRAGMENT,
  331.                                 // grab the texture color from texture 0
  332.                                 // and uv coordinates from varying register 1
  333.                                 // and store the interpolated value in ft0
  334.                                 &quot;tex ft0, v1, fs0 &lt;2d, repeat, miplinear&gt;\n&quot; +
  335.                                 // move this value to the output color
  336.                                 &quot;mov oc, ft0\n&quot;
  337.                         );
  338.                         // no texture, RGBA from the vertex buffer data
  339.                         var fragmentShaderAssembler2:AGALMiniAssembler = new AGALMiniAssembler();
  340.                         fragmentShaderAssembler2.assemble
  341.                         (
  342.                                 Context3DProgramType.FRAGMENT,
  343.                                  // grab the color from the v2 register
  344.                                 // which was set in the vertex program
  345.                                 &quot;mov oc, v2\n&quot;
  346.                         );
  347.                          // textured using UV coordinates AND colored by vertex RGB
  348.                         var fragmentShaderAssembler3:AGALMiniAssembler = new AGALMiniAssembler();
  349.                         fragmentShaderAssembler3.assemble
  350.                         (
  351.                                 Context3DProgramType.FRAGMENT,
  352.                                 // grab the texture color from texture 0
  353.                                 // and uv coordinates from varying register 1
  354.                                 &quot;tex ft0, v1, fs0 &lt;2d, repeat, miplinear&gt;\n&quot; +
  355.                                 // multiply by the value stored in v2 (the vertex rgb)
  356.                                 &quot;mul ft1, v2, ft0\n&quot; +
  357.                                 // move this value to the output color
  358.                                 &quot;mov oc, ft1\n&quot;
  359.                         );
  360.                         // textured using UV coordinates and
  361.                         // tinted using a fragment constant
  362.                         var fragmentShaderAssembler4:AGALMiniAssembler = new AGALMiniAssembler();
  363.                         fragmentShaderAssembler4.assemble
  364.                         (
  365.                                 Context3DProgramType.FRAGMENT,
  366.                                 // grab the texture color from texture 0
  367.                                 // and uv coordinates from varying register 1
  368.                                 &quot;tex ft0, v1, fs0&lt;2d, repeat, miplinear&gt;\n&quot; +
  369.                                 // multiply by the value stored in fc0
  370.                                 &quot;mul ft1, fc0, ft0\n&quot; +
  371.                                 // move this value to the output color
  372.                                 &quot;mov oc, ft1\n&quot;
  373.                         );
  374.                         // combine shaders into a program which we then upload to the GPU
  375.                         shaderProgram1 = context3D.createProgram();
  376.                         shaderProgram1.upload(vertexShaderAssembler.agalcode, fragmentShaderAssembler1.agalcode);
  377.                         shaderProgram2 = context3D.createProgram();
  378.                         shaderProgram2.upload(vertexShaderAssembler.agalcode, fragmentShaderAssembler2.agalcode);
  379.                         shaderProgram3 = context3D.createProgram();
  380.                         shaderProgram3.upload(vertexShaderAssembler.agalcode, fragmentShaderAssembler3.agalcode);
  381.                         shaderProgram4 = context3D.createProgram();
  382.                         shaderProgram4.upload(vertexShaderAssembler.agalcode, fragmentShaderAssembler4.agalcode);
  383.                 }
  384.                
  385.                 private function initData():void
  386.                 {
  387.                         // Defines which vertex is used for each polygon
  388.                           // In this example a square is made from two triangles
  389.                           meshIndexData = Vector.&lt;uint&gt;
  390.                           ([
  391.                                 0, 1, 2,     0, 2, 3,
  392.                           ]);
  393.                           
  394.                           // Raw data used for each of the 4 vertexes
  395.                           // Position XYZ, texture coord UV, normal XYZ, vertex RGBA
  396.                           meshVertexData = Vector.&lt;Number&gt;
  397.                           ([
  398.                                 //X,  Y,  Z,   U, V,   nX, nY, nZ,  R,  G,  B,  A
  399.                                  -1, -1,  1,   0, 0,   0,  0,  1,  1.0,0.0,0.0,1.0,
  400.                                   1, -1,  1,   1, 0,   0,  0,  1,  0.0,1.0,0.0,1.0,
  401.                                   1,  1,  1,   1, 1,   0,  0,  1,  0.0,0.0,1.0,1.0,
  402.                                  -1,  1,  1,   0, 1,   0,  0,  1,  1.0,1.0,1.0,1.0
  403.                           ]);
  404.                 }
  405.                
  406.         }
  407.         
  408. }
复制代码
0 0
原创粉丝点击