AGAL
  AGAL(Adobe Graphics Assembly Language)是Adobe开发的图形汇编语言,汇编语言是仅高于计算机二进制机器码的低级语言,可以精确地操控机器硬件比如可编程显卡,PC的Dirext9、MAC的OpenGL以及移动设备中的OpenGL ES 2都是可编程显卡,并且都支持AGAL。通过Adobe官方提供的编译器AGALMiniAssembler(实际上是一个AS类库),我们可以通过字符串指令来获得一个AGAL二进制流,再通过context3D上传给显卡的编程管线。对于顶点以及片段的运算都是通过AGAL交由显卡来处理的,这就是传说中的GPU硬件加速。),最新的测试版flash player 11中提供了可调用显卡资源来渲染图形API,即Molehill

 

  1。属性寄存器
  这些寄存器参考顶点着色器的VertexBuffer输入。因此,他们只能在顶点着色器中可用。
  要通过正确的索引分配一个VertexBuffer到一个特定的属性寄存器,使用方法
  Context3D:setVertexBufferAt()
  在着色器中,访问属性寄存器的语法:va<n>,其中<n>是属性寄存器的索引号。
  有一共有8个属性寄存器用于顶点着色器。

 

  2。常量寄存器
  这些寄存器是用来从ActionScript传递参数到着色的。这是通过Context3D::setProgramConstants()系列函数来实现。
  在着色器中,这些寄存器的访问语法:
  vc<n>,用于顶点着色器
  fc<n>,用于像素着色器
  其中<n>是常量寄存器的索引值。
  有128个常量寄存器用于顶点着色器和28常量寄存器用于像素着色器。

 

  3。临时寄存器
  这些寄存器在着色器中,可以用于临时计算。
  这些寄存器的访问语法:
  vt<n> (vertex),用于顶点着色器
  ft<n> (pixel),用于像素着色器
  <n>是寄存器编号。
  有8个用于顶点着色器,8个用于像素着色器。

 

  4。输出寄存器
  输出寄存器是在顶点和像素着色器存储其计算输出。此输出用于顶点着色器是顶点的剪辑空间位置。用于像素着色器是该像素的颜色。
  访问这些寄存器运算的语法:
  op,用于顶点着色器
  oc,用于像素着色器
  但显然只能一个输出寄存器用于顶点和像素着色器。

 

  5。变寄存器
  这些寄存器用来从顶点着色器传递数据到像素着色器。传递数据被正确地插入图形芯片,从而使像素着色器接收到正确的正在处理的像素的值。
  以这种方式获取传递的典型数据是顶点颜色,或 纹理UV 坐标。
  这些寄存器可以被访问的语法v <n>,其中<n>是寄存器编号。
  有8个变寄存器可用。

 

  6。纹理取样器
  纹理采样寄存器是用来基于UV坐标从纹理中获取颜色值。
  纹理是通过ActionScriptcall指定方法Context3D::setTextureAt()。
  纹理样本的使用语法是:fs<n> <flags>,其中<n>是取样指数,<flags>是由一个或多个标记,用于指定如何进行采样。
  <flags>是以逗号分隔的一组字符串,它定义:
  纹理尺寸。可以是:二维,三维,多维数据集
  纹理映射。可以是:nomip,mipnone,mipnearest,mipnone
  纹理过滤。可以是:最近点采样,线性
  纹理重复。可以是:重复,包装,夹取。
  因此,举例来说,一个标准的2D纹理没有纹理映射,并进行线性过滤,可以进行采样到临时寄存器FT1,使用以下命令:
  “tex ft1, v0, fs0 <2d,linear,nomip> “
  变寄存器v0持有插值的纹理 UVs。

 

AGAL Opcode 指令:

基本語法
[opcode] [destination] [source1] [source2 or sampler]
沒有使用到的欄位必須設為 0 (應該是指 bytecode)
mov  move        分量移動     移動 source1 資料到 destination
add  add         分量相加     destination = source1 + source2
sub  subtract    分量相減     destination = source1 - source2
mul  multiply    分量相乘     destination = source1 * source2
div  divide      分量相除     destination = source1 / source2
rcp  reciprocal  分量倒數     destination = 1 / source1
min  minimum     分量最小值    destination = minimum(source1 , source2)
max  maximum     分量最大值    destination = maximum(source1 , source2)
frc  fractional  分量取小數    destination = source1 - (float) floor(source1)
sqt  square      分量平方根    destination = sqrt(source1)
rsq  recip. root 分量平方根倒數 destination = 1 / sqrt(source1)
pow  power       分量指數      destination = pow(source1 , source2)
log  logarithm   2 為底分量對數 destination = log_2(source1)
exp  exponential 2 為底分量指數 destination = 2^source1
nrm  normalize   分量標準化    destination = normalize(source1)
sin  sine        分量正弦      destination = sin(source1)
cos  cosine      分量餘弦      destination = cos(source1)
abs  absolute    分量絕對值    destination = abs(source1)
neg  negate      分量負值      destination = -source1
sat  saturate    分量飽和值    destination = maximum(minimum(source1 , 1) , 0)
kil  kill / discard (fragment shader only)
   假如單一分量小於 0 便放棄繪圖
   If single scalar source component is less than zero, fragment is discarded and not drawn to the frame buffer.
   The destination register must be all 0.
tex  texture sample (fragment shader only)
   依據 source1 座標從 source2 材質取樣
   destination = load from texture source2 at coordinates source1.
   In this source2 must be in sampler format.
sge  set-if-greater-equal
   分量運算,假如 source1 大於等於 source2,目標為 1,否則目標為 0
   destination = source1 >= source2 ? 1 : 0
slt  set-if-less-than
   分量運算,假如 source1 小於 source2,目標為 1,否則目標為 0
   destination = source1 < source2 ? 1 : 0
crs  cross product 向量外積
   destination.x = source1.y * source2.z - source1.z * source2.y
   destination.y = source1.z * source2.x - source1.x * source2.z
   destination.z = source1.x * source2.y - source1.y * source2.x
dp3  dot product  向量內積
   destination = source1.x * source2.x + source1.y * source2.y + source1.z * source2.z
dp4  dot product  向量內積
   destination = source1.x * source2.x + source1.y * source2.y + source1.z * source2.z+ source1.w * source2.w
m33 multiply    3x3 矩陣相乘
   destination.x = (source1.x * source2[0].x) + (source1.y * source2[0].y) + (source1.z * source2[0].z)
   destination.y = (source1.x * source2[1].x) + (source1.y * source2[1].y) + (source1.z * source2[1].z)
   destination.z = (source1.x * source2[2].x) + (source1.y * source2[2].y) + (source1.z * source2[2].z)
m44 multiply    4x4 矩陣相乘
   destination.x = (source1.x * source2[0].x) + (source1.y * source2[0].y) + (source1.z * source2[0].z) + (source1.w * source2[0].w)
   destination.y = (source1.x * source2[1].x) + (source1.y * source2[1].y) + (source1.z * source2[1].z) + (source1.w * source2[1].w)
   destination.z = (source1.x * source2[2].x) + (source1.y * source2[2].y) + (source1.z * source2[2].z) + (source1.w * source2[2].w)
   destination.w = (source1.x * source2[3].x) + (source1.y * source2[3].y) + (source1.z * source2[3].z) + (source1.w * source2[3].w)
m34 multiply    3x4 矩陣相乘
   destination.x = (source1.x * source2[0].x) + (source1.y * source2[0].y) + (source1.z * source2[0].z) + (source1.w * source2[0].w)
   destination.y = (source1.x * source2[1].x) + (source1.y * source2[1].y) + (source1.z * source2[1].z) + (source1.w * source2[1].w)
   destination.z = (source1.x * source2[2].x) + (source1.y * source2[2].y) + (source1.z * source2[2].z) + (source1.w * source2[2].w)
 

從 AGALMiniAssembler 裡面看到還有這些 opcode

ifz, inz, ife, ine, ifg, ifl, ieg, iel, els, eif, rep, erp, brk, sgn

不過實際測試發現在目前這版 Flash Player 尚未支援

Error: Error #3621: AGAL validation failed: Invalid opcode, ifg is not implemented in this version at
 token 2 of fragment program.
 

AGAL 基本語法:

vc0, va0 作 4×4 矩陣轉型後指定到輸出剪輯空間 (output clipspace)
m44 op, va0, vc
以上語法等於以下個別分量的單獨作內積
dp4 op.x, va0, vc0
dp4 op.y, va0, vc1
dp4 op.z, va0, vc2
dp4 op.w, va0, vc3
從 va1 複製到 v0 給 fragment shader 使用
mov v0, va1
等於
mov v0, va1.xyzw
注意 xyzw 順序
mov v0, va1.yxzw
實際上是等於
mov v0.x, va1.y
mov v0.y, va1.x
mov v0.z, va1.z
mov v0.w, va1.w

 

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);