一. 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等數據。
這些寄存器是爲了從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. 操作符:
三. 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, viewProjection, 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代碼 則是紋理採樣的過程