初探Stage3D(二) 了解AGAL

关于本文

本文并没有打算事无巨细的介绍一遍AGAL,仅仅是对现有文档的一些理解及汇总,因此请先阅读相参考文档html

 

 

AGAL概念

参考资料spa

建议去看英文,中文翻译的很烂,要是想看英文,请在下方将语言换为英语,不然仍旧自动跳转回中文翻译

image

如文档中所说,AGAL(Adobe Graphics Assembly Language) 是一种接近于GPU指令的语言,同Pixel Bender3D的区别在于code

一个事先须要先编译好(Pixel Bender3D),component

另一个仅仅为一段字符串(借助AGAL Mini Assembler),能够在运行期间动态改变。orm

 

关于AGAL语法

<opcode> <destination>, <source 1>, <source 2 or sampler>

 

什么是AGAL Mini Assembler

文档中说起的AGAL Mini Assembler是一个小类库,下载地址http://www.bytearray.org/wp-content/projects/agalassembler/com.ziphtm

主要是用于将字符串形式的AGAL转换为ByteArray。blog

在代码中最后上传这些操做给GPU时候,实际用到的方法为ip

var program:Program3D = context3D.createProgram(); 
program.upload( vertexShaderAssembler.agalcode, fragmentShaderAssembler.agalcode);

能够在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-wise
  • add: destination = source1 + source2, component-wise
  • sub: destination = source1 – source2, component-wise
  • mul: destination = source1 * source2, component-wise
  • div: destination = source1 / source2, component-wise
  • dp3: dot product (3 components) between source1 and source2
  • dp4: dot product (4 components) between source1 and source2
  • m44: multiplication between 4 components vector in source1 and 4×4 matrix in source2
  • tex: texture sample. Load from texture at source2 at coordinates source1.

要了解后续代码的意思,须要引入寄存器的概念

 

关于Registers(汇编语言中有讲过)

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,什么是Pixel shaders

参考资料:

就我我的理解,应该能够认为Vertex Shader主要处理顶点相关的计算,如在数学上定义的一个三角形x(0,1,0),y(1,0,0),z(0,0,1),将这个三角形进行缩放,旋转等操做时候须要用到 Vertex Shader,

当该三角形完成以上所有操做后,后续的对其进行着色(UV map等)操做时候就须要用到Pixel shaders

 

6种寄存器类型

  • va<n> : Attribute registers -- 仅用于处理Vertex Shader,一共有8个,va0~va7
  • vc<n> fc<n> : Constant registers -- 用于存储从AS中传入的变量,Vertex Shaders能够用128个,及vc0~vc127,Pixel Shaders能够用28个,及fc0~fc27
  • vt<n> ft<n> : Temporary registers -- 用于存储计算中产生的临时数据,Vertex Shader和Pixel shaders各有8个,vt0~vt7 (Vertex Shaders),ft0~ft7 (Pixel Shaders)
  • op oc : Output registers -- 存储计算的结果,op用于存储Vertex Shaders,oc 用于存储Pixel Shaders
  • v<n> : Varying Registers -- 用于将Vertex Shader的数据传给Pixel shaders进行渲染,一共有8个,对应为v0~v7(我的理解 由于Attribute registers仅有8个)
  • fs<n> <flags> : Texture sampler registers -- 用于UV映射(3D渲染原理内具体说明)

再看例子

m44 op, va0, vc0 // pos to clipspace

mov v0, va1 // copy color

根据AGAL语法:<操做指令>,<目标>,<数据源1>,<数据源2>

m44 op,va0,vc0

将va0(顶点坐标),和vc0(AS中传入的变量)执行m44(矩阵相乘),放入op(顶点计算结果)中

 

一点疑惑

例子中的两行代码是否有任何关系?

m44 op, va0, vc0 // pos to clipspace mov v0, va1 // copy color

由于第二行代码仅操做的 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里面(后续会放出),存在以下代码

public function setVertexBufferAndTexture(context:Context3D, texture:Texture):void
{
    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 两个寄存器中

相关文章
相关标签/搜索