iT邦幫忙

DAY 10
0

30 天實戰跨平台行動APP系列 第 10

Day 10 Web GL Shader介紹

經過昨天一番折騰,做了WebGL第一個範例,是不是覺得非常的麻煩呢。雖然過去也有過寫shader的經驗,

但是那是為了要達成一些特殊效果。但OpenGL ES 與 WebGL是只能使用shader,為什麼這就要從Graphic pipeline來看,

Graphic Pipeline就是指電腦運算資料,最後顯示在螢幕上的一個流程。

*上圖出自於Brian Danchilla所著Beginning WebGL for HTML5第34頁

由上圖我們先看起點跟終點,終點就是Frame Buffer,就是儲存螢幕資料的一塊記憶體,就算你的繪圖程式中間有多驚人的運算,最終輸出就是每一個pixel他的顏色值是多少,組成的pixel陣列。

起點就是我們呼叫WebGL API 程式。呼叫api做環境的設定,然後提供vertex資料,呼叫api說要怎麼畫(triangle or line or?) ,上傳材質貼圖,這邊是fixed functionality一樣要做的,沒什麼不同。

再來看倒數第二行 ,電腦開始將vertex組成多邊形,算出每個vertex在螢幕上的位置,組成多邊形,然後做viewport的裁切,螢幕外的都不用理他,之後根據vertex的顏色或是材質,開始算出多邊形的顏色,

最後做alpha blending(如果有半透明要計算),depth test(被擋道不會顯示的就丟棄), stencil test (看你有沒有自定一些mask),產生最後的直存進frame buffer。這邊也是fixed functionality會做的。

與fixed functionality的差別就在Vertex Shader與Fragment Shader這邊可以讓你做一些自定的運算。fixed functionality你設定好vertex, texture , lighting..等這些設定,進入pipeline後就不能再改變了。

但是借由vertex shader與fragment shader的幫助,就可以達成fixed functionality達不成的效果。

例如一些自定的光影效果,一些filter與mask,或是進階的材質操作技術。我之前會使用shader就是因為我要使用dependable texture reading。就是建立一個材質當作lookup table,然後主要顯示的材質會根據lookup table來改變。

總之,就是比fixed functionality厲害就是了。

*上圖出自於Brian Danchilla所著Beginning WebGL for HTML5第35頁

圖2-2是上面那個流程的圖形化,由這圖可以清楚看到vertex shader與fragment shader他們分別做事的階段在哪裡。

GLSL 語言

寫shader就要用GL shader language,縮寫就是GLSL了。跟OpenGL一樣,也是有 GLSL ES,GLSL ES是基於GLSL1.20版本發展的,

而WebGL就是使用GLSL ES。GLSL是基於C++發展的語言,有兩種shader可以寫,分別是vertex shader與fragment shader,vertex shader可以

調整vertex的各項參數,例如位置,法向量,燈光,顏色,fragment shader則可以調整每個pixel的最終顏色值。

shader的程式要寫在哪裡呢?

  1. 跟上一個範例一樣直接寫在網頁內,在<script> tag 內,type要設定為 ”x-shader/x-vertex” ”x-shader/x-fragment”
  2. 寫在外部檔案,再用ajax方式讀取

1 昨天我們已經介紹過囉,所以現在來介紹2,

AJAX可以用 jQuery或是用XMLHttpRequest,我用XMLHttpRequest來做介紹,

 	var     vs_source = null,

        fs_source = null;



 	http_request = new XMLHttpRequest();

 

 	http_request.open('GET','./vertex_shader.vs',false);

 

 	http_request.overrideMimeType('text/xml');

 

 	http_request.send(null);

 

 	if(http_request.readyState==http_request.DONE){

 	 if(http_request.status==200){

 	 vs_source = http_request.responseText;

 	 }

 	 else{

 	 alert("loading vertex shader error");

 	 }

 	}

 

 	http_request.open('GET','./fragment_shader.fs',false);

 	 

 	http_request.send(null);

 

 	if(http_request.readyState==http_request.DONE){

 	 if(http_request.status==200){

 	 fs_source =  http_request.responseText;

 	 }

 	 else{

 	 alert("loading fragment shader error");

 	 }

 	}

將寫在script tag中的shader code分別存在.vs與.fs檔案裡面,上傳到server,

就可以實現ajax load shader,站在開發方便管理的角度,這樣子是比較好的!

至於GLSL的細節,推薦

http://www.amazon.com/OpenGL-Shading-Language-3rd-Edition/dp/0321637631

這本大象封面的書,大陸有出簡體版的!但我覺得直接看英文其實還比較好懂,

一開始接觸的可以快速把握幾個重點:

  • gl_開頭的都是保留字

  • void , bool , int , float - C/C++ type

  • vec2,vec3,vec4 - GLSL type,代表1*2, 1*3,1*4

  • mat2,mat3,mat4 - GLSL type ,代表2*2, 3*3, 4*4 矩陣

  • sampler2D, sampler3D, samplerCube - GLSL type 代表材質

  • 儲存屬性的修飾詞有const, uniform, attribute, varying

    • const 常數
    • uniform 在 primitive 中的常數
    • attribute 我們從WebGL傳給 vs shader的變數
    • varying 從vs shader傳到 fs shader的變數
  • 內建變數

    • gl_FragColor 最終的fragment值
    • gl_Position vertex值
  • 向量變數可以用 (x,y,z,w) (r,g,b,a) (s,t,p,q) 三種方式來取得裡面某分量的值,可分別代表位置,顏色,材質,有利程式的可讀性

  • 有非常多的內建數學函式,可以去抓GLSL的說明文件查看

  • 材質對照函式,輸入材質物件與對照的坐標

    • vec4 texture2D (sampler2D sampler,vec2 coord)

GLSL 的簡易介紹就到這邊為止囉,目前看來,做Computer Graphic相關的是一定要懂得著色語言的!


上一篇
Day 9 : WebGL初探
下一篇
Day 11 WebGL 顏色
系列文
30 天實戰跨平台行動APP26

尚未有邦友留言

立即登入留言