Away3D之-------------------------------------------AGAL入门

一.  AGAL概述:


AGAL是Adobe图形汇编语言,它与DX的HLSL  OPENGL的GLSL类似是一种着色器语言,用于编写着色器供GPU使用。    AGAL与HLSL等类似,语言基本结构也是汇编。 


二.  AGAL基本语法:


AGAL代码行的语法:   <opcode> <destination>, <source 1>, <source 2 or sampler>

opcode为操作码也就是指令 如: mov add等destination用来保存运算结果source 1 source 2 分别为用于计算的数据源 。

  

    GPU操作的数据信息并非存放在内存而是存放在寄存器中, 每个指令是对寄存器中数据进行的操作destinationsource 1 source 2都是存放在寄存器中的数据。


1. 寄存器:


在绘制过程中所有数据将被传入寄存器, 程序通过命令对数据计算得出结果用于显示,寄存器的最大数量是固定的,每个

寄存器为128位,能包含4个浮点数值。对寄存器中的数据可以通过“坐标”存取器(xyzw)和色彩存取器(rgba)存取。如: 

个寄存器数据可以通过<register name>.x <register name>.y <register name>.z

来取也可以用<register name>.r<register name>.g<register name>.b来获取。 


寄存器的种类总共分为六种:


a. 属性寄存器( Attribute registers )

 

这些寄存器引用了从顶点着色器输入的VertexBuffer中的顶点属性数据。因此,他们只能在顶点着色器中被使用。
这是顶点着色器负责处理的主要数据流,。VertexBuffer中的每个顶点属性都有其自己的属性寄存器。
为了将一个VertexBuffer属性分配到一个特定的属性寄存器中,在AS3代码中可以使用Context3D:setVertexBufferAt(),

通过适当的索引。在着色器中,你可以通过以下语法访问属性注册器:va<n>,其中<n>属性寄存器的索引号。

总共有8个用于顶点着色器的属性寄存器。这8个顶点着色器属性寄存器用于存放顶点Buffer中的位置 法线 UV等数据。


b.Constant registers常量寄存器

这些寄存器是为了从ActionScript向着色器传递参数的目的而服务的。通过执行Context3D:setProgramConstants()等系列函数来达到这一目的。

在着色器中使用如下语法能够访问到这些寄存器:对于顶点着色器可以使用vc<n>,对于像素着色器可以使用fc(n),其中<n>是常量寄存器的索引号

有128个用于顶点着色器和28个用于像素着色器的常量寄存器。常量寄存器用于逻辑向着色器传递的常量参数。



c.Temporary registers临时寄存器

这些寄存器供着色器在临时计算时使用。由于AGAL不使用变量,您可以使用临时寄存器来存储整个代码中的数据。
可以使用如下语法访问临时寄存器:vt<n>(顶点着色器)和ft<n>(像素着色器)<n>是寄存器编号。

分别有8个临时寄存器用于顶点着色器和像素着色器。临时寄存器相当于运算过程中的临时变量,用于存放临时变量。

d.Output registers输出寄存器

输出寄存器存储顶点和像素着色器的计算输出。对于顶点着色器,输出的是顶点位置。对于像素着色器,它输出像素的颜色。


这些寄存器可以通过语法op(顶点着色器)和oc(像素着色器)来进行访问。


显然只有一个用于顶点和像素着色器的输出寄存器。


5.Varying Registers变量寄存器

这些寄存器用于将数据从顶点着色器传递至像素着色器。这些数据通过GPU被传递被正确插入,使得像素着色器对于那些正在被处理的像素收到了正确的值。

用这种方法传递的典型数据是顶点的颜色或纹理的UV坐标。

这些寄存器可以通过以下语法被访问:v<n>,其中<n>寄存器编号。

共有8个可用的变量寄存器。用于顶点着色器向像素着色器传递数据参数。

6.Texture sampler registers纹理采样寄存器

纹理采样寄存器是用来采集基于UV坐标系的纹理中的颜色值。
通过ActionScript调用Context3D::setTextureAt()指定要使用的纹理。
使用纹理采样器的语法是:fs<n> <flags>,其中<n>是取样索引,<flags>是一个或多个标志,指定应如何抽样。
<flags>是一个逗号分隔的字符串,它的定义如下:

  texture dimension.Options: 2d, cube 材质类型
   mip mapping.Options: nomip (or mipnone , they are the same) , mipnearest, miplinearMip映射
   texture filtering.Options: nearest, linear过滤方式
   texture repeat.Options: repeat, wrap, clamp纹理重复


2. 操作符:

 

       min:destination=min(source1 , source2) : 两个寄存器之间的较小值,分量形式
       max:destination=max(source1 ,source2): 两个寄存器之间的较大值,分量形式
       sqt:destination=sqrt(source):一个寄存器的平方根,分量形式
       rsq:destination=1/sqrt(source) 一个寄存器的平方根倒数,分量形式
      pow:destination=pow(source1 ,source2):source1的source2次冥,分量形式
      log:destination=log(source1)一个寄存器以2为底的对数,分量形式
      exp:destination=2^source1:2的source1次方,分量形式
     nrm:destination=normalize(source1):将一个寄存器标准化为长度1的单位向量
      abs:destination=abs(source1):一个寄存器的绝对值,分量形式
      sat:destination=max(min(source1,1),0):将一个寄存器锁0-1的范围里
     
     crs:两个寄存器间的叉积
      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:两个寄存器间的点积,3分量
     destination=source1.x*source2.x+source1.y*source2.y+source1.z*source2.z
    dp4:两个寄存器间的点积,4分量
     destination=source1.x*source2.x+source1.y*source2.y+source1.z*source2.z+source1.w+source2.w
    m33:由一个3*3的矩阵对一个3分量的向量进行矩阵乘法
     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)
      m34:由一个3*4的矩阵对一个4分量的向量进行矩阵乘法
       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)
    m44:由一个4*4的矩阵对一个4分量的向量进行矩阵乘法
     destination.x=(source1.x*source2[0].x)+(source1.y*source2[0].y)+(source1.z*source2[0].z)+(source1.w*source2[0].w)
       destination.x=(source1.x*source2[1].x)+(source1.y*source2[1].y)+(source1.z*source2[1].z)+(source1.w*source2[1].w)
        destination.y=(source1.x*source2[2].x)+(source1.y*source2[2].y)+(source1.z*source2[2].z)+(source1.w*source2[2].w)
       destination.z=(source1.x*source2[3].x)+(source1.y*source2[3].y)+(source1.z*source2[3].z)+(source1.w*source2[3].w)
 

 

   add:destination=source1+source2:两个寄存器相加,分量形式
   sub:destination=source1-source2:两个寄存器相减,分量形式
     mul:destination=source1*source2:两个寄存器相乘,分量形式
      div:destination=source1/source2:两个寄存器相除,分量形式
   rcp:destination=1/source1:一个寄存器的倒数,分量形式
   frc:destination=source1-(float)floor(source1)一个寄存器的分数部分,分量形式
   neg:destination=-source1:一个寄存器取反,分量形式

 

 三.  AGAL示例:


以天空盒渲染shader为例,通过简单的天空盒绘制代码了解AGAL的工作流程:


顶点着色器vs代码:

arcane override function getVertexCode():String
{
return "mul vt0, va0, vc5 \n" +
// 将0号属性寄存器值(顶点位置信息)与5号常量

// 寄存器数值相乘结果保存在0号临时寄存器
"add vt0, vt0, vc4 \n" + // 0号临时寄存器与4号常量寄存器相加结果保存

// 到0号临时寄存器
"m44 op, vt0, vc0 \n" +/ // 0号临时寄存器与0号常量寄存器(矩阵)运算结果

// 保存在输出寄存器op中供像素着色器使用
"mov v0, va0\n"; // 将0号属性寄存器值保存在v0中供像素着色器使用
}
                     


像素着色器ps代码:

arcane override function getFragmentCode(animationCode:String):String
{
var format:String;
switch (_cubeTexture.format) {
case Context3DTextureFormat.COMPRESSED:
format = "dxt1,";
break;
case "compressedAlpha":
format = "dxt5,";
break;
default:
format = "";
} // 确定纹理格式
var mip:String = ",mipnone";
if (_cubeTexture.hasMipMaps)
mip = ",miplinear"; // 确定纹理mip样式
return "tex ft0, v0, fs0 <cube," + format + "linear,clamp" + mip + "> \n" +  // 从cube纹理中进行采样
"mov oc, ft0 \n";  // 将采样数据保存在oc中作为ps输出
}                


override arcane function render(renderable:IRenderable, stage3DProxy:Stage3DProxy, camera:Camera3D, viewProjection:Matrix3D):void
{
var context:Context3D = stage3DProxy._context3D;
var pos:Vector3D = camera.scenePosition;
_vertexData[0] = pos.x;
_vertexData[1] = pos.y;
_vertexData[2] = pos.z;
_vertexData[4] = _vertexData[5] = _vertexData[6] = camera.lens.far/Math.sqrt(3);
context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, viewProject
ion, true);
context.setProgramConstantsFromVector(Context3DProgramType.VERTEX, 4, _vertexData, 2);
renderable.activateVertexBuffer(0, stage3DProxy);
context.drawTriangles(renderable.getIndexBuffer(stage3DProxy), 0, renderable.numTriangles);
}
     

                    // 此函数是用来设置常量激活顶点缓冲区 0号常量为视图矩阵 4 5号常量为视距的最大长度除以根号3 也就是矩形体的对角线长度

    // 天空盒子的顶点数据为 -1 1 1 -1......的边长为2的矩形-1 1 即为顶点又为UV 因此VS代码可理解为:

    "mul vt0, va0, vc5 将单位为2的盒子缩放到最大视距的大小 

     "add vt0, vt0, vc4 将缩放后的盒子归一到0~对象线长度2倍的区域

"m44 op, vt0, vc0 将盒子缩放归一后的顶点转化到视图空间

"mov v0, va0 将原-1 1 1 -1等顶点数据作为UV值传给PS使用


PS代码 则是纹理采样的过程


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值