纳金网
标题: AGAL语法 [打印本页]
作者: 家熊 时间: 2013-5-18 02:18
标题: AGAL语法
本帖最后由 家熊 于 2013-5-18 02:24 编辑
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。
va属性寄存器
这些寄存器参考顶点着色器的VertexBuffer输入。因此,他们只能在顶点着色器中可用。
要通过正确的索引分配一个VertexBuffer到一个特定的属性寄存器,使用方法
Context3D:setVertexBufferAt()
在着色器中,访问属性寄存器的语法:va<n>,其中<n>是属性寄存器的索引号。
有一共有8个属性寄存器用于顶点着色器。
常量寄存器
这些寄存器是用来从ActionScript传递参数到着色的。这是通过Context3D::setProgramConstants()系列函数来实现。
在着色器中,这些寄存器的访问语法:
vc<n>,用于顶点着色器
fc<n>,用于像素着色器
其中<n>是常量寄存器的索引值。
有128个常量寄存器用于顶点着色器和28常量寄存器用于像素着色器。
临时寄存器
这些寄存器在着色器中,可以用于临时计算。
这些寄存器的访问语法:
vt<n> (vertex),用于顶点着色器
ft<n> (pixel),用于像素着色器
<n>是寄存器编号。
有8个用于顶点着色器,8个用于像素着色器。
输出寄存器
输出寄存器是在顶点和像素着色器存储其计算输出。此输出用于顶点着色器是顶点的剪辑空间位置。用于像素着色器是该像素的颜色。
访问这些寄存器运算的语法:
op,用于顶点着色器
oc,用于像素着色器
但显然只能一个输出寄存器用于顶点和像素着色器。
变寄存器
这些寄存器用来从顶点着色器传递数据到像素着色器。传递数据被正确地插入图形芯片,从而使像素着色器接收到正确的正在处理的像素的值。
以这种方式获取传递的典型数据是顶点颜色,或 纹理UV 坐标。
这些寄存器可以被访问的语法v <n>,其中<n>是寄存器编号。
有8个变寄存器可用。
纹理取样器
纹理采样寄存器是用来基于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 = -source1
sat saturate 分量饱和值 destination = maximum(minimum(source1 , 1) , 0)
kil kill / discard (fragment shader only)
如果单个标量源组件是小于零,片段将被丢弃,而不是绘制到帧缓冲器。
目标寄存器必须全部为0。
tex texture sample (fragment shader only)
目的地=加载的纹理2源于1的坐标。 在这种来源2必须是在采样格式。
sge set-if-greater-equal
destination = source1 >= source2 ? 1 : 0
slt set-if-less-than
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 shaderProgramrogram3D = _context3D.createProgram();
4、将编译后的AGAL代码上载给Shader ,如:
shaderProgram.upload(vertexShaderAssembler.agalcode, fragmentShaderAssembler.agalcode);
欢迎光临 纳金网 (http://rs.narkii.com/club/) |
Powered by Discuz! X2.5 |