OpenGL之GLSL

GLSL是OpenGL Shader的編程語言,爲了更好的進行視頻編輯和特效開發,抽空學習了其語法和特性,並作此記錄,留做備忘查詢。編程

類型

類型概述

變量類別 變量類型 備註
void 用於標識無參函數或者無返回值函數:void main(void);
標量 bool/int/float 布爾類型、整型、浮點型
布爾型向量 bvec2/bvec3/bvec4 其中b表示向量類型,數字表示向量的份量數
整型向量 ivec2/ivec3/ivec4 其中i表示向量類型,數字表示向量的份量數
浮點型向量 vec2/vec3/vec4 默認狀況下是float類型,數字表示向量的份量數
浮點型矩陣 mat2/mat3/mat4 數字表示矩陣的列數,行數和列數相同
2D texture sampler2D 2D紋理,僅能做爲uniform變量
Cubemap(立方體) texture samplerCube 立方體紋理,僅能做爲uniform變量
結構體 struct 相似於C語言結構體,把多個變量聚合在一塊兒
數組 array GLSL只支持1維數組,數據類型能夠是標量類型、向量類型、矩陣類型、結構體類型

向量構造器有兩種參數構造方式:數組

  1. 單標量參數:向量中的全部份量都會初始化爲該標量值。
  2. 多標量參數、向量參數、或者標量和向量混合參數:按照參數順序初始化向量的全部份量,須要保證參數個數(向量參數的份量拆分開)很多於向量份量個數。
vec4 aVec4 = vec4(1.0, 1.0, 1.0, 1.0);
// 所有份量都爲1.0
vec4 bVec4 = vec4(1.0);

vec3 aVec3 = vec3(1.0);
// 經過向量和標量初始化4維向量
vec4 cVec4 = vec4(aVec3, 1.0);
複製代碼

類型轉換:GLSL不支持隱式類型轉換,必須進行顯示類型轉換,向量也支持直接類型轉換。即只有類型一致時,變量才能完成賦值或其它操做。less

float floatParam = 1.0;
// float -> bool
bool boolParam = bool(floatParam);

vec4 fVec4 = vec4(1.0, 1.0, 1.0, 1.0);
// 4維float向量 -> 4維int向量
ivec4 iVec4 = ivec4(fVec4);
// 4維float向量 -> 3維int向量
ivec3 iVec3 = ivec3(fVec4);
複製代碼

矩陣構造器也有兩種參數構造方式:編程語言

  1. 單標量參數:用於主對角線上份量的初始化,其餘份量皆爲0.0。
  2. 多標量參數、向量參數、或者標量和向量混合參數:按照參數順序初始化矩陣的全部份量(列優先),須要保證參數個數(向量參數的份量拆分開)很多於矩陣份量個數。
// 經過多個標量爲矩陣的各個份量賦值
mat3 aMat3 = mat3(1.0, 0.0, 0.0,  // 第一列
                  0.0, 1.0, 0.0,  // 第二列
                  0.0, 0.0, 1.0); // 第三列
// 單個標量用於主對角線上份量的初始化,其餘份量皆爲0.0 
mat3 bMat3 = mat3(1.0);

vec3 aVec3 = vec3(1.0,0.0,0.0);
vec3 bVec3 = vec3(0.0,1.0,0.0);
mat3 cMat3 = mat3(aVec3,  // 經過向量初始化第一列
                  bVec3,  // 經過向量初始化第二列
                  0.0, 0.0, 1.0); // 經過多個標量初始化第三列
複製代碼

向量和矩陣操做

向量和矩陣都是由份量構成的,咱們能夠經過多種方式訪問份量。 針對向量,能夠經過.和數組下標訪問,也能夠經過xyzwrgba或者strq來訪問,其中,xyzw一般用於位置相關向量,rgba一般用於顏色相關向量,strq一般用於紋理座標相關向量。xrs分別表示向量的第一個份量。上述三種方式不能混用,好比:xgr是不容許的。ide

針對矩陣,能夠認爲是向量的組合,一個mat3能夠當作三個vec3,因此能夠經過數組下標獲取某一列的向量,而後再經過上述方法訪問向量份量。函數

// 向量訪問
vec3 aVec3 = vec3(0.0, 1.0, 2.0); 
vec3 temp;
temp = aVec3.xyz; // temp = {0.0, 1.0, 2.0}
temp = aVec3.xxx; // temp = {0.0, 0.0, 0.0}
temp = aVec3.zyx; // temp = {2.0, 1.0, 0.0}

// 矩陣訪問
mat4 aMat4 = mat4(1.0); 
vec4 column0 = aMat4[0];	        // column0 = {1.0, 0.0, 0.0,0.0}
float column1_row1 = aMat4[1][1];   // column1_row1 = 1.0
float column2_row2 = myMat4[2].z;   // column2_row2 = 1.0
複製代碼

結構體

與C語言相似,glsl支持定義結構體,同時會自動爲結構體建立構造器(與結構體同名),用於生成結構體實例。學習

// Leon是新的結構體類型,leon是結構體變量,是可選的。
struct Leon {
    vec4 aVec4; 
    mat4 bMat4;
    float cF;
} leon;
// 經過結構體構造器初始化結構體參數,構造器的參數和結構體的元素必須有精確的對應關係 
leon = Leon(vec4(1.0),mat4(1.0),1.0); 
// 經過.操做符訪問成員變量
vec4 dVec4 = leon.aVec4;
mat4 eMat4 = leon.bMat4;
複製代碼

數組

與C語言相似,glsl支持定義數組,數組類型能夠是任意基本類型和結構體類型。glsl有兩點特殊之處:測試

  1. 除了uniform變量以外,數組的索引必須是編譯期常量。
  2. 數組的定義和初始化是分開的,即數組中的元素必須在數組定義以後逐個初始化,且數組不能使用const限定符。
// 定義數組
float fArray[2];
vec2 vec2Array[2];
mat2 mat2Array[2];
Leon leonArray[2];

// 數組元素必須逐一被初始化 
fArray[0] = 0.0;
fArray[1] = 1.0;
    
vec2Array[0] = vec2(0.0);
vec2Array[1] = vec2(1.0);
    
mat2Array[0] = mat2(0.0);
mat2Array[1] = mat2(1.0);
    
leonArray[0] = Leon(vec4(1.0),mat4(1.0),1.0);
leonArray[1] = Leon(vec4(1.0),mat4(1.0),1.0);
複製代碼

語句

流程控制語句

流程控制語句與C語言很是類似。ui

循環語句

GLSL支持經過continue跳過單次循環,break退出整個循環。spa

// 經過計數器控制的循環
for(int i = 0; i <= 99; i++) {
    function(); 
}

// 經過前置(循環)條件控制的循環
int i = 0;
while(i <= 99) { 
    function();
    i++;
}

// 經過後置(循環)條件控制的循環
do { 
    function();  
    i++;
} while(i <= 99);
複製代碼

條件語句

與C語言相似

if(condition){
    functionA();
} else {
    functionB();
}
複製代碼

discard語句

discard關鍵字通常用於片元着色器中,用於丟棄當前片元,即:當即退出當前片元的着色程序,當前片元最終是默認色。

Start語句

// main函數是頂點和片元着色器入口,至關於C語言的主函數
void main(void) {
    function();  
}
複製代碼

運算符

GLSL運算符與C語言相似,此處再也不贅述,只說不一樣點:

  • GLSL要求運算符兩側的變量必須具備相同的數據類型。
  • 對於二目運算符(*,/,+,-),操做數必須爲浮點型或者整型。
  • 比較運算符只能用於標量,有專門的內置函數用於向量比較,後續內置函數會介紹。

限定符

存儲限定符

聲明變量時,可使用存儲限定符進行修飾,相似C語言中的說明符。

const

const用於修飾編譯時常量(聲明時必須賦初值),或者只讀的函數參數。結構體成員不能被聲明爲常量,可是結構體變量能夠被聲明爲常量,而且須要在初始化時使用構造器初始化其值。

attribute

attribute變量是應用程序傳輸給頂點着色器的逐頂點數據,即每一個頂點都須要一份數據,一般用於表示頂點座標、頂點顏色、紋理座標等數據。attribute變量在shader中是隻讀的,不能在頂點着色器中進行修改。此外,attribute變量必須由執行着色器的應用程序傳輸數據進行賦值。

可以使用的最大attribute數量是有上限的,可使用內置函數glGetIntegerv來查詢GL_MAX_VERTEX_ATTRIBS。OpenGL ES 2.0至少支持8個attribute變量。

uniform

uniform可用在頂點和片元着色器中,用於修飾全局變量,即它們不限於某個頂點或者某個像素。一般用於表示變換矩陣、紋理等數據。uniform變量在shader中是隻讀的,不能在着色器中進行修改。此外,uniform變量必須由執行着色器的應用程序傳輸數據進行賦值。

着色器可使用的uniform個數是有限的,可使用內置函數glGetIntegerv來查詢GL_MAX_VERTEX_UNIFORM_VECTORSGL_MAX_FRAGMENT_UNIFORM_VECTORS。OpenGL ES 2.0至少支持128個頂點uniform以及16個片元uniform。

varying

varying用於聲明頂點着色器和片元着色器之間共享的變量。在頂點和片元着色器中,必須有相同的varying變量聲明。首先,頂點着色器爲每一個頂點的varying變量賦值,而後光柵化階段會對varying變量進行插值計算(光柵化後的每一個片元都會獲得一個對應的varying變量值),最後把插值結果交給片元着色器進行着色。varying只能用於修飾浮點標量、浮點向量、浮點矩陣以及包含這些類型的數組。

varying數量也存在限制,可使用glGetIntegerv來查詢GL_MAX_VARYING_VECTORS。OpenGL ES 2.0至少支持8個varying變量。

本地變量和函數參數只能使用const限定符,函數返回值和結構體成員不能使用限定符。 attributeuniform變量不能在初始化時賦值,這些變量必須由應用程序主動進行賦值。

參數限定符

GLSL提供了參數限定符用於修飾函數參數,表示參數是否可讀寫。

in(只讀參數)

in是默認修飾符,表示參數是值傳遞,而且在函數內不能修改該值。

out(只寫參數)

out表示參數是引用傳遞,可是參數沒有被初始化,因此在函數內不可讀,只可寫,而且函數結束後,修改依然生效。

inout(可讀寫參數)

inout表示參數是引用傳遞,在函數內能夠對參數進行讀寫。而且函數結束後,修改依然生效(相似於C++中的引用)。

int newFunction(in bvec4 aBvec4,   // read-only 
                out vec3 aVec3,    // write-only
                inout int aInt);   // read-write

複製代碼

精度限定符

精度限定符明確指定了着色器變量使用的精度範圍,包括:lowpmediumphighp三種精度。當使用低精度時,OpenGL ES能夠更快速和低功耗地運行着色器,效率的提升得益於精度的捨棄,若是精度選擇不合理,着色器運行的結果會出現失真。因此須要測試不一樣的精度才能肯定最合適的配置。

精度限定符 描述
highp 最高精度
lowp 最低精度
mediump 中間精度,介於二者之間

精度限定符能夠修飾整型或者浮點型標量、向量和矩陣。在頂點着色器中,精度限定符是可選的,假如沒有指定限定符,那麼默認使用最高精度。在片元着色器中,精度限定符是必須的,要麼在定義變量時直接指定精度,要麼指定類型的默認精度。

// 爲類型指定精度,若定義float變量時,沒有指定精度限定符,那麼默認是highp精度
precision highp float;
precision mediump int;

// 爲變量指定精度
highp vec4 position;
varying lowp vec4 color;
複製代碼

在OpenGL ES中,精度的定義及範圍取決於具體的實現,不是徹底一致。精度限定符指定了存儲這些變量時,必須知足的最小範圍和精度。具體實現可能會使用比要求更大的範圍和精度,但絕對不會比要求少。

不一樣着色器支持的不一樣精度限定符的範圍與精度可使下面的函數查詢:

void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision);
複製代碼

其中,shadertype必須是VERTEX_SHADERFRAGMENT_SHADER;precisiontype必須是GL_LOW_FLOATGL_MEDIUM_FLOATGL_HIGH_FLOATGL_LOW_INTGL_MEDIUM_INTGL_HIGH_INT;range是指向長度爲2的整數數組的指針,這兩個整數表示數值範圍:

range[0] = log2(|min|)
range[1] = log2(|max|)
複製代碼

precision是指向整數的指針,該整數是對應的精度位數(用log2取對數值)。

當表達式中出現多種精度時,選擇精度最高的那個;當一個精度都沒找到時,則使用默認或最大精度。

限定符的順序

當出現多種限定度時,須要遵循必定的順序:

  • 通常變量:存儲限定符 -> 精度限定符
  • 函數參數:存儲限定符 -> 參數限定符 -> 精度限定符
// 變量
varying highp float color; // storage -> precision
void fun(const in lowp float size){ // storage -> parameter -> precision
}
複製代碼

預處理

GLSL中的預處理指令與C語言相似,都是以#開頭,每一個指令獨佔一行。常見的預處理指令以下所示:

// 定義和取消定義
#define
#undef
// 條件判斷
#if
#ifdef
#ifndef
#else
#elif
#endif

#pragma
#extension
#version
#line
複製代碼

#pragma表示編譯指示,用來控制編譯器行爲。

#pragma debug(on)
#pragma debug(off)
複製代碼

開發和調試時能夠打開debug選項,以便獲取更多的調試信息,默認爲off。

#version指定使用哪一個GLSL版本編譯着色器,必須寫在編譯單元的最前面,其前面只能有註釋或空白,不能有其餘字符。

#extension用來啓用某些擴展功能,每一個顯卡驅動廠商均可以定義本身的OpenGL擴展,如:GL_OES_EGL_image_external。啓用擴展的命令以下所示:

// 爲某個擴展設置行爲
#extension extension_name: behavior
// 爲全部擴展設置行爲
#extension all : behavior
// 啓用OES紋理
#extension GL_OES_EGL_image_external : require
複製代碼

extension_name表示具體某個擴展,all表示編譯器支持的全部擴展,behavior表示對擴展的具體操做,好比啓用、禁用等,以下所示:

behavior 描述
require 啓用某擴展,若是不支持,則報錯,若是擴展參數爲all,則必定會出錯
enable 啓用某擴展,若是不支持,則會警告,若是擴展參數爲all,則必定會出錯
warn 除非由於該擴展被其它處於啓用狀態的擴展所須要,不然使用該擴展時會發出警告,若是擴展參數爲all,則必定會拋出警告
disable 禁用某擴展,若是使用該擴展則會拋出錯誤,若是擴展參數爲all(默認設置),則不容許使用任何擴展

對於每個被支持的擴展,都有一個對應的宏定義,咱們能夠用它來判斷編譯器是否支持該擴展。

#ifdef OES_extension_name
#extension OES_extension_name : enable
    
#else
    
#endif
複製代碼

除此以外,還有一些預約義的系統變量:

__LINE__ 	// int類型,當前源碼中的行號.
__FILE__ 	// int類型,當前Source String的惟一ID標識
__VERSION__ // int類型,當前的glsl版本,好比100(100 = v1.00)
GL_ES 		// 若是當前是在OpenGL ES環境,爲1,不然爲0
複製代碼

內置變量

OpenGL着色語言包含一些內置變量,這裏主要介紹頂點和片元着色器的內置變量。

頂點着色器內置變量

gl_Position

gl_Position是輸出變量,用來保存頂點位置的齊次座標。該值用做圖元裝配、裁剪以及其餘固定管道操做。若是頂點着色器中沒有對gl_Position賦值,那麼在後續階段它的值是不肯定的。gl_Position能夠被寫入屢次,後續步驟以最後一次寫入值爲準。

gl_PointSize

gl_PointSize是輸出變量,是着色器用來控制被柵格化點的大小,以像素爲單位。若是頂點着色器中沒有對gl_PointSize賦值,那麼在後續階段它的值是不肯定的。

片元着色器內置變量

gl_FragColor

gl_FragColor是輸出變量,定義了後續管線中片元的顏色值。gl_FragColor能夠被寫入屢次,後續步驟以最後一次寫入值爲準。若是執行了discard操做,則片元會被丟棄,gl_FragColor將再也不有意義。

gl_FragCoord

gl_FragCoord是隻讀變量,保存當前片元的窗口座標(x, y, z, 1/w),該值是圖元裝配階段對圖元插值計算所得,z份量表示當前片元的深度值。

gl_FragDepth

gl_FragDepth是輸出變量,用於改變片元的深度值(替代gl_FragCoord.z深度值)。若是在任何地方寫入了它的值,那麼務必在全部執行路徑中都寫入它的值,不然未寫入的路徑上它的值有可能不明確。

gl_FrontFacing

gl_FrontFacing是隻讀變量,若是片元屬於面朝前的圖元,那麼它的值爲true。該變量能夠選取頂點着色器計算出的兩個顏色之一以模擬雙面光照。

gl_PointCoord

gl_PointCoord是隻讀變量,表示當前片元在點圖元中的二維座標,範圍是0.0到1.0。若是當前圖元不是點,那麼gl_PointCoord讀取的值將是不明確的。

函數

自定義函數

GLSL支持自定義函數,可是函數不能嵌套,不支持遞歸調用,必須聲明函數返回值類型(無返回值時聲明爲void)。若是一個函數在定義前被調用,則須要先聲明其函數原型。

vec4 getPosition(){ 
    vec4 v4 = vec4(0.,0.,0.,1.);
    return v4;
}
複製代碼

內嵌函數

三角形函數

ParamType能夠是floatvec2vec3vec4,參數類型和返回類型是一致的。

函數原型 描述
ParamType radians(ParamType degrees) 把角度轉換爲弧度
ParamType degrees(ParamType radians) 把弧度轉換爲角度
ParamType sin(ParamType radians) 以弧度爲單位,計算正弦值
ParamType cos(ParamType radians) 以弧度爲單位,計算餘弦值
ParamType tan(ParamType radians) 以弧度爲單位,計算正切值
ParamType asin(ParamType value) sin的反函數,計算給定值的弧度,value的絕對值 <= 1,返回的弧度範圍是[-π/2,π/2]
ParamType acos(ParamType value) cos的反函數,計算給定值的弧度,value的絕對值 <= 1,返回的弧度範圍是[0,π]
ParamType atan(ParamType y_over_x) tan的反函數,計算給定值的弧度,返回的弧度範圍是[-π/2,π/2]
ParamType atan(ParamType y, ParamType x) tan的反函數,也能夠稱做atan2,返回一個正切值爲y/x的弧度,x和y的符號用來肯定角在哪一個象限。返回的弧度範圍是(−π,π)。若是x和y都爲0,則結果是未定義的

指數函數

ParamType能夠是floatvec2vec3vec4,參數類型和返回類型是一致的。

函數原型 描述
ParamType pow(ParamType x, ParamType y) 冪函數返回x的y次方
ParamType exp(ParamType x) exp函數返回常數e的x次方
ParamType exp2(ParamType x) exp2函數返回常數2的x次方
ParamType log(ParamType x) 以常數e爲底x的對數函數
ParamType log2(ParamType x) 以常數2爲底x的對數函數
ParamType sqrt(ParamType x) 返回X的平方根
ParamType inversesqrt(ParamType x) 返回x的平方根的倒數

通用函數

ParamType能夠是floatvec2vec3vec4,參數類型和返回類型是一致的。

函數原型 描述
ParamType abs(ParamType x) 返回x的絕對值
ParamType sign(ParamType x) x爲正時返回1.0,x爲零時返回0.0,x爲負時返回-1.0
ParamType floor(ParamType x) 返回小於或等於x的最大整數
ParamType ceil(ParamType x) 返回大於或等於x的最小值
ParamType fract(ParamType x) 返回x的小數部分,即: x - floor(x)。
ParamType mod(ParamType x, ParamType y) x – y * floor(x / y),若是x和y是整數,返回值是x除以y的餘數
ParamType mod(ParamType x, float y) 上面mod的變體:y老是float,對於浮點向量,向量的每一個份量除以y
ParamType min(ParamType x, ParamType y) 返回兩個參數的較小值。對於浮點向量,操做是按份量進行比較的
ParamType min(ParamType x, float y) 上面min的變體:y老是float,對於浮點向量,向量的每一個份量與y進行比較
ParamType max(ParamType x, ParamType y) 返回兩個參數的較大值。對於浮點向量,操做是按份量進行比較的
ParamType max(ParamType x, float y) 上面max的變體:y老是float,對於浮點向量,向量的每一個份量與y進行比較
ParamType clamp(ParamType x, ParamType minVal, ParamType maxVal) 若是x大於minVal,小於maxVal,則返回x。若是x小於minVal,則返回minVal。若是x大於maxVal,則返回maxVal
ParamType clamp(ParamType x, float minVal, float maxVal) 上面clamp的變體,minVal和maxVal老是float,對於浮點向量,向量的每一個份量與minVal和maxVal進行比較
ParamType mix(ParamType x, ParamType y, ParamType a) 返回x和y的線性混合,即x * (1 - a) + y * a
ParamType mix(ParamType x, ParamType y, float a) 上面mix的變體,a老是float,對於浮點向量,向量的每一個份量與a計算
ParamType step(ParamType edge, ParamType x) 若是x比edge小,則返回0.0,不然返回1.0
ParamType step(float edge, ParamType x) 上面step的變體,edge老是float,對於浮點向量,向量的每一個份量與edge計算
ParamType smoothstep(ParamType edge0, ParamType edge1, ParamType x) 若是x小於edge0,則返回0.0;若是x大於edge1,則返回1.0。不然,返回值將使用Hermite多項式在0.0到1.0之間進行插值
ParamType smoothstep(float edge0, float edge1, ParamType x) 上面smoothstep的變體,edge0和edge1老是float,對於浮點向量,向量的每一個份量與edge0和edge1比較

幾何函數

ParamType能夠是floatvec2vec3vec4

函數原型 描述
float length(ParamType x) 返回向量長度,即各份量平方和的平方根,對於浮點標量則返回其絕對值
float distance(ParamType p0, ParamType p1) 返回兩點之間的距離,兩點的距離就是向量d(p0 - p1, 從p1開始,指向p0)的長度,對於浮點標量則返回其絕對值
float distance(ParamType p0, ParamType p1) 返回兩點之間的距離,兩點的距離就是向量d(p0 - p1, 從p1開始,指向p0)的長度,對於浮點標量則返回其絕對值
float dot(ParamType x, ParamType y) 返回兩個向量的點積,即兩個向量各個份量乘積的和,對於浮點標量則返回x和y的乘積
vec3 cross(vec3 x, vec3 y) 返回兩個向量的叉乘向量,更爲熟知的叫法是法向量,該向量垂直於x和y向量構成的平面,其長度等於x和y構成的平行四邊形的面積。輸入參數只能是三份量浮點向量
ParamType normalize(ParamType x) 返回向量x的單位向量,即x / \|x\|,對於浮點標量直接返回1.0
ParamType faceforward(ParamType N, ParamType I, ParamType Nref) 若是dot(Nref, I) < 0那麼返回N向量,不然返回–N向量
ParamType reflect(ParamType I, ParamType N) I:the incident vector(入射向量), N:the normal vector of the reflecting surface(反射面的法向量),返回反射方向: I – 2 * dot(N,I) * N,N通常是單位向量
ParamType refract(ParamType I, ParamType N, float eta) I:the incident vector(入射向量), N:the normal vector of the refracting surface(折射面法向量),eta:折射率。返回入射向量I關於法向量N的折射向量,折射率爲eta,I和N通常是單位向量

矩陣函數

不一樣於傳統的向量相乘,這裏matrixCompMult返回一個向量,該向量的各份量等於x和y向量各個份量的乘積。

mat2 matrixCompMult(mat2 x, mat2 y)  
mat3 matrixCompMult(mat3 x, mat3 y)  
mat4 matrixCompMult(mat4 x, mat4 y)

// 結果向量z
z[i][j] = x[i][j] * y[i][j]
複製代碼

矢量(向量)關係函數

矢量(向量)關係函數主要包含:<, <=, >, >=, ==, !=),函數參數是整型或者浮點型向量,函數返回值是參數向量各個份量比較產生的一個布爾型向量。 下面用bvec表示bvec二、bvec三、bvec4;ivec表示ivec二、ivec三、ivec4;vec表示 vec二、vec三、vec4。參數向量和返回值向量的大小必須一致。

函數原型 描述
bvec lessThan(vec x, vec y)
bvec lessThan(ivec x, ivec y)
結果向量result[i] = x[i] < y[i]
bvec lessThanEqual(vec x, vec y)
bvec lessThanEqual(ivec x, ivec y)
結果向量result[i] = x[i] <= y[i]
bvec greaterThan(vec x, vec y)
bvec greaterThan(ivec x, ivec y)
結果向量result[i] = x[i] > y[i]
bvec greaterThanEqual(vec x, vec y)
bvec greaterThanEqual(ivec x, ivec y)
結果向量result[i] = x[i] >= y[i]
bvec equal(vec x, vec y)
bvec equal(ivec x, ivec y)
結果向量result[i] = x[i] == y[i]
bvec notEqual(vec x, vec y)
bvec notEqual(ivec x, ivec y)
結果向量result[i] = x[i] != y[i]
bool any(bvec x) 假如參數向量的任意一個份量爲true,那麼返回true
bool all(bvec x) 假如參數向量的全部份量爲true,那麼返回true
bvec not(bvec x) 對布爾向量取反

紋理查找函數

紋理查詢的目的是從紋理中提取指定座標的顏色信息。OpenGL中紋理有兩種:

  • 2D紋理(sampler2D)
  • 3D紋理(samplerCube)

頂點着色器和片元着色器中均可以使用紋理查找函數。可是頂點着色器中不會計算細節級別(level of detail),因此兩者的紋理查找函數略有不一樣。

如下函數只在頂點着色器中可用:

vec4 texture2DLod(sampler2D sampler, vec2 coord, float lod);
vec4 texture2DProjLod(sampler2D sampler, vec3 coord, float lod);
vec4 texture2DProjLod(sampler2D sampler, vec4 coord, float lod);
vec4 textureCubeLod(samplerCube sampler, vec3 coord, float lod);
複製代碼

如下函數只在片元着色器中可用:

vec4 texture2D(sampler2D sampler, vec2 coord, float bias);
vec4 texture2DProj(sampler2D sampler, vec3 coord, float bias);
vec4 texture2DProj(sampler2D sampler, vec4 coord, float bias);
vec4 textureCube(samplerCube sampler, vec3 coord, float bias);
複製代碼

float類型參數bias表示:使用mipmaps計算紋理的適當細節級別以後,在執行實際的紋理查找操做以前添加的誤差。

如下函數在頂點着色器和片元着色器中均可用:

vec4 texture2D(sampler2D sampler, vec2 coord);
vec4 texture2DProj(sampler2D sampler, vec3 coord);
vec4 texture2DProj(sampler2D sampler, vec4 coord);
vec4 textureCube(samplerCube sampler, vec3 coord);
複製代碼
相關文章
相關標籤/搜索