记录作者:Jave.Lin
原贴:http://blog.csdn.net/linjf520/article/details/8758954
首先:AGAL缩放的,全拼意思:Adobe Graphics Assembly Language:Adobe 图形图像汇编语言
先记录一下:常用的寄存器的名称表列(缩写=>全拼),大部份名称都是按自己的喜欢来定而使用,因为用在不一样的公式,计算,都会用不一样的结果:
顶点着色器(Vertex Shader/Program)
va=>Vertex Attribute=>直译:顶点属性;
vc=>Vertex Constant=>直译:顶点常量,一般常量都不可以再改,但这里我们在CPU层上,是怎么改都可以的;但便与我们在使用AGAL中的习惯来用;
vt=>Vertex Temporary=>直译:顶点临时变量,同上,也是习惯而用;
op=>Output Position=>直译:顶点输出位置,在“顶点着色器”的代码中都有用到的寄存器名称;存放最终GPU用于渲染时的顶点位置数据变量
片段着色器(Fragment Shader/Program)
fc=>Fragment Constant=>直译:片段常量;
ft=>Fragment Temporary=>直译:片段临时变量;
fs=>Fragment Texture Sampler=>直译:片段纹理采样(采样:你懂的,不懂就百度一下)
oc=>Output Color=>直译:片段输出颜色:存放最终决定渲染时的像素颜色数据变量;
向量、矩阵的操作码
1、m44的用法:
m44 dest, v, m
dest=>Vector3D(x,y,z,w);
v=>Vector.<Number>[x,y,z,w];
m=>Vector.<Number>(
[
m11,m12,m13,m14,
m21,m22,m23,m24,
m31,m32,m33,m34,
m41,m42,m43,m44
]
);
m44 运算是,展开来看,就是下面的过程;
dest.x=v.x*m.m11+v.y*m.m12+v.z*m.m13+v.w*m.m14;
dest.y=v.x*m.m21+v.y*m.m22+v.z*m.m23+v.w*m.m24;
dest.z=v.x*m.m31+v.y*m.m32+v.z*m.m33+v.w*m.m34;
dest.w=v.x*m.m41+v.y*m.m42+v.z*m.m43+v.w*m.m44;
作用是:将v顶点的原数据,与m矩阵转换(点乘、点积,或是理解成:m有4个顶点,每个点与v点积的结果,等于第N维对应的数据)后的结果,存放到:dest顶点中
示例:
以下是assemble(programeType,agalStr)方法中agalStr就是AGAL: var vertexShaderAssembler:AGALMiniAssembler = new AGALMiniAssembler(); vertexShaderAssembler.assemble( Context3DProgramType.VERTEX, // 4x4矩阵乘以相机角度 "m44 op, va0, vc0\n"+ // 告诉片段着色器x,y,z的值 //"mov v0, va0\n"+//因为:v0在片段着色器中没有用到,先暂时注释掉 // 告诉版段着色器u,v的值 "mov v1, va1\n" ); var fragmentShaderAssembler:AGALMiniAssembler = new AGALMiniAssembler(); fragmentShaderAssembler.assemble( Context3DProgramType.FRAGMENT, // 使用存于v1中的u,v坐标,从纹理fs0中取得纹理的颜色 "tex ft0, v1, fs0 <2d, repeat, miplinear>\n"+ // 使用fc0 烘焙 颜色到纹理 // "mul ft1, fc0, ft0\n"+//mul dest, src1, src2中,src1与src2的位置是可以无序的;加、乘法,都可以交换的,大家都懂的;其它的就不一样喔; "mul ft1, ft0, fc0\n"+ // 将结果输出 "mov oc, ft1\n" ); 如何在CPU层上的代码设置呢?va0,vc0,va1,fs0,等;如下: // set va0, position register : x, y ,z context3D.setVertexBufferAt(0, vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3); // set va1, color register : r, g, b, a context3D.setVertexBufferAt(1, vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_3); // set fs0, texture sample register context3D.setTextureAt(0, myTexture); // set fc0 value context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT,0,Vector.<Number>([Math.sin(t/60), Math.sin(t/10), 1, 1]));
最后自己总结:
AGAL,的语法取决于,这个编译器:
AGALMiniAssembler.as
这个类可以在官网,或是其它地弄成到,总之,大家去搜一下总弄找到;(最简单,直接对GitHub,肯定有)
而这个迷你编译器,最后是把我们输入的字符串“如: vs : "m44 op va0 vc0", fs/ps "move oc fs0";(其实很个m44,dp3,dp4,add,mul,move,等这些命令,到最后,都为转码ByteArray的一个OpCode:操作码,的标识,具体值,我看文档介绍也没有,不过你可以参考:AGALMiniAssembler.as内的代码,里面有对应的枚举定义)
这两个shader都是最后编译成:ByteArray,然后通后,底层的Stage3D.Context3D.program.unload(ByteArray);
也就说,我们可以完也不用官网的这个迷你编译器;而自己写一个;
不过这个你得先了解,这个ByteArray的结构,与Stage3D.context.program,与别的HLSL,或是GLSL有什么支持与不支持的关系;
这样你就完全可以自己写一个基于:Stage3D 的GPU汇编语言了;
如果你能否强大于,可以写个:这个语言的IDE,像VS那么厉害,可以高亮代码,智能提示,调试,那就不得了了;
至于,program接受你传的ByteArray操作码的二进制数据结构,你可以参考我这里提供的两个.pdf:
以别的CG语言与AGAL的简单比较
官方提供的AGAL的ByteArray结构
最后,给大家一些AGAL基础相关,比较有用的网址:
A闪网:(个人比较推荐这个,说得挺详细易懂,大部都是源码注释+博文说明)
http://ashan.org/post-309.html#comment-17360
官方网的一些文章:(中文滴喔,大家好好看这个)
http://www.adobe.com/cn/devnet/flashplayer/articles/what-is-agal.html
Flashache:
http://www.flashache.com/2012/09/19/stage3d-agal-intro-1/
纳金网,3D分栏:--AGAL语法,其实就是别的英文文档的翻译
http://www.narkii.com/club/thread-297505-1.html
以上大部分的中文.pdf都是英文翻译资源;
建议大家都看英文文档;
唉,现在才知道,以前没学好,英文,数学,物理,是多悲催的一件事;