初探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 兩個寄存器中

相關文章
相關標籤/搜索