OpenGL ES基礎知識回顧

OpenGL ES基礎知識回顧

  • GLSL著色器語言
  • 語言基礎
  • 繪制方式
  • 紋理映射

一、GLSL著色器語言

  • 渲染管線
    渲染管線有時也被稱為渲染流水線,一般是由顯示芯片(GPU)內部處理圖形信號的并行處理單元組成。這些并行處理單元兩兩之間是相互獨立的,在不同型號的硬件上獨立處理單元的數量也有很大的差異。一般越高端的硬件,其中獨立處理單元的數量也就越多。
  • 頂點著色器:頂點著色器是一個可編程的處理單元。(接收頂點緩存對象的頂點數據,單獨處理每個頂點。)
    功能:為執行頂點的變換、光照、材質的應用與計算等頂點的相關操作,其每頂點執行一次。
    工作過程為:首先將原始的頂點幾何信息及其他屬性傳遞到頂點著色器中,經過自己開發的頂點著色器處理后產生紋理坐標、顏色、點位置等后繼流程需要的各項頂點屬性信息,然后將其傳遞給圖元裝配階段。
    頂點著色器的工作原理圖

(1) 頂點著色器的輸入主要為待處理頂點相應的 attribute(屬性) 變量、uniform(全局) 變量、采樣器以及臨時變量,輸出主要為經過頂點著色器后生產的varying(易變) 變量及一些內建輸出變量。
(2) attribute 變量指的是3D物體中每個頂點各自不同的信息所屬的變量,一般頂點的位置、顏色、法向量等每個頂點各自不同的信息都是以attribute 變量的方式傳入頂點著色器的。

  • 片元著色器:片元著色器是用于處理片元值及其相關數據的可編程單元,其可以執行紋理的采樣,顏色的匯總,計算霧顏色等操作,每片元執行一次。
    功能:是通過重復執行(每片元一次),將3D物體中的圖元光柵化后產生的每個片元的顏色屬性計算出來送入后繼階段,如剪裁測試、深度測試及模板測試等。

  • 細分著色器:接收來自頂點著色階段的輸出數據,并對收到的數據進一步處理。(用Patch描述一個物體的形狀,在OpenGL管線內部生成新的幾何體,并且模型的外觀也會變得更加平順,細分著色器會用到兩個階段來分別管理Patch數據,并生成最終狀態)。

  • 幾何著色器:在管線內部會對所有的圖元進行修改,改變幾何圖元的類型,或者放棄所有的幾何體。如果啟用,那么輸入可能會來自頂點著色階段完成的幾何圖元,也可能來自細分階段的圖元數據。

  • 光柵化:將輸入圖元的數學描述轉換為與屏幕位置對應的像素片元。


二、語言基礎

-數據類型概述

  • 標量

  • 布爾型—bool

  • 整形–int

  • 浮點型–float

  • 向量

向量類型 說明
vec2 包含了2個浮點數的向量
vec3 包含了3個浮點數的向量
vec4 包含了4個浮點數的向量
向量類型 說明
ivec2 包含了2個整數的向量
ivec3 包含了3個整數的向量
ivec4 包含了4個整數的向量
向量類型 說明
bvec2 包含了2個布爾數的向量
bvec2 包含了3個布爾數的向量
bvec2 包含了4個布爾數的向量

向量的運算

vec4 a; vec4 b;
a-b :A和B分量相減

  • 加長取短
    加長:vec2 a;
    vec4 c=vec4( a,1000,2 );
    取短 :vec4 rgba;
    vec3 rgb=vec3( rgba.rgb);

  • 矩陣

  • 特點:先填充列,然后填充行。

矩陣類型 說明
mat2 2 x 2 的浮點矩陣
mat3 3 x 3 的浮點矩陣
mat4 4 x 4 的浮點矩陣
- - -
1 4 7
2 5 8
3 6 9

mat3 m = mat(1,2,3,4,5,6,7,8,9);
mat3 m = mat(vec3(1,2,3), vec3(4,5,6), vec3(7,8,9));

  • 采樣器:采樣器是著色器語言中不同于C語言的一種特殊的基本數據類型,其專門用來進行紋理采樣的相關操作。一般情況下,一個采樣器變量代表一幅或一套紋理貼圖。 其具體情況如下表:
采樣器類型 說明
sampler2D 用于訪問二維紋理
sampler3D 用于訪問三維紋理
samplerCube 用于訪問立體貼圖紋理

特點

  1. 采樣器變量不能再著色器中初始化。
  2. 一般情況下采樣器變量都用uniform限定符來修飾,從寄主語言(如java)接收傳遞進著色器的值。
  3. sampler3D 并不是在所有的OpenGL ES 實現中都支持,因此,如要使用必須首先在著色器代碼中進行設置,打開相應的擴展。
  • 結構體
    結構體:OpenGL ES 著色器還提供了類似于c語言中的用戶自定義結構體,同樣也是使用struce關鍵字進行聲明,基本用法如下所示。
struct info{           //聲明一個結構體info
    vec3 color;        //顏色成員
    vec3 position;     //位置成員
    vec2 textureCoor;  //紋理坐標成員
}

聲明了info類型的結構體之后,就可以像使用內健數據類型一樣使用 這 個用戶自定義的數據類型了,如:

info CubeInfo;   //聲明了一個info類型的變量CubeInfo

對于結構體來說,其他的使用方法都與C語言基本類似。

  • 數組

聲明數組的方式:

  • 在聲明數組同時,指定數組的大?。?/li>
vec3 position[20]; //聲明了一個包含20個vec3的數組,索引從0開始。

  • 在聲明數組時,也可以不指定數組的大小,但是必須符合下列兩種情況之一。

  • 引用數組之前,要再次使用第一種聲明方式來聲明該數組,具體代碼如下:

vec3 position[];  //聲明了一個大小不定的vec3型數組。
vec3 pisition[]5; //再次聲明該數組,并且指定大小。
  • 提示:再次聲明數組,指定大小之后,就不能再進行聲明了。
  • 代碼中訪問數組的下標都是編譯時常量(如:字面常量),這時編譯器會自動創建適當大小的數組,使得數組尺寸足夠存儲編譯器看到的最大索引值對應的元素,代碼如下:
vec3 position[];  //聲明了一個大小不定的vec3型數組。
pisition[3] = vec3(3.0);//position需要為一個大小為4的數組
position[20] = vec3(6.0);//position需要為一個大小為21的數組
  • 說明:上述代碼的第2行需要尺寸為4的數組,代碼的第3行需要尺寸為21的數組,若后面沒有更大的下標出現,則編譯器自動創建position為尺寸21的數組。這種由系統量體裁衣、自動分配的方法若恰當采用可以提高硬件的使用效率,降低對硬件資源的消耗。
  • 類型修飾符
修飾符 說明
in 輸入變量
out 輸出變量
inout 輸入輸出變量
attribute 一般用于每個頂點都各不相同的量,如頂點位置、顏色等(只能修飾頂點著色器的變量)
uniform 一般用于對同一組頂點組成的單個3D物體中所有頂點都相同的量,如當前的光源位置 {一致變量修飾符,(頂點和片元都可以用)}
varying 用于從頂點著色器傳遞到片元著色器的量(如果說要傳遞,變量名一致)
const 用于聲明常量

三、繪制方式

  • OpenGL ES 中支持的繪制方式大致分3類,包括點、線段、三角形,每類中包含一種或多種具體的繪制方式,各種具體繪制方式的說明如下所列。

① GL_POINTS:點類下唯一的繪制方式,用來繪制點。
② GL_LINES:將著色器傳入的頂點按順序兩個一組來繪制成線段。
③ GL_LINES_STRIP:按照頂點順序連接頂點。(不封口)
④ GL_LINES_LOOP:按照頂點順序連接頂點,并將第一個頂點和最后一個頂點相連。(封口)
⑤ GL_TRIANGLES:按照頂點順序每3個點組成三角形進行繪制。
⑥ GL_TRIANGLE_STRIP:頂點按照順序依次組織成三角形進行繪制, 最后實際形成的是一個三角形帶。若有 N個頂點將繪制出n-2個三角形 (節省頂點空間)
⑦ GL_TRIANGLE_FAN:將第一個點作為中心點其他點作為邊緣點,繪制一系列組成扇形的相鄰三角形
⑧ glDrawArrays:按照傳入渲染管線頂點本身的順序及選用的繪制方式將頂點組織成圖元進行繪制。稱之 為頂點法( 特點:方便 ,但是出現了很多的重復頂點。 )
⑨ glDrawElements:繪制時不但要將頂點序列傳入渲染管線,還需要將索引序列傳入管線,繪制時跟據索引序列取出頂點值,并根據當前選用的繪制方式組織成圖元。

區別:
用GL_TRIANGLES繪制方式(繪制一個正方形)
1.glDrawArrays需要6個頂點
2.glDrawElements需要四個頂點


四、紋理映射

  • 紋理映射的原理
    ① 為頂點指定紋理坐標;
    ② 通過紋理坐標在紋理圖上確定紋理區域;
    ③ 將選定的區域根據紋理坐標映射到圖元上。

  • 紋理的注意事項
    ① 紋理坐標用浮點數來表示,范圍一般從0.0~1.0;
    ② 規定紋理的圖片的寬高必須是2的n次方;

  • 紋理拉伸和截取
    兩種拉伸方式的概述
    無論是 S 軸還是 T 軸的紋理坐標都是在0.0~1.0中,這滿足了大多數情況。但是在特定的情況下,也可以設置大于1的紋理坐標。當紋理坐標大于1以后,設置的拉伸方式就會起作用了。下面對兩種拉伸方式進行單獨介紹:
    (1) 重復拉伸方式
    如果設置的拉伸方式為重復,當頂點紋理坐標大于1時則實際起作用的紋理坐標為紋理坐標的小數部分。也就是說若紋理坐標為3.3,則起作用的紋理坐標為0.3,這種情況下會產生重復的效果。如下圖所示:

 //重復拉伸
   GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D
                         ,GLES20.GL_TEXTURE_WRAP_S //設置S軸的拉伸方式為重復
                         ,GLES20.GL_REPEAT);

   GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D
                          ,GLES20.GL_TEXTURE_WRAP_T  //設置S軸的拉伸方式為重復
                           ,GLES20.GL_REPEAT);
  • 提示:開發中 S 與 T 兩個軸的拉伸方式是獨立設置的,但在一般情況下兩個軸都會設置同樣的選項。

重復拉伸的方式在很多大場景地形的紋理貼圖中很有作用,如將大塊地面重復鋪滿草皮紋理、將大片水面重復鋪滿水波紋等。如果沒有重復拉伸方式,則開發人員只能將大塊面積切割為一塊一塊的小面積矩形,對每一塊矩形單獨設置0.0 ~ 1.0 內的紋理坐標。這樣開發不但繁瑣,而且大大增加了頂點的數量,程序運行的效率也會受到很大的影響。因此開發中要注意重復拉伸方式的靈活運用,可以使用重復拉伸方式時就不要去無畏地增加頂點數量了。

(2) 截取拉伸方式

截取拉伸方式中當紋理坐標的值大于1時都看作 1,因此會產生邊緣被拉伸的效果。具體情況如下圖所示。

從圖中可以看出,需要紋理映射的矩形中4個頂點紋理坐標分別為(0,0)、( 4,0)、(0,4)、( 4,4),因此矩形中的各片元紋理坐標范圍為S 軸方向 0 ~ 4,T 軸方向0 ~ 4.由于在此種拉伸方式下,大于1的紋理坐標都看作1,因此產生了紋理橫向和縱向邊緣被拉伸的效果。

   //截取拉伸
   GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
                          GLES20.GL_TEXTURE_WRAP_S,//設置S軸的拉伸方式為截取
                          LES20.GL_CLAMP_TO_EDGE);

   GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
                         GLES20.GL_TEXTURE_WRAP_T,//設置T軸的拉伸方式為截取
                         LES20.GL_CLAMP_TO_EDGE);
  • 紋理采樣

所謂紋理采樣就是:根據片元的紋理坐標到紋理圖中提取對應位置顏色的過程。但是由于被渲染圖元中的片元中的片元數量與其對應紋理區域中像素的數量并不一定相同,也就是說圖元中的片元與紋理圖中的像素并不總是–對應的。

例如,將較小的紋理圖映射到較大的圖元或將較大的紋理映射到較小的圖元時這種情況就會產生。因此通過紋理坐標在紋理圖中并不一定能找到與之完全對應的像素,這時候需要采用一些策略使得紋理采樣可以順利進行下去。通常采用的策略有最近點采樣、線性采樣兩種。

  1. 最近點采樣
  1. 線性紋理采樣
  1. MIN 與 MAG 采樣

腳注

生成一個腳注[1].

[TOC]

目錄

[TOC]

  • 關于 其iOS開發-GitHub地址 ,參考 這兒,
  • 關于 其CSDN博客地址 ,參考 這兒,

  1. 這里是 腳注內容. ?

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容