可能看到這很多人就會認爲跑偏了,我們明明是來學AR/VR的爲啥要搞 GLSL ?這是神馬鬼?
其實在圖形學中,我們要學的東西很多,就比如說一些專業術語,還有線性代數。。。
所以今天就帶大家先來認識一下這些專業術語以及基本的OpenGL着色語言(GLSL也叫着色語言)。
1. GLSL是什麼(GLSL詳細簡介)?
GLSL是一門專門爲圖形開發設計的編程語言。
2.名詞解釋
圖元 :是圖形軟件包中用來描述各種圖形元素的函數,簡單來說,圖元就是組成圖像的基本單元。
渲染管線 :渲染管線也稱爲渲染流水線,是顯示芯片內部處理圖形信號相互獨立的並行 處理單元。
簡單的來說:就是一系列有序的處理 階段的序列,用於把我們應用中的數據轉化到OpenGL生成一個最終的圖像的一個過程。
------------------------------------------------------------------------------------------------------------
渲染流程 :
流程:OpenGL首先接收用戶提供的幾何數據,並且將他輸入的數據經過一系列着色階
段中進行處理,包括頂點着色 ,細分着色,以及幾何着色器,然後被送入光柵化單元,光柵化負責剪切區域內的圖元並生成片元數據,然後對每一個片元都執行一個片元着色器,然後產生我們最終想要的效果。
在OpenGL中,我們可以使用四種shader階段。
**頂點着色器(必要) :**接收頂點緩存對象的頂點數據,單獨處理每個頂點
**細分着色器(可選) :**接收到來自頂點着色階段的輸出數據,並對收到的數據進一步處理 (用Patch描述一個物體的形狀,在OpenGL線管內部生成新的幾何體)
**幾何着色器(可選):**在管線內部會對所有的圖元進行修改,改變幾何圖元的類型,或者放棄所有的幾何體。如果啓用,那麼輸入可能會來自頂點着色階段完成的幾何圖元,也可能來自細分階段的圖元數據
片段着色器(必要):作色管線最後一部分,用來處理OpenGL 光柵化之後生成的單獨片元,並且這個階段也必須綁定一個着色器。(在這個階段裏面,計算一個偏遠的顏色和深度值,然後傳遞到管線的片元測試和混合的模塊。)
----------------------------------(以下爲了解內容,可以先略過)---------------------------------
那在這些步驟 裏面都做了什麼呢?
那前面我們也講了,OpenGL需要將所有的數據都保存到緩存對象中,這也就相當於在OpenGL的服務端維護一塊內存區域。當緩存初始化完畢後,我們通過調用OpenGL的繪製命令來渲染幾何圖元(例:glDrawArray命令,就是一個常用的繪製命令)
1、那我們把數據傳過來之後OpenGL首先是頂點着色,
頂點着色器(必要):接收頂點緩存對象的頂點數據,單獨處理每個頂點
2、當頂點處理完後,會激活細分着色器,
細分着色器(可選):接收到來自頂點着色階段的輸出數據,並對收到的數據進一步處理
(用Patch描述一個物體的形狀,在OpenGL線管內部生成新的幾何體,並且模型的外觀也會變得更加平順,細分作色器會用到兩個階段來分別管理patch數據,並生成最終狀態)
3、幾何着色器(可選):在管線內部會對所有的圖元進行修改,改變幾何圖元的類型,或者放棄所有的幾何體。如果啓用,那麼輸入可能會來自頂點着色階段完成的幾何圖元,也可能來自細分階段的圖元數據
4、那以上的階段都是頂點數據的處理,頂點着色決定了一個圖元應該位於屏幕的什麼位置,那接下來我們會用片元着色決定片元的顏色。
接下來這些頂點數據和頂點之間如何讓構成幾何圖元的所有信息會被傳入到OpenGL當中。然後將這些頂點與相關的幾何圖元之間組織起來,準備光柵化(圖元裝配)
5、在光柵化之前,有些頂點會落在視口之外,那此時與頂點相關的圖元會做出改動,來保證相關像素不會在視口之外繪製。(這就是剪切)(視口:我們進行繪製的窗口區域),
6、剪切完之後馬上就會進入光柵化,
光柵化:將更新後的圖元傳遞到光柵化單元,生成對應的片元。
7、然後接下來就是片元操作
在這個階段裏面,會計算每一個片元的顏色和深度值,然後傳遞到管線的片元測試和混合的模塊(混合我們的效果),
接下來就是最後的獨立片元處理過程
這個階段裏面會使用深度測試和模版測試的方式來決定一個片元是否可見。
如果一個片元通過了所有激活測試,那他就會保存到幀緩存裏面,它的對應的的像素的顏色值會被更新。如果開啓了融合模式,那麼片元的顏色會與該像素當前顏色相疊加形成新的顏色值並寫入幀緩存中!
片段着色器(必要):作色管線最後一部分,用來處理OpenGL 光柵化之後生成的單獨片元,並且這個階段也必須綁定一個着色器。(在這個階段裏面,計算一個偏遠的顏色和深度值,然後傳遞到管線的片元測試和混合的模塊。)
----------------------------------(以上爲了解內容,可以先略過)---------------------------------
說了這麼多 大家先來看一下着色器長什麼樣子吧!
這裏面有好多大家不認識的 類型修飾符 和 數據類型 那這裏我們來看一下這裏面都用到了那些數據類型 那些類型修飾符 以及簡單的語法。
像 uniform 、attribute、varying這些叫類型修飾符!
像 mat4 、vec3 、vec2、這些是數據類型!
像 void positionShift(){ } 、void main(){} 這些是方法!
gl_Position 是內置變量(GLSL中有很多內置變量和內置方法) !
基本語法
(1)註釋:支持單行註釋符 “//” 和 多行註釋符 "/……/ "
(2)main函數沒有返回值
(3)每行結尾都必須有一個分號
(4)變量名、方法名、不允許用 gl 或者 gl_ 開頭。
=( GLSL 基礎部分 )===
一、數據類型
總體來說,GLSL數據類型可以分爲標量、向量、矩陣、採樣器以及數組等幾類。 在學習之前,我們要先認識一下這些名詞 :
標量 :標量 也被稱爲 “ 無向量 ” 其值只有大小,並不具有方向。
OpenGL ES着色語言支持的標量類型有布爾型(bool)、整形(int)和浮點型(float)。
向量 :OpenGL ES着色語言中,向量可以看做是用同樣類型的標量組成
其基本類型也分爲bool、int和float三種。 每個向量可以由2個、3個、4個相同的標量組成。
聚合類型 :是指 矩陣 和 向量。
採樣器 :專門用來進行紋理採樣的相關操作(後面詳細講)。
數組:有限個類型相同的變量的集合就是數組。
結構體:是由一系列具有相同類型或不同類型的數據構成的數據集合,也叫做結構。
1、數據類型—— 標量
類型 | 描述 |
---|---|
float | IEEE 32位浮點值 |
int | 有符號二進制補碼的32位整數 |
bool | 布爾值 |
Android上OpenGL ES2.0中基本數據類型:
浮點型(float)、布爾型(bool)、整型(int)、矩陣型(matrix)以及向量型(vec2、vec3等)等。
2、聚合類型——向量
向量在着色器代碼的開發中的作用 : 可以很方便的存儲以及操作顏色、位置、紋理座標等。
| 基本類型| 2D向量| 3D向量|4D向量 |
| - | :-: | -: |
| float | vec2 (包含了2個32位浮點數的向量)值 | vec3 | vec4|
| double
(集成的顯卡好像不行,只能獨立卡)
| dvce2(包含了2個64位浮點數的向量) | dvce3 | dvce4 |
| int | ivec2 (包含了2個整數的向量)值 | ivec3 | ivec4 |
| uint | uvec2 (包含了2個無符號整數的向量) | uvec3 | uvec4 |
| bool | bvec2 (包含了2個布爾數的向量) | bvec3 | bvec4 |
//向量的使用 :
// 1、使用這些類型聲明的變量的初始化過程 與 標量部分是類似的
//例如:(聲明一個包含了3個32位浮點數的向量)
vec3 velocity=vec3( 0.0,2.0,3.0 );
// 2、類型之間也可以進行等價轉換
//例如:(將一個包含了3個32位浮點數的向量 等價轉換爲 一個包含3個整數的向量)
vec3 velocity=vec3( 0.0,2.0,3.0 );
ivec3 steps =ivec3 (velocity);
// 3、向量的構造函數還可以用來截短或者加長一個向量。
//如果我們將一個較長的向量傳遞給一個較短向量的構造函數,那麼
//向量將會被自動取短到對應的長度
例如:
截短:
//將一個包含了4個32位浮點數的向量 截短成 一個包含3個32位浮點數的向量
vec4 color;//RGB A
vec3 RGB=vec3 (color);//現在RGB只有前三個分量了
加長:
//將一個包含了3個32位浮點數的向量加長爲一個包含4個32位浮點數的向量
vec3 white=vec3(1.0); //white=(1.0,1.0,1.0)
vec4 translucent=vec4 (white,0);
3、聚合類型—— 矩陣
有一些基礎的開發人員都知道,3D場景中的移位、旋轉、縮放等變換都是由矩陣的運算來實現的。因此3D場景的開發中會非常多的使用矩陣 。
| 基本類型| 2x2的矩陣| 3x3的矩陣| 4x4的矩陣 |
| - | :-: | -: |
| float | mat2(2x2的浮點數矩陣)| mat3 | mat4 |
| double| dmat2| dmat3| dmat4|
矩陣的使用:
1、矩陣類型需要給出兩個維度的信息
例如:
mat44,其中第一個值表示列數,第二個值表示行數。
2、矩陣的構建方式
矩陣的構建方式和我們的向量類似,並且可以將它初始化爲一個對角矩陣 或者 完全填充的矩陣。對於對角矩陣 ,只需要向構造函數傳遞一個值,矩陣的對角線元素就設置爲這個值,其他元素全部設置爲0;
例如:對於矩陣,OpenGL中矩陣是列主順序的。如果只傳了一個值,則會構造成對角矩陣,其餘的元素爲0。(看下圖)
當然矩陣也可以通過在構造函數中指定每一個元素的值來構建。傳入元素可以是標量和向量的集合,只要給定足夠的數據就行,每一列的設置方式也遵循這樣的原則,也就是說,傳入的數據將首先填充列,然後填充行。
例如:
1、初始化耦合33的矩陣
mat3 M=mat3(1.0,2.0,3.0, 4.0,5.0,6.0, 7.0,8.0,9.0);
-----------------------------------------------------------------------------------------------------------
vec3 column1=vec3(1.0,2.0,3.0);
vec3 column2=vec3(4.0,5.0,6.0);
vec3 column3=vec3(7.0,8.0,9.0);
mat3 M=mat3(column1,column2,column3);
-----------------------------------------------------------------------------------------------------------
vec2 column1=vec2(1.0,2.0);
vec2 column2=vec2(4.0,5.0);
vec2 column3=vec2(7.0,8.0);
mat3 M=mat3(column1,3.0,column2,6.0, column3,9.0);
這些寫法得到的效果都是(看下圖):(GLSL的矩陣 首先填充列,然後填充行)
4、訪問向量和矩陣中的元素
1. 什麼是分量?
分量就是聚合類型中的某一個元素
2.分量名稱三種形式的集合:
分量訪問符 符號描述
(x,y,z,w) 與位置相關的分量
(r,g,b,a) 與顏色相關的分量
(s,t,p,q) 與紋理座標相關的分量注意:
1.他們實現的工作是一樣的。不同的名稱集和只是爲了在使用的時候便於區分不同的操作
2.w 是 齊次座標
分量訪問符的作用 :
例如: 基於顏色的紅色分量來設置一個亮度。
vec3 luminance=color.rrr;
改變向量中分量各自的位置
color =color.abgr;//反轉color的每個分量(RGBA——>ABGR)
3.向量與矩陣中的元素訪問方式
向量與矩陣中的元素是可以單獨訪問和設置的。向量支持兩種類型的元素訪問方式:
1、使用分量的名稱,或者數組訪問的形式。
(1)使用分量的名稱進行訪問
例如:
float red=color.r;
float v_Y=velocity.y;
(2)數組的形式訪問。(通過索引)
例如:
float red=color [0];
float Y=velocity [1];
2、矩陣元素的訪問可以使用數組標記方式,或者從矩陣中直接得到一個標量。
例如:
mat4 m=mat4(2.0);
vec4 zvec=m[2];//獲取矩陣第二列
float yScale= m[1] [1] ;//也可以用m[1].y
注意:
1.唯一限制:在一條語句的一個變量中,只能使用一種類型的訪問符。
正確寫法:vec4 color=otherColor.rgba;
錯誤寫法:vec4 color=otherColor.rgz;// 錯誤原因: ” Z “來自不同的訪問符集和。
2.訪問元素不能超出訪問類型的範圍
錯誤寫法: vec2 pos;
float zPos=pos.z;//錯誤原因:2D向量不存在“z”分量
5、採樣器和結構體
採樣器作用:專門用來進行紋理採樣的相關操作。一般情況下,一個採樣器變量代表一副或者一套紋理貼圖
採樣器類型 | 說明 |
---|---|
sampler2D | 用於訪問二維紋理 |
sampler3D | 用於訪問三位紋理 |
samplerCube | 用於訪問立方貼圖紋理 |
注意:
1、採樣器變量不能再着色器中初始化。
2、一般情況下,採樣器變量都用uniform限定符來修飾,從宿主語言(JAVA語言)接收傳遞進着色器的值。
3、sampler3D並不是在所有的OpenGL ES實現中都支持,因此,使用時必須要首先在着色器代碼中設置,打開相應拓展。
什麼是結構體?
結構體:是由一系列具有相同類型或不同類型的數據構成的數據集合,也叫做結構。
簡單解釋:就是從邏輯上將不同的類型的數據組合到一個數據集合當中
結構體的作用:
結構體和其他類型基礎數據類型一樣,例如int類型,char類型 只不過結構體可以做成我們想要的數據類型。以方便日後的使用。
在實際項目中,結構體是大量存在的。研發人員常使用結構體來封裝一些屬性來組成新的類型。研發人員通常使用結構體創造新的“屬性”,其目的是 簡化運算。
結構體在函數中的作用不是簡便,其最主要的作用就是封裝。(封裝的好處是什麼?)封裝的好處就是可以再次利用。讓使用者不必關心這個是什麼,只要根據定義使用就可以了。
結構體在GLSL裏面的作用:結構體可以簡化多組數據傳入函數的過程
// 使用:
// 怎麼定義一個結構體?
struct info { //聲明一個結構體info
vec3 color; //顏色成員
vec3 position; //位置成員
vec2 velocitCoor; //紋理座標成員
}
// 怎麼調用結構體元素做爲輸入參數呢?
//如果定義了一個結構體,那麼它會自動創建一個新的類型,並且會隱式定義一個構造函數.
// 那我們只需要這樣操作:
Particle p=Particle(10.0,pos,vel);
float lifetime=p .lifetime;
//就可以將各種類型的數據的結構體元素作爲輸入參數。
6、數組
數組這東西很熟悉吧!但是你知道什麼是數組嗎?如果不懂就簡單看一下吧!
1、什麼是數組? 答:有限個類型相同的變量的集合就是數組
2、 GLSL數組特性 和 注意事項:
1.GLSL支持任意類型的數組,包括結構體數組。
2.數組索引從零開始
3.負數形式的數組索引,或者超出範圍的索引值都是不允許的!
4.在GLSL中數組的元素也可以是另一個數組,因此可以處理多維度的數據(GLSL4.3以前不行)
5.數組可以定義爲有大小的,或者沒有大小的。
例如: float coeff[ 3 ];//有三個float元素的數組
float[ 3 ] coeff;//有三個float元素的數組
int indices[ ];//未定義維數,稍後可以重新聲明
6.數組屬於GLSL中的第一等類型。
1.GLSL數組有構造函數,並且可以用作函數的參數和返回類型。
2.可以靜態初始化一個數組的值
例如: //靜態初始化一個數組的值(這裏構造函數)
float coeff [3]=float[3](1.11,52.0,52.1);
7.GLSL有一個隱式的方法可返回元素個數
(也就是我們所說的,得到數組長度)
例如:
for (int i=0;i<coeff.length;++i){
coeff [i] *=2.0;
}
注意:
1.我們的向量和矩陣類型也可以使用 length() 方法。
2.向量的長度是它包含的分量個數。
3.矩陣的長度是它包含的列的個數。
例如:
mat3*4 m;
int c = m.length();//m包含的列數爲3
int r = m[0].length();//第0個向量中分量個數爲4
4.因爲長度值在編譯時就是已知的,所以length()方法會返回一個編譯時常量,
這個常量在需要使用的場合可以直接使用
例如:mat4 m;
Float angle[ m.length];//設置數組大小與矩陣大小相等
8.多維數組
float coeeff[3][5];//一個大小爲3的數組,其中包含大小爲5的多個數組。
coeeff [2][1] *=2.0;//內層索引爲1,外層索引爲2;
coeeff.length();//調用這個方法返回長度爲3
coeeff [2];//這是一個大小爲5的一維數組
coeeff [2].length();//調用這個方法返回長度爲5
7、類型修飾符(存儲限制符)
類型修飾符的作用:
數據類型也可以通過一些修飾符來改變自己的行爲。(關於限制符這裏大家肯定會有很多問題,因爲限制符需要結合實際場景操作,這裏我會多舉一些例子,讓大家能更詳細的瞭解 存儲限制符,同時我也會在項目中大量用到 存儲限制符)
類型修飾符 | 描述 |
---|---|
attribute | 一般用於每個頂點都各不相同的量,如:頂點位置,顏色等 |
uniform | uniform爲一致變量限定符 |
varying | 用於從頂點着色器傳遞到片元的量 |
const | 用const修飾的變量的值是不可變的,也就是我們說的常量,又叫編譯時常量 |
in | 設置這個變量爲着色器階段的輸入變量。 |
out | 設置這個變量爲着色器階段的輸出變量。 |
inout | 用來修飾的參數爲輸出輸入參數,具有輸入輸出兩種參數功能 |
buffer | 設置應用程序共享的一塊可讀寫內存。這塊內存也作爲作色器總的存儲緩存使用。 |
shared | 設置變量是本地工作組中共享的。他只能用於計算着色器中。 |
8、算數操作符
(1)GLSL操作符 與 優先級
(2)操作符重載
GLSL中大部分操作符都是經過重載的,也就是說他們可以用於多種類型的數據操作。特別是,矩陣和向量的算數操作符,在GLSL中都是經過嚴格定義的。
例如:如果我們需要進行向量和矩陣之間的乘法
vec3 v;
mat3 m;
vec3 r=v*m;
基本的限制條件:要求矩陣和向量的維度必須是匹配的!
-
但是這裏有一個例外 簡單說一下
兩個向量相乘得到的時一個逐分量相乘的新向量,
但是兩個矩陣相乘得到的是通常矩陣相乘的結果。
例如:
vec2 a,b,c;
c=a*b; //c=( a.x*b.x ,a.y*b.y )
mat2 m,u,v;
m= u*v; //m=( u00*v00+u01*v10 u00*v01+u01*v11
// u01*v00+u11*v10 u10*v01+u11+v11 );
//----------------------------------------------------------------
(3)控制流
GLSL的邏輯控制方式也是用的if和switch,
if(條件){
}else{
}
=====================
switch(條件){
case:
brake;
case:
brake;
default :
brake;
}
注意:
1.如果沒有使用brake結尾,拿語句會繼續執行case的內容。
(4)循環語句
GLSL的循環語句是for 、while、do{ }while
1.for循環可以在循環初始化條件中聲明循環迭代變量,迭代變量的作用於直線於循環內
for(int i=0;i<10;++i){}
2. while(n<10){….}
3. do{…...}while(n<10)
(5)流控制語句
語句 | 描述 |
---|---|
brake | 終止循環體的運行,並且繼續執行循環體外的內容 |
continue | 種植循環體內當前迭代過程的執行,跳轉到代碼塊開始的部分並繼續執行下一次迭代的內容 |
return | 從當前例程返回,可以帶有一個函數的返回值(返回值必須與函數聲明的返回類型相符合) |
discard | 丟棄當前片元,終止片元着色器執行(只能在片元着色器中使用,運行到該語句位置上時 片元着色器會立即終止) |
(6)函數聲明
函數的作用:我們可以使用函數調用來取代可能反覆執行的通用代碼。
聲明:
returnType functionName([accessmodifier] type,…..){
….
//函數體
return returnValue;//如果returnType爲void ,則不需要return語句;
}
注意:
1.函數聲明,變量名需要添加訪問修飾符
2.GLSL支持用戶自定義函數,同時它定義了一些內置函數
3.函數名稱可以是任何字符、數字、下劃線,但是不能使用數字,
連續下劃線或者gl_作爲函數的開始
4.返回值可以是任何內置的GLSL類型,或者用戶定義的結構體和數組類型。
5.返回值是數組時,必須現實的指定大小。函數返回類型是void則沒有返回值
6.函數的參數也可以是任何類型的函數,包括數組(這裏數組必須設置大小)
7.在使用一個函數前必須聲明他的原型或者直接給出函數體。
8.GLSL的編譯器在使用函數前必須找到函數的聲明,否則會產生錯誤
9.函數原型只是給出了函數的形式,但是並沒有給出具體的實現內容
例如:
float HornerEvalPolynomial(float coeeff[10] ,float x);
9、程序基本結構
一個着色器程序一般3大部分組成:全局變量聲明,自定義函數,main函數。
代碼解釋
【1】前四行爲全局變量聲明
那大家根據前四行代碼判斷一下這是一個什麼着色器?
判斷依據:
1、attribute屬性限定符只能用於頂點着色器中。
2、verying用於從頂點着色器傳遞到片元的量
uniform爲一致變量限定符
(一致變量指的是 對同一組頂點組成的單個3D物體中所有頂點都相同的量。)
1.uniform變量可以用在頂點着色器 或者 片元着色器中。
2.可以修飾所有的基本數據類型
【2】自定義函數部分 void positionShift()
這裏這個gl_Position是頂點着色器的內置變量(後面會介紹)
【3】主函數 void main()
大家要注意一點 :
着色器程序中要求被調用的函數必須再調用之前聲明!!!
【4】拓展知識
gl_Position是vec4類型的?不是應該是vec3嗎,多出來的那個是什麼呀?
在3d圖形用到了 4x4的矩陣(4行4列),
矩陣乘法要求 nxm * mxp(n行m列 乘 m行p列)才能相乘
注意:m是相同的,所以 1x4 * 4x4 才能相乘(nxm * mxp)。
這部分知識我們會在投影變換的時候繼續講
十、內建變量
着色器代碼的開發中會用到很多變量,其中大部分可能是由開發人員根據需求自定義的,但着色器中也提供了一些用來滿足特性需求的內建變量。
特點:
1.內建變量不需要聲明就可以使用。
2.一般用來實現 管線渲染固定功能部分與自定義頂點 或者片元着色器之間的信息交互。
分類:
內建變量根據信息傳遞方向分爲兩類,
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 | 輸出的深度用於隨後的像素操作,如果這個值沒有被寫,則使用固定功能管線的深度值代替|內置函數
與其他高級語言類似,爲了方便開發,OpenGL ES着色語言也提供了很多的內置函數。這些函數大都已經被重載,一般具有4種變體,分別用來接收和返回float、vec2、vec3以及vec4類型的值。
1、內置函數都是以最優的方式實現的,有部分函數甚至由硬件直接支持,大大提高了執行效率!
2、大部分內置函數同時適用於頂點作色器與片元着色器,但也有部分內置函數只適合頂點着色器或者片元着色器的。
內置函數按照設計目的分爲3個類型:
類型 | Academy |
---|---|
提供獨特硬件功能訪問的接口 | 像紋理採樣系列的函數,這些函數用戶是無法自己開發的。着色語言去年通過提供特定內置函數對這些硬件功能進行封裝我們要使用就直接調用就成 |
簡單的數學函數 | 像:abs (求摸)、foolr(取整)等。 (自己可以寫,但是如果對底層不瞭解,實現方式機會效率低) |
一些複雜的函數 | 像:三角函數等 高等數學知識的函數 |
GLSL基礎我們暫時就講這些(寫的有點多),如果有什麼疑問或者問題的可以加我的微信 ↓