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代碼 則是紋理採樣的過程


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章