在webgl中,調用了OpenGL-ES-2.0的API,而在OpenGL-ES專爲嵌入式設備設計,其和其它設備同樣,都是使用GLSL(GL Shading Language)來編寫片斷程序並執行於GPU的着色器上,來完成對對象的渲染。GLSL在其中起着至關重要的做用,因此要玩好webgl,咱們就得把GLSL搞懂,本文主要介紹shader的基礎使用及組成。web
整個管線處理過程:數組
1.指定幾何對象緩存
2.逐個頂點操做函數
3.圖元組裝webgl
根據指定的圖元組裝方式將若干頂點組成一個圖元,OpenGL支持的幾何圖元有點、線、不閉合折線、閉合折線、多邊形、三角形、線型連續填充三角形、扇形連續填充三角形、四邊形以及連續填充四邊形。spa
而webgl支持的圖元爲POINTS(點), LINE_STRIP(不閉合折線), LINE_LOOP(閉合折線), LINES(獨立的線段), TRIANGLE_STRIP(頂點按順序相連的三角形), TRIANGLE_FAN(扇形順序組合三角形), TRIANGLES(每三個頂點組合成一個三角形)。.net
繪製三角形序列的三種方式解釋了三種三角形繪製方法之間的不一樣。設計
4.圖元處理指針
5.柵格化(生成片元fragment)code
6.片元處理
7.逐個片元操做
8.幀緩衝區操做
在這八個步驟中,咱們最重要的是對頂點和片元的操做,在整個管線中,咱們能夠加入的本身程序的部分則是頂點着色器和片元着色器部分。
頂點着色器:
操做的是頂點值和其關聯的數據,它可完成下面這些操做:
頂點着色器必須計算座標在裁剪空間中的齊次位置並將結果存儲在特殊的輸出變量gl_Position中,它還有特殊的輸出變量gl_ClipVertex,gl_PointSize。
頂點處理器的輸出將被髮送到後續的處理階段,即:圖元組裝,用戶裁剪,平截裁剪,透視劃分,視口貼圖,多邊形偏移,多邊形模式,陰影模式,消隱等。
片元着色器:
處理片元值及其相關聯數據,它可執行傳統的圖形操做,如:
在插值等到的值上的操做
片元着色器其有特殊的輸入變量gl_FragCoord(片元的窗口相對座標)和gl_FrontFacing(正面圖元爲true,反之爲false),通過計算顏色和深度將這些值寫入特殊的輸出變量gl_FragColor和gl_FragDepth中,或者徹底丟棄(使用discard關鍵字)片元。
片元處理器的一大優勢是它能夠任意屢次地訪問紋理內存,並能夠任意方式結合所讀取的值,一次紋理訪問的結果可做爲執行另外一次紋理訪問的基礎。
有三個精度可選擇:lowp highp mediump
精度可指定於變量或設置默認精度
頂點着色器中的float和init默認精度爲highp
片元着色器中float沒有默認精度,因此必須爲其指定默認精度,如:precision mediump float;
着色器多個執行是可並行發生的,針對每一個頂點都會執行一次頂點着色器,針對每一個片元都會執行一次片元着色器。
咱們要向着色器中傳入數據,則要了解其裏面變量的組成和輸入方式
屬性變量(attribute):
這些變量表明瞭很是頻繁地從應用程序傳遞到頂點處理器的值,只應用於程序中定義頂點數據,因此只容許做爲頂點着色器的一部分,該值能夠像每一個頂點那樣常常變更
一致變量(uniform):
用來將數據值從應用程序傳遞到頂點處理器或片元處理器,一致變量一般用來提供不頻繁變更的值。
易變變量(varying):
定義了從頂點處理器傳遞到片元處理器的數據。
常量變量(const):
如C中的常量變量
標量:
支持使用浮點數(float)、整數(int)和布爾值(bool)
矢量:
浮點數矢量:
vec2 (2個浮點數的矢量)
vec3 (3個浮點數的矢量)
vec4 (4個浮點數的矢量)
整數矢量:
ivec2 (2個整數的矢量)
ivec3 (3個整數的矢量)
ivec4 (4個整數的矢量)
布爾矢量:
bvec2 (2個布爾值的矢量)
bvec3 (3個布爾值的矢量)
bvec4 (4個布爾值的矢量)
矩陣:
mat2 (2×2的浮點數矩陣)
mat3 (3×3的浮點數矩陣)
mat4 (4×4的浮點數矩陣)
mat矩陣就像是一個vec數組,它也可使用數組來進行訪問。
取樣器:
sampler1D (訪問一個一維紋理)
sampler2D (訪問一個二維紋理)
sampler3D (訪問一個三維紋理)
samplerCube (訪問一個立方貼圖紋理)
sampler1DShadow (訪問一個帶對比的一維深度紋理)
sampler2DShadow (訪問一個帶對比的二維深度紋理)
只能經過uniform限定的取樣器從應用程序接收取樣器
使用時: uniform sampler2D texture;
若是要對矢量進行部分操做,則可用訪問矢量中的部分來使用,在shader中,共有三組組合供使用:
這四個值只是分別讀取矢量中的第一個、第二個、第三個、第四個值,只是爲了編寫方便,語義化了三組組合,分別爲座標、紋理、顏色,可是使用它們去讀取出來的值是同樣的,如:
vec4 values = vec4(1.0,2.0,3.0,4.0); values.z; //3.0 values.p; //3.0 values.b; //3.0
values[2]; //3.0
這三組使用時必須成組出現,不能混組出現,如:
vec4 values = vec4(1.0,2.0,3.0,4.0); vec2 combination1 = values.xy; //同一組,正確 vec3 combination2 = values.rgb; //同一組,正確 vec3 combination3 = values.xt; //不一樣組,不正確
對矩陣的讀取能夠像數組同樣:
vec2 x,y; mat2 matrix; x = matrix[0]; y = matrix[1];
對於矢量的計算:
vec3 v,u,w; w = v + u; //計算過程等價於 w.x = v.x + u.x; w.y = v.y + u.y; w.z = v.z + w.z;
對於矩陣和矢量的計算:
//該過程遵照線性代數中的計算規定,即作點乘的兩個矩陣,前一個矩陣的行數等於後一個矩陣的列數 vec4 v,u; mat4 m; v * m; //行矢量與矩陣相乘 m * v; //矩陣與列矢量相乘 m * m; //矩陣與矩陣相乘
運算順序:
//當多個矩陣同時施加加頂點矢量上時,則要以相反的順序矩陣相乘 //如想實現先Ma再Mb的運算 vec4 v,u; mat4 Ma,Mb; u = Mb * (Ma * v); //即 u = (Mb * Ma) * v; //即 u = Mb * Ma * v;
着色語言做爲一種處理數字的語言,而不是處理字符或字符串數據的語言,在其中沒有包含對指針、字符串、字符或基於這些類型的任何操做支持。
而且爲了使編譯器和圖形硬件的實現負擔更小,該語言不支持雙精度浮點數、字節、短整數、長整數或者這些類型的無符號變化形式。
其包括了C++的一些重要語言特性:支持函數重載,支持基本類型bool。
在向頂點着色器中進行傳值時,頂點着色器會從緩存中依次讀取每一個頂點,若是使用的是頂點數組方法:
如傳入:new Float32Array([1.0,1.0,1.0,0.0,
0.5,0.5,0.5,0.0]);
那麼在shader中,假設有attribute vec4 position;
會從緩存中依次讀取四個數來做爲position進行處理,則總共執行了兩次頂點着色器,共兩個頂點。
若是在shader中有attribute vec2 position;
則會從緩存中依次讀取兩個數來做爲position進行處理,共四個頂點,頂點着色器執行四次。
WebGL-1.0參考卡片:http://files.cnblogs.com/files/zhiyishou/webgl-reference-card-1_0.pdf
OpenGL-ES-2.0參考卡片:http://files.cnblogs.com/files/zhiyishou/OpenGL-ES-2_0-Reference-card.pdf
The end.