GLSL語言–OpenGL Shading Language
無論是OpenGL還是其他圖形API的着色器,通常都是通過一種特殊的編程語言去編寫的。對於OpenGL來說,我們會使用GLSL,它是在OpenGL2.0版本左右發佈的,GLSL與“C”語言非常類似,當然還有一點C++的影子。因爲從下一節基本圖元的繪製開始,我們就會開始接觸到GLSL,所以必須先介紹GLSL。我們主要從以下幾個常用的方面介紹:
1. 註釋
類型 | 符號 |
---|---|
單行註釋 | // |
多行註釋 | /* 內容 */ |
2.基本數據類型
GLSL是一種強類型語言,所有變量都必須事先聲明,並要給出變量的類型(如下表)。變量名的命名規範與C語言相同:可以使用字母、數字、以及下劃線字符,但是數字不能作爲變量名稱的第一個字符,此外也不能包含連續的下劃線。
類型 | 符號 |
---|---|
float | 32位浮點數 |
double | 64位浮點數(使用double時要看是否支持,不支持要看起擴展) |
int | 有符號二進制補碼的32位整數 |
uint | 無符號的32位整數 |
bool | 布爾值 |
3. 聚合類型
GLSL的基本類型可以合併,從而與OpenGL的數據類型相匹配。GLSL支持2個、3個以及4個分量的向量,每個分量都可以使用bool、int、uint、float、double這些基本變量,此外GLSL也支持float和double類型的矩陣。具體如下表:
基本類型 | 2D向量 | 3D向量 | 4D向量 | 矩陣類型 | 非方陣矩陣 |
---|---|---|---|---|---|
float | vec2 | vec3 | vec4 | mat2 mat3 mat4 | mat2x2 mat2x3 mat4x2… |
double | dvec2 | dvec3 | dvec4 | dmat2 dmat3 dmat4 | dmat2x2 dmat2x3 dmat4x2… |
int | ivec2 | ivec3 | ivec4 | ||
uint | uvec2 | uvec3 | vec4 | ||
bool | bvec2 | bvec3 | bvec4 |
在上面的非方陣矩陣中給出了兩個維度的信息,例如mat4x3,其中第一個值表示列數,第二個值表示行數。
在訪問向量時可以通過以下幾種方式,我們以常用的vec4爲例:
分量訪問符 | 符號描述 |
---|---|
(x、y、z、w) | 與位置相關的分量 |
(r、g、b、a) | 與顏色相關的分量 |
(s、t、p、q) | 與紋理相關的分量 |
//定義一個顏色向量(需要注意的是不能混合使用分量訪問符)
vec4 color = vec4(1.0f,1.0f,1.0f,1.0f);
float red = color.r;
float green = color.g;
color.b = 0.2f;
//錯誤示範
vec2 temp = color.ry;
...
//矩陣訪問
mat4 m = mat4(2.0);
//獲取矩陣的第二列(從0開始)
vec4 zVec = m[2];
float yScale = m[1][1];
4. 結構體
結構體和C語言的用法類似,我們就簡單的寫一個示例來說明:
struct Demo{
float lifeTime;
vec3 position;
};
vec3 pos = vec3(1.0);
Demo d = Demo(10.0,pos);
這個目前我用的不是很多,如果後面用的多的話,會更新這些文章的。所以這裏就簡單說明一下。
5. 數組
GLSL支持任意類型的數組,包括結構體數組。這個和C語言也是差不多的,下面寫一個示例:
//有3個float元素的數組
float coeff[3];
float[3] coeff;
//未定義維數,後面可以重新聲明它的維數
int indices[];
6.存儲限制符
通過存儲限制符可以改變數據類型的行爲。GLSL中一共定義了以下幾種全局範圍內的修飾符,如下表:
類型修飾符 | 描述 |
---|---|
const | 將一個變量定義爲只讀形式 ,必須在聲明時初始化 |
in | 設置變量爲着色器階段的輸入變量 |
out | 設置變量爲着色器階段的輸出變量 |
inout | 設置變量同時作爲輸入、輸出變量 |
uniform | 設置變量爲應用程序傳遞給着色器的數據 |
buffer | 指定後面所修飾的塊作爲着色器與應用程序共享的一塊內存緩存。這塊緩存對於着色器來說是可讀、可寫的 |
shared | 設置變量是本地工作組中共享,它只能用於計算着色器中 |
attribute | 表示只讀的頂點數據,只用在頂點着色器中 可以是浮點數類型的標量,向量,或者矩陣 |
varying | 作爲頂點和片元中的共享參數,注意參數名必須相同 |
以上這些限制符在後面的文章所搭配的Demo中只要有用到都會有詳細說明。
7.語句
語句這裏蠻多的,主要說明一些我們常用的:
- 算術運算符
操作符 | 描述 |
---|---|
() | 用於表達式組合,函數調用,構造 |
[] | 數組下標,向量或矩陣的選擇器 |
. | 結構體和向量的成員選擇 |
++ – | 前綴或後綴的自增自減操作符 |
|
一元操作符,表示正 負 邏輯非 |
|
乘 除操作符 |
|
二元操作符 表示加 減操作 |
<> <= >= == != | 小於,大於,小於等於, 大於等於,等於,不等於 判斷符 |
&& || ^^ | 邏輯與 ,或, 異或 |
?: | 條件判斷符 |
= += –= *= /= | 賦值操作符 |
, | 表示序列 |
- 循環語句
for(int i = 0; i < 10;i++){}
while(n<10){}
do{
...
}while(n<10);
- 流控制語句
語句 | 描述 |
---|---|
break | 跳出當前所以的最近一層的循環 |
continue | 終止本次循環,繼續下一次循環 |
return | 結束當前函數,可攜帶返回值 |
discard | 丟棄當前的片元,終止着色器的執行。discard只在片元着色器中生效 |
函數
GLSL中的函數和C也是差不多的,如下,我們就不在多說了。
void test(float a){
}
到這裏在OpenGL ES中常用的GLSL着色器語言就差不多了。下面我們給出了兩個示例着色器代碼。
頂點着色器
//從變換矩陣
uniform mat4 uMVPMatrix;
//頂點數據
attribute vec3 aPosition;
//顏色
attribute vec4 aColor;
//傳遞給片元着色器的顏色
varying vec4 vColor;
/*
* 程序入口
*/
void main() {
gl_Position = uMVPMatrix*vec4(aPosition,1);
vColor = aColor;
}
片元着色器
precision mediump float;
//接收從頂點着色器過來的參數
varying vec4 vColor;
void main() {
//給片元設置顏色值
gl_FragColor = vColor;
}