1.類型轉換內置函數
轉換/函數/描述
轉換為整形數/int(float)/將浮點數的小數部分刪去,轉換為整形數(比如,將3.14轉換為3)
轉換為整形數/intl(bool)/true被轉換為1,false被轉換為0
轉換為浮點數/float(int)/將整形數轉換為浮點數(比如,將8轉換為8.0)
轉換為浮點數/float(bool)/true被轉換為1.0,false被轉換為0.0
轉換為布爾值/bool(int)/0被轉換為false,其他非0倍轉換為true
轉換為布爾值/0.0被轉換為false,其他非0值被轉換為true
2.矢量和矩陣類型
類型/GLEL ES 數據類型/描述
矢量/vec2、vec3、vec4/具有2、3、4個浮點數元素的矢量
矢量/ivec、ivec3、ivec4/具有2、3、4個整形數元素的矢量
矢量/bvec、bvec3、bvec4/具有2、3、4個布爾值元素的矢量
矩陣/mat2、mat3、mat4/2*2、3*3、4*4的浮點數元素的矩陣(分別具有4、9、16個元素)
3.分量名
類別/描述
x、y、z、w/用來獲取頂點坐標分量
r、g、b、a/用來獲取顏色分量
s、t、p、q/用來獲取紋理坐標分量
由於矢量可用來存儲頂點的坐標、顏色、紋理坐標,所以GLSL ES支持以上三種分量名稱以增強程序的可讀性。事實上,任何矢量的x、r或s分量都會返回第一個分量,y、g、t分量都返回第二個分量,等等。比如:
vec3 v3 = vec3(1.0, 2.0, 3.0) //將v3設置為(1.0, 2.0, 3.0) float f; f = v3.x; //設置f為1.0 f = v3.y //設置f為2.0 f = v3.z //設置f為3.0 f = v3.r; //設置f為1.0 f = v3.s; //設置f為1.0
將多個分量名共同置於點運算符后,就可以從矢量中同時抽取出多個分量。這個過程稱為混合(swizzing)。下面的例子中,我們使用了x、y、z和w,其他的集合也有相同的效果:
vec2 v2; v2 = v3.xy; //設v2為(1.0, 2.0) v2 = v3.yz; //設v2位(2.0, 3.0) 可以省略任意分量 v2 = v3.xz; //設v2位(1.0, 3.0) 可以跳過任意分量 v2 = v3.yx; //設v2為(1.0, 1.0) 可以逆序 v2 = v3.xx; //設v2為(1.0, 1.0) 可以重復任意分量 vec3 v3a; v3a = v3.zyx; //設v3a位(3.0, 2.0, 1.0),可以使用所有分量
4.[]運算符
矩陣中的元素任然是按照列主序讀取的。與在javascript中一樣,下表從0開始,所以通過[0]可以訪問到矩陣中的第一列元素,[1]可以訪問到第二列元素,[2]可以訪問到第三列元素,如下所示:
此外,連續兩個[]運算符可以訪問某列的某個元素:
float m23 = m4[1][2]; //將m23設置為m4的第二列中的第三個元素(7.0)。
5.數組
GLSL ES只支持一維數組,而且數組對象不支持pop()和push()等操作,創建數組時也不需要使用new運算符。聲明方式如下:
float floatArray[4]; // 聲明含有4個浮點數元素的數組 vec4 vec4Array[2]; // 聲明含有兩個vec4對象的數組
數組的長度必須是大於0的整形常量表達式,如下定義:
1.整形字面量(0、1)
2.用const限定字修飾的全局變量或局部變量,不包含函數參數
因此,下面的代碼將會出錯:
int size = 4; vec4 vec4Array[size]; //錯誤。如果第一行為const int size = 4;則不會報錯
6.取樣器(紋理)
我們必須通過取樣器(sampler)類型變量訪問紋理。有兩種基本的取樣器類型:sampler2D和samplerCube。取樣器變量只能是uniform變量,或者需要訪問紋理的函數,如texture2D()函數的參數。比如:
uniform smapler2D u_Sampler;
此外,唯一能賦給去取樣變量的就是紋理單元編號,而且你必須使用WebGL方法gl.uniform1i()來進行賦值。例如:
gl.uniform1i(u_Sampler, 0) //將紋理單元編號0傳給着色器
7.規范聲明
如果函數定義在其調用之后,那么我們必須在進行調用之前先聲明該函數的規范。規范聲明不預先告訴WebGL系統函數的參數、參數類型、返回值類型等等。例如:
float luma(vec4); //規范聲明 main(){ ... float brightness = luma(color); //luma()在定義之前就被調用了 } float luma(vec4 color){ return 0.2126 * color.r + 0.7162 * color.g + 0.0722 * color.r; }
8.內置函數
9.存儲限定字
在GLSL ES中,我們經常使用attriute、varying和uniform限定字來修飾變量,如圖所示:
此外,我們有時也會使用const限定字,它表示着色器中的某個變量使恆定的常量。幾個存儲限定自的使用分別如下:
1.Attribute變量
attribute變量只能出現在定點着色器中,只能被聲明為全局變量,被用來表示逐頂點的信息。頂點着色器中能夠容納的attribute變量的最大數目與設備有關,你可以通過訪問內置的全局常量獲取該值。但是,支持WebGL環境都支持至少8個attribute變量。如下所示:
2.uniform變量
可以用在頂點着色器和片元着色器中,且必須是全局變量。uniform變量是只讀的,它可以是除了數組或結構體之外的任意類型。如果頂點着色器和片元着色器中聲明了同名的uniform變量,那么它就會被兩種着色器共享。
3.varying變量
必須是全局變量,它的任務是從頂點着色器向片元着色器傳輸數據。我們必須在梁總着色器中聲明同名、同類型的varying變量。它的類型只能是以下類型:float、vec2、vec3、vec4、mat2、 mat 3、mat4。
10.精度限定字
GLSL ES新引入了精度限定字,目的是幫助着色器程序提高運行效率,消減內存開支。使用精度限定字,你就能夠精細地控制程序在效果和性能間的平衡。然而,精度限定字是可選的,如果你不確定,可以使用下面這個適中的默認值:
#ifdef GL_ES precision mediump float; #endif
如下所示,WebGL程序支持三種精度,其限定字分別為highp、mediump、lowp。
下面是聲明變量精度的幾個例子:
mediump float size; //中精度的浮點型變量 highp vec4 position; //具有高精度浮點型元素的vec4對象 lowp vec4 color; //具有低精度浮點型元素的vec4對象
為每個變量都聲明精度很繁瑣,我們也可以使用關鍵字precision來聲明着色器的默認精度,並且這行代碼必須放在頂點着色器或片元着色器的頂部,格式如下:
precision mediump float;
我們已經發使用精度限定字一般都只在片元着色器中使用,這是因為,除了片元着色器的float類型沒有默認精度,其他類型都有默認精度。如下是數據類型的默認精度:
GLSL ES支持預處理指令。預處理指令用來在真正編譯之前對代碼進行預處理。都已#號開始。下面就是預定義float類型精度的預處理指令:
#ifdef GL_ES precision mediump float; #endif
下面是我們在GLSL ES中可能用到的三種預處理指令。
#if 條件表達式 If 如果條件比倒是為真,執行這里 #endif #ifdef 謀宏 如果定義了某宏,執行這里 #endif #ifndef 某宏 如果沒有定義某宏,執行這里 #endif
可以使用一下指定進行宏定義:
#define 宏名 宏內容
可以使用undef 宏名,結束宏定義。例如:
#define NUM 100 #ifNUM == 100 如果宏NUM為100,執行這里 #else 否則,執行這里 #endif
預定義的內置宏有:
宏/描述
GL_ES/在OpenGL ES2.0中定義為1
GL_FRAGEMENT_PRECISION_HIGH/片元着色器支持highp精度