GLSL是學習webgl的必備的知識點,故整理這篇文章
前言
GLSL Shader Example,這是一份不錯的練習例子。
1. 變數
1.1 基本型別
變數型別 | 說明 |
---|---|
bool | 布林型標量資料型別 |
int/ivec2/ivec3/ivec4 | 包含 1/2/3/4 個整型向量 |
float/vec2/vec3/vec4 | 包含 1,2,3,4 個浮點型向量 |
sampler2D | 表示 2D 紋理 |
samplerCube | 表示立方體紋理 |
mat[2..3] | 表示 2x2 和 3x3 的矩陣 |
mat4 | 表示 4x4 的矩陣 |
sampler1D | 用於內建的紋理函式中引用指定的 1D 紋理的控制程式碼。只可以作為一致變數或者函式引數使用 |
sampler2D | 二維紋理控制程式碼 |
sampler3D | 三維紋理控制程式碼 |
samplerCube | cube map 紋理控制程式碼 |
sampler1DShadow | 一維深度紋理控制程式碼 |
sampler2DShadow | 二維深度紋理控制程式碼 |
1.2 內建變數
頂點著色器可用的內建變數如下表:
名稱 | 型別 | 描述 |
---|---|---|
gl_Color | vec4 | 輸入屬性-表示頂點的主顏色 |
gl_SecondaryColor | vec4 | 輸入屬性-表示頂點的輔助顏色 |
gl_Normal | vec3 | 輸入屬性-表示頂點的法線值 |
gl_Vertex | vec4 | 輸入屬性-表示物體空間的頂點位置 |
gl_MultiTexCoordn | vec4 | 輸入屬性-表示頂點的第 n 個紋理的座標 |
gl_FogCoord | float | 輸入屬性-表示頂點的霧座標 |
gl_Position | vec4 | 輸出屬性-變換後的頂點的位置,用於後面的固定的裁剪等操作。所有的頂點著色器都必須寫這個值。 |
gl_ClipVertex | vec4 | 輸出座標,用於使用者裁剪平面的裁剪 |
gl_PointSize | float | 點的大小 |
gl_FrontColor | vec4 | 正面的主顏色的 varying 輸出 |
gl_BackColor | vec4 | 背面主顏色的 varying 輸出 |
gl_FrontSecondaryColor | vec4 | 正面的輔助顏色的 varying 輸出 |
gl_BackSecondaryColor | vec4 | 背面的輔助顏色的 varying 輸出 |
gl_TexCoord[] | vec4 | 紋理座標的陣列 varying 輸出 |
gl_FogFragCoord | float | 霧座標的 varying 輸出 |
片段著色器的內建變數如下表:
名稱 | 型別 | 描述 |
---|---|---|
gl_Color | vec4 | 包含主顏色的插值只讀輸入 |
gl_SecondaryColor | vec4 | 包含輔助顏色的插值只讀輸入 |
gl_TexCoord[] | vec4 | 包含紋理座標陣列的插值只讀輸入 |
gl_FogFragCoord | float | 包含霧座標的插值只讀輸入 |
gl_FragCoord | vec4 | 只讀輸入,視窗的 x,y,z 和 1/w |
gl_FrontFacing | bool | 只讀輸入,如果是視窗正面圖元的一部分,則這個值為 true |
gl_PointCoord | vec2 | 點精靈的二維空間座標範圍在(0.0, 0.0)到(1.0, 1.0)之間,僅用於點圖元和點精靈開啟的情況下。 |
gl_FragData[] | vec4 | 使用 glDrawBuffers 輸出的資料陣列。不能與 gl_FragColor 結合使用。 |
gl_FragColor | vec4 | 輸出的顏色用於隨後的畫素操作 |
gl_FragDepth | float | 輸出的深度用於隨後的畫素操作,如果這個值沒有被寫,則使用固定功能管線的深度值代替 |
2. 修飾符
變數的宣告可以使用如下的修飾符:
修飾符 | 描述 |
---|---|
const | 常量值必須在宣告時初始化。它是隻讀的不可修改的。 |
attribute | 表示只讀的頂點資料,只用在頂點著色器中。資料來自當前的頂點狀態或者頂點陣列。它必須是全域性範圍宣告的,不能在函式內部。一個attribute可以是浮點數型別的標量,向量,或者矩陣。不可以是陣列或者結構體 |
uniform | 一致變數。在著色器執行期間一致變數的值是不變的。與const常量不同的是,這個值在編譯時期是未知的是由著色器外部初始化的。一致變數在頂點著色器和片段著色器之間是共享的。它也只能在全域性範圍進行宣告。 |
varying | 頂點著色器的輸出。例如顏色或者紋理座標,(插值後的資料)作為片段著色器的只讀輸入資料。必須是全域性範圍宣告的全域性變數。可以是浮點數型別的標量,向量,矩陣。不能是陣列或者結構體。 |
centorid varying | 在沒有多重取樣的情況下,與varying是一樣的意思。在多重取樣時,centorid varying在光柵化的圖形內部進行求值而不是在片段中心的固定位置求值。 |
invariant | (不變數)用於表示頂點著色器的輸出和任何匹配片段著色器的輸入,在不同的著色器中計算產生的值必須是一致的。所有的資料流和控制流,寫入一個invariant變數的是一致的。編譯器為了保證結果是完全一致的,需要放棄那些可能會導致不一致值的潛在的最佳化。除非必要,不要使用這個修飾符。在多通道渲染中避免z-fighting可能會使用到。 |
in | 用在函式的引數中,表示這個引數是輸入的,在函式中改變這個值,並不會影響對呼叫的函式產生副作用。(相當於C語言的傳值),這個是函式引數預設的修飾符 |
out | 用在函式的引數中,表示該引數是輸出引數,值是會改變的。 |
inout | 用在函式的引數,表示這個引數即是輸入引數也是輸出引數。 |
3. 陣列
GLSL中只能使用一維陣列。陣列的型別可以是一切基本型別或者結構體。宣告方式如下:
vec4 transMatrix[4];
vec4 affineMatrix[4] = {0, 1, 2, 3};
vec4 rotateMatrix = affineMatrix;
4. 結構體
struct rotateMatrix {
float x;
float y;
float z;
float coeff[8];
}
struct positionInfo {
vec2 coord;
float value;
rotateMatrix matrix;
}
5. 控制結構
5.1 迴圈
for (int s = 0; s < 7; s++) {
vec2 r;
r = vec2(cos(uv.y * i0 - i4 + time / i1), sin(uv.x * i0 - i4 + time / i1)) / i2;
r += vec2(-r.y, r.x) * 0.3;
uv.xy += r;
i0 *= 1.93;
i1 *= 1.15;
i2 *= 1.7;
i4 += 0.05 + 0.1 * time * i1;
}
5.2 控制語句
與js一致,注意沒有switch語句,且if過多會消耗效能。
if(express) {
}
6. 函式
6.1 自定義函式
float noise(in vec2 pt) {
return snoise(pt) * 0.5 + 0.5;
}
6.2 內建函式
- 常用函式
語法 | 說明 |
---|---|
genType abs (genType x) | x的絕對值 |
genType sign (genType x) | 判斷x是正數、負數,還是零 |
genType floor (genType x) | 返回不大於x的最大整數 |
genType ceil (genType x) | 返回不小於x的最小整數 |
genType fract (genType x) | 返回x的小數部分,即x-floor(x) |
genType mod (genType x, genType y) | 返回x – y * floor (x/y) |
genType min (genType x, genType y) | 返回x和y的較小值 |
genType max (genType x, genType y) | 返回x和y的較大值 |
genType clamp (genType x, genType minVal, genType maxVal) | min (max (x, minVal), maxVal),如果minVal > maxVal,則返回undefined |
genType mix (genType x, genType y, genType a) | 返回x (1−a) + y a |