本文并无打算事无巨细的介绍一遍AGAL,仅仅是对现有文档的一些理解及汇总,所以请先阅读相参考文档
参考资料
建议去看英文,中文翻译的很烂,要是想看英文,请在下方将语言换为英语,否则仍旧自动跳转回中文
如文档中所说,AGAL(Adobe Graphics Assembly Language) 是一种接近于GPU指令的语言,同Pixel Bender3D的区别在于
一个事先需要先编译好(Pixel Bender3D),
另外一个仅仅为一段字符串(借助AGAL Mini Assembler),可以在运行期间动态改变。
文档中提及的AGAL Mini Assembler是一个小类库,下载地址http://www.bytearray.org/wp-content/projects/agalassembler/com.zip
主要是用于将字符串形式的AGAL转换为ByteArray。
在代码中最后上传这些操作给GPU时候,实际用到的方法为
可以在API中查到,参数类型为ByteArray,而非字符串
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display3D/Program3D.html
所以才需要一个小类库,将字符串转化为ByteArray
m44 op, va0, vc0 // pos to clipspace
mov v0, va1 // copy color
根据语法来说,第一个m44 和 mov 均为指令集
mov:
moves data from source1 to destination, component-wiseadd:
destination = source1 + source2, component-wisesub:
destination = source1 – source2, component-wisemul:
destination = source1 * source2, component-wisediv:
destination = source1 / source2, component-wisedp3:
dot product (3 components) between source1 and source2dp4:
dot product (4 components) between source1 and source2m44:
multiplication between 4 components vector in source1 and 4×4 matrix in source2tex:
texture sample. Load from texture at source2 at coordinates source1.要了解后续代码的意思,需要引入寄存器的概念
AGAL doesn't use variables to store data, like ActionScript and other high level languages do. AGAL just uses registers.Registers are small memory areas in the GPU that AGAL programs (Shaders) can use during their execution. Registers are used to store both the sources and the destination of AGAL commands.
参考资料:
就我个人理解,应该可以认为Vertex Shader主要处理顶点相关的计算,如在数学上定义的一个三角形x(0,1,0),y(1,0,0),z(0,0,1),将这个三角形进行缩放,旋转等操作时候需要用到 Vertex Shader,
当该三角形完成以上全部操作后,后续的对其进行着色(UV map等)操作时候就需要用到Pixel shaders
m44 op, va0, vc0 // pos to clipspace
mov v0, va1 // copy color
根据AGAL语法:<操作指令>,<目标>,<数据源1>,<数据源2>
m44 op,va0,vc0
将va0(顶点坐标),和vc0(AS中传入的变量)执行m44(矩阵相乘),放入op(顶点计算结果)中
例子中的两行代码是否有任何关系?
因为第二行代码仅操作的 v0 和va1 和op没有任何关系,在后续中我会说一下我自己做的Demo,其中的Shader是
//compile vertex shader var vertexShader:Array = [ "dp4 op.x, va0, vc0", //4x4 matrix transform from 0 to output clipspace "dp4 op.y, va0, vc1", "dp4 op.z, va0, vc2", "dp4 op.w, va0, vc3", "mov v0, va1.xyzw" //copy texcoord from 1 to fragment program ]; //compile fragment shader var fragmentShader:Array = [ "mov ft0, v0\n", "tex ft1, ft0, fs1 <2d,clamp,linear>\n", //sample texture 1 "mov oc, ft1\n" ];
可以看出 仍旧之前先操作va0, 但是最后一行仍旧是操作的va1—> mov v0,va1.xyzw
已经在stackoverflow上面发帖,希望能够得到解答
http://stackoverflow.com/questions/13854785/adboe-agal-confused-about-the-registers
对于疑惑的解答
后来有人在StackOverflow上面回帖了,我也自己看了一下代码,在Demo里面(后续会放出),存在如下代码
{ context.setVertexBufferAt(0, _buffer, 0, Context3DVertexBufferFormat.FLOAT_2); //xy
context.setVertexBufferAt(1, _buffer, 2, Context3DVertexBufferFormat.FLOAT_2); //uv
context.setTextureAt(1 , texture); }
该代码的意思及为,在va0中放入了顶点坐标,在va1中放入了uv坐标。
所以例子中的五行
"dp4 op.x, va0, vc0",
"dp4 op.y, va0, vc1",
"dp4 op.z, va0, vc2",
"dp4 op.w, va0, vc3",
"mov v0, va1.xyzw"
可以拆分为两部分理解,前四行操作的是vc0中的变换,最后存入op
第五行做的操作其实是为了后续的fragmentShader操作做准备(如不太明白,可以查阅 什么是Vertex Shader,什么是Pixel shaders)
整体AGAL做的事情可以理解为:就是执行多种变换,最终结果存入op和oc 两个寄存器中