笔记:AGAL语言与AS3.0 API的对应关系

AGAL(Adobe Graphics Assembly Language) 语言是Adobe 公司为stage3D 开发一门图形渲染语言,类似 Opengl Shader Language.

AGAL有30个指令,并不复杂. 只要熟练掌握这30个指令的使用方式,以及如果将程序参数传入AGAL,以及从AGAL中输出参数,就可以入门编写自己想要的效果了.

在寄存器中 有128个存储临时变量的地方 v0-v127

现在针对一个最简单的 AGAL shader 程序,来看看如何操作

1
2
3
4
var fragmentShaderAssembler : AGALMiniAssembler = new AGALMiniAssembler();
fragmentShaderAssembler.assemble(Context3DProgramType.FRAGMENT,
    "mov oc, v2n"
    );

这个操作是将 v2 中的变量输出到 oc 中.

1
2
3
4
5
6
7
8
9
10
meshIndexData = Vector.<uint>(
    [0,1,2, 0,2,3]
    );
           
meshVertexData = Vector.<Number>(
    [   -1,-1,1,    0,0,    0,0,1,  1.0,0.0,0.0,1.0,
        1,-1,1,     1,0,    0,0,1,  0.0,1.0,0.0,1.0,
        1,1,1,      1,1,    0,0,1,  0.0,0.0,1.0,1.0,
        -1,1,1,     0,1,    0,0,1,  1.0,1.0,1.0,1.0
        ]);

这个操作构造了2个三角形,IndexData 为三角形要用到的顶点索引位, VertexData 为顶点数据

1
2
    //rgba
    context3D.setVertexBufferAt(2, vertexBuffer, 8, Context3DVertexBufferFormat.FLOAT_4);

将rgba的数值传入渲染.
setVertexBufferAt 的第一个参数就是要使用的 临时寄存器位置, 2 表示 使用v2(0-7). vertexBuffer 为数据, 8 表示要使用的数据是从 VertexData 顶点数据中第8位开始的 即 “1.0,0.0,0.0,1.0”, 最后一个参数是 FLOAT_4 即要使用的数据类型,它表示我们要使用一个4位的浮点型,rgba有4位,如果你传入的是顶点数据x,y,z, 那么你应该使用的是 FLOAT_3 . 对于rgba来说,他们是不可能出现负数的,这意味着你使用BYTES_4 也是可行的,而且最好这么使用.

试着让一个自定义的材质呈现不同颜色
在 agal 中要渲染一个材质的话,需要如下shader

1
2
3
4
5
var fragmentShaderAssembler : AGALMiniAssembler = new AGALMiniAssembler();
fragmentShaderAssembler.assemble(Context3DProgramType.FRAGMENT,
    "tex ft0, v1, fs0 <2d,repeat,miplinear>n" +
    "mov oc, ft0n"
    );

“tex ft0, v1, fs0 <2d,repeat,miplinear>n” 指从 fs0 的地方取得材质, 从 v1 的地方取得 坐标系, 然后将他们存入 ft0
“mov oc, ft0n” 将 ft0 的数据输出
那么怎么给 fs0 和 v1 赋值呢?
fs0 赋值方式为 context3D.setTextureAt(0,myTexture);
v1 赋值方式为 context3D.setVertexBufferAt(1, vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2); v1 的数据就只之前的 meshData 从第三位开始的 U,V 数据.

从上面的agal代码中,我们将材质的颜色仅仅是重现而已,并没有让它呈现不同颜色,接下来,我们来常识实现变色

shader如下

1
2
3
4
5
6
var fragmentShaderAssembler3 : AGALMiniAssembler = new AGALMiniAssembler();
fragmentShaderAssembler3.assemble(Context3DProgramType.FRAGMENT,
    "tex ft0, v1, fs0 <2d,repeat,miplinear>n" +
    "mul ft1, v2, ft0n" +
    "mov oc, ft1n"
    );

这个shader程序仅仅比之前多一行
“mul ft1, v2, ft0n” 的操作为 对于材质的每一个像素 都乘以 从v2中获取的rgba参数,并将结果存入 ft1
“mov oc, ft1n” 将这些参数输出

如果不是针对每一个像素,而是让整个材质呈现同一种颜色.
只需要将第二句改变为 “mul ft1, fc0, ft0n”
fc0 的赋值方式为 context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT,0,Vector.([1,0,0,1]));

最后整理一下AS3.0 中 API的解释,以及所有寄存器的定义,最后是30个寄存器列表

setVertexBufferAt
() 方法
public function setVertexBufferAt(index:int, buffer:VertexBuffer3D, bufferOffset:int = 0, format:String = “float4”):void

语言版本: ActionScript 3.0
运行时版本: Flash Player 11, AIR 3

指定与单个着色器程序输入相对应的顶点数据组件。

使用 setVertexBufferAt 方法来标识 VertexBuffer3D 缓冲区中每个顶点定义的哪些数据组件属于顶点程序的哪些输入。顶点程序的开发人员会确定每个顶点需要的数据量。该数据从 1 个或多个 VertexBuffer3D 流映射到顶点着色器程序的属性寄存器中。

顶点着色器所使用数据的最小单位为 32 位数据。距顶点流的偏移量以 32 位的倍数指定。
举例来说,编程人员可以使用以下数据定义每个顶点:

position: x float32
y float32
z float32
color: r unsigned byte
g unsigned byte
b unsigned byte
a unsigned byte

假定在 VertexBuffer3D 对象中定义了名为 buffer 的对象,则可使用以下代码将其分配给顶点着色器:

setVertexBufferAt( 0, buffer, 0, Context3DVertexBufferFormat.FLOAT_3 ); // attribute #0 will contain the position information
setVertexBufferAt( 1, buffer, 3, Context3DVertexBufferFormat.BYTES_4 ); // attribute #1 will contain the color information

参数
index:int — 顶点着色器中的属性寄存器的索引(0 到 7)。

buffer:VertexBuffer3D — 包含要馈送到顶点着色器中的源顶点数据的缓冲区。

bufferOffset:int (default = 0) — 单个顶点的起始数据偏移量,从此处开始读取此属性。在上例中,位置数据的偏移量为 0,因为它是第一个属性;颜色的偏移量为 3,因为颜色属性跟在 3 个 32 位位置值之后。以 32 位为单位指定偏移量。

format:String (default = “float4”) — 来自 Context3DVertexBufferFormat 类的值,指定此属性的数据类型。

引发
Error — 无效的枚举:当格式不是 Context3DVertexBufferFormat 类中定义的值之一时。

RangeError — 属性寄存器超出边界:当 index 参数超出 0 到 7 的范围时。(着色器最多可使用 8 个顶点属性寄存器。)

setProgramConstantsFromVector
() 方法
public function setProgramConstantsFromVector(programType:String, firstRegister:int, data:Vector., numRegisters:int = -1):void

语言版本: ActionScript 3.0
运行时版本: Flash Player 11, AIR 3

设置着色器程序的常量输入。

设置要通过顶点或片段着色器程序访问的常量数组。Program3D 中设置的常量在着色器程序内作为常量寄存器访问。每个常量寄存器都由 4 个浮点值(x、y、z、w)组成。因此,每个寄存器都要求数据 Vector 中有 4 个条目。您可以为顶点程序设置 128 个寄存器,为片段程序设置 28 个寄存器。

参数
programType:String — 着色器程序类型,Context3DProgramType.VERTEX 或 Context3DProgramType.FRAGMENT。

firstRegister:int — 要设置的首个常量寄存器的索引。

data:Vector. — 浮点常量值。data 中至少有 numRegisters 4 个元素。

numRegisters:int (default = -1) — 要设置的常量数量。指定 -1(默认值),设置足够的寄存器以使用所有可用数据。

引发
TypeError — Null 指针错误:当 data 为 null 时。

RangeError — 常量寄存器超出边界:当尝试设置超出最大数量的着色器常量寄存器时(顶点程序为 128;片段程序为 28)。

对于常量寄存器来说 顶点着色器可以使用128个,像素着色器可以使用28个.
即 vc0-vc127, fc0-fc27
vc 为 Vertex Constant
fc 为 Fragment Constant
赋值方式为 context3D.setProgramConstantsFromVector(Context3DProgramType.(FRAGMENT || VERTEX),0,Vector.([1,0,0,1]));

对于临时寄存器来说 顶点着色器和像素着色器各有8个
vt0-vt7, ft0-ft7
vt 为 Vertex Temp
ft 为 Fragment Temp

输出寄存器 顶点着色器为 op, 像素着色器为 oc
像之前输出处理过的像素 就是使用 mov oc ft0

通用寄存器 即一个公共区域的变量可以被 顶点着色器和像素着色器公用
v0-v7 共8个

顶点属性寄存器和像素采样寄存器
分别是 va0-va7 , fs0-fs7
赋值方式为 setVertexBufferAt 和 setTextureAt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
  private static const MOV:String       = "mov"; //数据牵移
  private static const ADD:String       = "add"; //数据加法
  private static const SUB:String       = "sub"; //数据减法
  private static const MUL:String       = "mul"; //数据乘法
  private static const DIV:String       = "div"; //除法
  private static const RCP:String       = "rcp"; //倒数
  private static const MIN:String       = "min"; //比较   较小值
  private static const MAX:String       = "max"; //比较  较大值
  private static const FRC:String       = "frc"; //取小数。。
  private static const SQT:String       = "sqt"; //开方
  private static const RSQ:String       = "rsq"; //开方倒数
  private static const POW:String       = "pow"; //数幂指数
  private static const LOG:String       = "log"; //log运算
  private static const EXP:String       = "exp"; //e的运算 e^2
  private static const NRM:String       = "nrm"; //标准化
  private static const SIN:String       = "sin"; //sin运算
  private static const COS:String       = "cos"; //cos运算
  //cross product  destination.x = source1.y * source2.z - source1.z * source2.y  destination.y = source1.z * source2.x - source1.x * source2.z
  private static const CRS:String       = "crs"; //叉乘运算
  private static const DP3:String       = "dp3"; //点乘运算。。向量间投影
  private static const DP4:String       = "dp4"; //四向量点乘
  private static const ABS:String       = "abs"; //数的绝对值
  private static const NEG:String       = "neg"; //取相反数
  private static const SAT:String       = "sat"; //取数与0的最大值    maximum(minimum(source1,1),0),
  private static const M33:String       = "m33"; //33矩阵乘法
  private static const M44:String       = "m44"; //44矩阵乘法
  private static const M34:String       = "m34"; //34矩阵乘法
  private static const IFZ:String       = "ifz";
  private static const INZ:String       = "inz";
  private static const IFE:String       = "ife";
  private static const INE:String       = "ine";
  private static const IFG:String       = "ifg";
  private static const IFL:String       = "ifl";
  private static const IEG:String       = "ieg";
  private static const IEL:String       = "iel";
  private static const ELS:String       = "els";
  private static const EIF:String       = "eif";
  private static const REP:String       = "rep";
  private static const ERP:String       = "erp";
  private static const BRK:String       = "brk";
  private static const KIL:String       = "kil"; // 关闭 显卡显示?kil   0x27   kill / discard (fragment shader only)
  private static const TEX:String       = "tex"; // 贴图 texture sample (fragment shader only)
  private static const SGE:String       = "sge"; //destination = source1 >= source2 ? 1 : 0 进行设置
  private static const SLT:String       = "slt"; //destination = source1 < source2 ? 1 : 0 进行设置
  private static const SGN:String       = "sgn";

发表评论

电子邮件地址不会被公开。 必填项已用*标注

This site uses Akismet to reduce spam. Learn how your comment data is processed.