OpenGL ES系列三--GLSL着色器語言

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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章