Stage3d 由淺到深理解AGAL的管線vertex shader和fragment shader || 簡易教程 學習心得 AGAL 非常非常好的入門文章

總結來說,Stage3D是跟GPU打交道的技術。涉及到幾方面的知識:

1、渲染的過程,3d管線的概念。有vertex shader,有fragment shader,這連個是管線裏邊提供接口出來,可供自定義編程的

     http://hi.baidu.com/haorui1130/item/aa65dcceceaebf3f4494167b

2、Stage3D的context3d是核心,負責跟gpu打交道,上傳頂點信息xy、紋理信息uv、常量等。初始化時,每個xy對應一個uv

3、編寫兩個shader(利用AGAL),將上傳的信息計算出最後的結果值;

vertex shader負責計算圖形的大小變化、位置、旋轉;

fragment shader負責計算貼圖

需要注意的是:

  • vertex shader對整個繪圖區域,以中心點爲原點,y軸向上,範圍[-1, 1];而普通stage座標是,左上角爲原點,y軸向下
  • fragment shader的紋理座標又不一樣,左上角爲原點,y軸向下,範圍是[0, 1]

AGAL的指令,可以跟PixelBender的做比較,略有類似。

兩段程序,如果要執行片段shader,那麼在頂點shader的代碼最後需要把頂點位置信息傳到v0,以供片段shader取出來用

GPU會對每個頂點信息執行這兩個代碼,這就類似於PixelBender執行每一個像素

指令的相似:一樣用xyzxw存取float4,而float4跟float可以直接相乘,出來的還是float4。float4也可以乘以float4,出來的還是float4,是x和x,y和y分別相乘。

矩陣計算:

Matrix3D可以不斷乘以新的矩陣,等於多個變換集合在一起。比flash原來的Matrix好使多了。AGAL對Matrix3D的使用,其實跟flash普通sprite的matrix是同一個道理。

函數是append和prepend,兩者區別,打印矩陣一看就懂了

例子

利用Matrix3d和Vertex shader實現變形:

var matrix:Matrix3D = new Matrix3D();
matrix.appendScale(0.5, 0.5, 1);   //縮小一倍
matrix.appendTranslation(0.5, 0.25, 0);   //x移動0.5,也就是1/4,y移動0.25
matrix.appendRotation(45, new Vector3D(0,0,1));       //平時Sprite的旋轉45度
for (var i:int = 0; i < matrix.rawData.length; i+=4)
{
        trace(matrix.rawData[i] + "\t" + matrix.rawData[i + 1] + "\t" + matrix.rawData[i + 2] + "\t" + matrix.rawData[i + 3]);
}

_context3d.setProgramConstantsFromMatrix( "vertex", 0, matrix, true);     //這裏需要注意,涉及到位移,這裏需要把矩陣轉置一下,true表示先轉置一下。否則計算結果有問題

private var _vertexProgram:String = "m44 op, va0, vc0\n" +
                     "mov v0, va1";  //傳遞給片段shader座標值

利用Matrix3d和Fragment Shader實現sepia效果(舊照片濾鏡):

private var _fragmentProgram:String = "tex ft1, v0, fs0<2d,linear,nomip>\n" +
                                                               "m44 ft2, ft1, fc1\n" +                    //顏色變換
                                                               "mul ft2, ft2, fc0.x\n" +          //效果圖跟原圖做multiply,向量float4 * float = float4,類似PixelBender
                                                               "mul ft1, ft1, fc0.y\n" +
                                                               "add ft2, ft2, ft1\n" +
                                                               "mov oc, ft2" ;
//multiple比例
_context3d.setProgramConstantsFromVector( "fragment" , 0, new<Number>[1, 0, 0, 0]);
//顏色矩陣
_context3d.setProgramConstantsFromMatrix( "fragment" , 1, new Matrix3D( new <Number>[
       0.393, 0.768, 0.189, 0,
       0.349, 0.686, 0.168, 0,
       0.272, 0.534, 0.13, 0,
       0, 0, 0, 1
]));
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章