1. 程式人生 > >OpenGL 著色器語言基礎

OpenGL 著色器語言基礎

資料型別概述:

  • 標量 :也被稱為“無向量”其值只有大小,並不具有方向。
  • 向量:有方向的量叫做向量。OpenGLES著色語言中,向量可以看做是用同樣型別的標量組成,其基本型別也分為bool、int和float三種。 每個 向量可以由2個、3個、4個相同的標量組成。

    1.其基本型別也分為bool、int和float三種。 每個向量可以由2個、3個、4個相同的標量組成 
    2.向量在著色器中的作用可以很方便的儲存以及操作顏色、位置、紋理座標等不僅包含一個組成部分的量。
     開發中,有時可能需要單獨訪問向量中的某個分量,基本的語法為 “<向量名>.<分量名>”。
    

    這裡寫圖片描述

  • 矩陣:
    1.矩陣在3D開發中的作用:做位移變換
    2.矩陣型別

    3.矩陣初始化
    mat4*4 是什麼意思:第一個值表示列,第二個表示行
    初始化矩陣
    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 );
    mat3 m=mat3(column1,column2 ,column3);
    vec2 column1=vec2(1.0 , 2.0 );
    vec2 column3=vec2( 7.0 ,8.0 );
    mat3 m=mat3(column1 ,3.0 ,column2 ,6.0 ,column3 ,9.0);
  • 取樣器
    取樣器是著色語言中不同於C語言的一種特殊的基本資料型別,其專門用來進行紋理取樣的相關操作。一般情況下,一個取樣器變數代表一幅或一套紋理貼圖
    這裡寫圖片描述
  • 結構體
    OpenGL ES著色語言還提供了類似C語言中的使用者自定義結構體,同樣也是使用struct關鍵字進行宣告。

    struct info{ //宣告一個結構體 info
    vec3 color; //顏色成員
    vec3 position; //位置成員
    vec2 texturecoor; //紋理座標成員
    }

  • 陣列:宣告陣列的方式主要有兩種:

    1.在宣告陣列的同時,指定陣列的大小。
    vec3 position[10];//宣告 一個包含10個vec3的陣列
    2.引用陣列之前,要再次使用第一種宣告方式來生命該陣列。
    vec3 position[];//宣告 一個大小不定的vec3整型陣列
    vec3 position[5];//再次宣告該陣列 並指定大小

程式碼中訪問陣列的下標都是編譯時常量,這時編譯器會自動建立適當大小的陣列,使得陣列尺寸足夠儲存編譯器看到的最大索引值對應的元素。

  • 程式碼如下:
  • vec3 position[];//聲明瞭一個大小不定的vec3陣列
    position[3] = vec3(3.0); //position需要一個大小為4的陣列
    position[20] = vec3(6.0); //position需要一個大小為21的陣列

  • 空型別:空型別使用void表示,僅用來宣告不返回任何值得函式。例如在頂點著色器以及片元著色器中必須存在的main函式就是一個返回值為空的函式,程式碼如下:

    void main() {//宣告一個空返回值型別的main方法
     }
     
     

  • 型別修飾符
    1.attribute 一般用於每個頂點都各不相同的資料,例如:顏色,頂點。。。

    • 只有頂點著色器中會有這哥們(attribute )
    • 是屬性限定符
    • 只能用來修飾 浮點數的標量 ,浮點數的向量 , 浮點數的矩陣變數,不能用於修飾其他型別

    2.uinfrom 一致變數限定符

    (一致變數:對同一組頂點組成的單個3D物體中所有的頂點都相同的量)

    • 主要出現在頂點和片元 著色器
    • 可以修飾所有的基本資料型別

    3.verying 用來傳遞頂點著色器中的資料到片元著色器中

    例如:
    頂點著色器 verying vec2 texture;
    片元著色器 verying vec2 texture;

    4.const 加了這哥們變數值不可變,常量,編譯時常量 (編譯時常量:在宣告的時候要進行初始化,編譯器在編譯的時候不需要給他分配任何執行時資源。)
    例如:
    const float PI=3.14;

    5.in 和out 用in修飾的變數代表的是輸入變數,用out修飾的表示輸出變數
    6.inout 用來修飾引數為輸入輸出引數,同時具有兩種功能!

  • GLSL操作符與優先順序

    這裡寫圖片描述

  • 操作符過載
    例如:向量和矩陣之間的乘法 vec3 v;
    mat3 m;
    vec3 r=v*m;注意:矩陣和向量的維度必須匹配!

  • 控制流

if(){
}else{
}
switch(){
    case : brake; 
    default:break;
 }
  • 迴圈語句
for(int i=0 ;i<10;i++){}
while(){}
do{
}while()
  • 流控制語句
    brake;
    return;
    continue;
    discard:丟棄當前片元,終止片元著色器執行( 只能在片元著色器中使用,只要執行到該語句,那片元著色器就 會立刻終止)
  • 函式宣告
    1.函式宣告,變數名需要新增訪問修飾符
    2.GLSL支援使用者自定義函式,同時它定義了一些內建函式
    3.函式名稱可以是任何字元、數字、下劃線,但是不能使用數字,連續下劃線或者gl_作為函式的開始
    4.返回值可以是任何內建的GLSL型別,或者使用者定義的結構體和陣列型別。
    5.返回值是陣列時,必須現實的指定大小。函式返回型別是void則沒有返回值
    6.函式的引數也可以是任何型別的函式,包括陣列(這裡陣列必須設定大小)
    7.在使用一個函式前必須宣告他的原型或者直接給出函式體。
    8.GLSL的編譯器在使用函式前必須找到函式的宣告,否則會產生錯誤
    9.函式原型只是給出了函式的形式,但是並沒有給出具體的實現內容

  • 內建變數

    介紹:著色器程式碼的開發中會用到很多變數,其中大部分可能是由開發人員根據需求自定義的,但著色器中也提供了一些用來滿足特性需求的內建變數
    

    特點:

     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_FogCoord 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 輸出的深度用於隨後的畫素操作,如果這個值沒有被寫,則使用固定功能管線的深度值代替