代码改变世界

[Stage3D]AGAL的寄存器及常用指令

2012-03-23 11:45  WesleyWoo  阅读(2455)  评论(1编辑  收藏  举报

AGAL, Adobe Graphics Assembly Language(Adobe图形汇编语言), 简称AGAL, 是Adobe堆出的一种操作 GPU 的Shader语言。

要了解AGAL,跟其他的汇编语言一样,必须先了解他的寄存器和指令。

 

AGAL寄存器:

AGAL共有6种寄存器

1、顶点属性寄存器(Vertex Attribute Registers):va0,va1,....,va7

  ·共有8个顶点属性寄存器,每个寄存器能放4个float型,所以总共有32个Number的数据可以使用(对于每个顶点);

  ·顶点属性寄存器的内容通过 Context3D::setVertexBufferAt() 函数将值上载;

  ·例如,指令 “m44 op, va0, vc0 ” 的意义就是:将va0(顶点属性) 乘上 vc0(变形矩阵)后,将结果放到 op(位置输出寄存器);

2、常量寄存器 (Constant Registers)

   ·用于Vertex Program: vc0,vc1,....,vc127 共128个。主要用来保存位置变换等常量,如变换矩阵,用 Context3D::setProgramConstantsFromMatrix() 函数将值上载,例如,指令 “m44 op, va0, vc0 ” 中的 vc0 保存的就是变换矩阵。

   ·用于Fragment Program:fc0,fc1,....,fc27 共28个。主要用来保存颜色数据等常量, 用该寄存器可以在运行时动态改变颜色数据。同样地,用 Context3D::setProgramConstantsFromVector() 函数将值上载

3、暂存寄存器 (Temporary Registers)

   ·用于Vertex Program :vt0,vt1,...,vt7

     ·用于Fragment Program :ft0,ft1,...,ft7

   暂存数据

4、输出寄存器(Output Registers)

   ·位置输出寄存器 op,为 Vertex Program 所用;

   ·颜色输出寄存器 oc,为 Fragment Program 所用;

   ·例如,指令“m44 op, va0, vc0 ” 是将计算后的位置信息,放到op 输出; 指令 “mov oc, ft1” ,将ft1中的颜色信息放到oc 中输出

5、变量寄存器(Varying Registers):v0,v1,...,v7

   用于从 Vertex Program 向 Fragment Program 传递数据,例如,UV坐标是通过 Context3D::setVertexBufferAt() 上载到 顶点属性寄存器 va1 ,指令“mov v1, va1”则将va1中的uv坐标数值移到v1中,以便Fragment Program可以访问到, 如 "tex ft0, v1, fs0<2d, repeat, miplinear>" 指令 ,意义为:将fs0中的纹理数据,通过UV坐标裁剪后放到 ft0 暂存寄存器

6、纹理样本 (Texture Sampler):fs0,fs1,...,fs7

   用来存放纹理数据,通过函数 Context3D::setTextureAt() 函数将值载入, 使用时,如上  "tex ft0, v1, fs0<2d, repeat, miplinear>" 指令。

*关于AGAL寄存器的几点说明

1、每个寄存器占16个字,即4个float型,在AS3里则表现为4个Number型;

2、通过 x,y,z,w 或 r,g,b,a 可以访问寄存器中的4个float型数值(元素),如va1.x 和 va1.r 都表示va1中的第一个元素,寄存器运算时各个元素对应;

3、在vertex shader中我们一般用 x,y,z,w 来访问, 在fragment shader中用 r,g,b,a 访问

 

AGAL操作码:

AGAL共有30个操作码,这里列出常用的几个:

        mov - 移动
        add - 加
        sub - 减
        mul - 乘
        div - 除
        m44 - 乘上4阶矩阵
        tex - 纹理裁剪, 将保存在fs[n]中的纹理数据,根据UV坐标,裁剪制作成纹理样本

    其他操作指令参见AGAL文档:http://vdisk.weibo.com/s/3qDOt/1332504563

*每条VertexShader指令在每个顶点上都跑一遍;同样的,每条Fragment Shader指令将在每个像素上都跑一遍;

 

AS3中,编译AGAL指令须按照以下几个步骤:

1、创建AGALMiniAssembler类对象 (AGALMiniAssembler 是Adobe提供的用来将字符串格式的AGAL指令编译成二进制码的工具类),如:

var vertexShaderAssembler:AGALMiniAssembler = new AGALMiniAssembler();
var fragmentShaderAssembler:AGALMiniAssembler = new AGALMiniAssembler();

2、编译AGAL代码,如:

 vertexShaderAssembler.assemble(Context3DProgramType.VERTEX,
"m44 op, va0, vc0\n" +
"mov v0, va0\n" +
"mov v1, va1\n" +
"mov v2, va2\n" );

  fragmentShaderAssembler.assemble(Context3DProgramType.FRAGMENT,
"tex ft0, v1, fs0<2d, repeat, miplinear>\n" +
"mov oc, ft0\n" );

3、创建Shader,如:

var shaderProgram:Program3D = _context3D.createProgram();

4、将编译后的AGAL代码上载给Shader ,如:

shaderProgram.upload(vertexShaderAssembler.agalcode, fragmentShaderAssembler.agalcode);