2012年7月16日 星期一

Introduction to Stage3D: Part 5

Stage3D 基本介紹及教學

之前的例子都是在幾何圖形上渲染上不同的顏色,
這篇介紹如何在圖形上貼上材質,
進入貼圖之前,先說明一下 UV(U,V) 座標對應,
U 水平 V 垂直,以百分比描述。

UV: 0-1
0,0          1,0

1,0          1,1

貼圖大小通常為 256x256,512x512
不管材質的長寬是多少,實際在貼圖的時候會發現,
當放大縮小物件時,會出現鋸齒狀。
Mipmaps(MIP maps) 可以改善這狀形況,
簡單說 mipmaps 可以提高 render 效率及減少圖形鋸齒狀,
上傳不同大小的材質,GPU 會視狀況選用適當大小的材質來 render,
缺點是會佔用較多的 video ram[ref 1]。

直接來看程式碼,

定義頂點資料(x,yz,u,v)
var vertexData:Vector.<Number>=Vector.<Number>([
-0.5, 0.5, 0, 0, 0,
0.5, 0.5, 0, 1, 0,
0.5, -0.5, 0, 1, 1,
-0.5, -0.5, 0, 0, 1
]);
索引排列如下
0     1
3     2
vertexBuffer.uploadFromVector(vertexData, 0, 4);
indexBuffer.uploadFromVector(Vector.<uint>([0, 1, 2, 0, 2, 3]), 0, 6);

建立材質物件
width: 寬
height: 高
format: BitmapData 以 BGRA 格式來儲存 32 位元整數紋理/ByteArray 則使用慣用的 RGBA 格式來儲存 32 位元浮點數紋理
texture = context.createTexture(text.bitmapData.width, text.bitmapData.height, Context3DTextureFormat.BGRA, false);
上傳材質
texture.uploadFromBitmapData(text.bitmapData);

設定 register 0 -> (x,y,z)
context.setVertexBufferAt(0, vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
register 1 -> (u,v)
context.setVertexBufferAt(1, vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
fragment sampler -> texture
context.setTextureAt(0, texture);

AGAL assembly code
頂點座標 va0
code += "mov vt0, va0\n";
vt0*vc0 4x4矩陣相乘運算
code = "m44 op, vt0, vc0\n";
UV座標 v0 = va1
code += "mov v0, va1\n";
參照 UV 座標從材質 (fs0) 中取樣放入
片段暫存器(存放最後要輸出的材質)
<2d> 或 <2d,linear, nomip, repeat> 為取樣的方式
code = "text ft0 v0, fs0 <2d>\n"
此種方式,貼圖的畫質較佳
code = "text ft0 v0, fs0 <2d,linear, nomip, repeat>\n";
輸出
code += "mov oc, ft0\n";

最後一樣 render 出結果並輸出到螢幕。

附上結果圖。


[ref]
1. http://en.wikipedia.org/wiki/Mipmap

沒有留言:

張貼留言