OpenGL ES 2.0 入门(持续更新)
請尊重原創,轉載請注明出處:http://blog.csdn.net/mabeijianxi/article/details/79186086
發現公司不管是游戲業務還是視頻業務無不與 Open GL 息息相關,于是每周抽了點時間操練下,萬一哪天被點將點中了也是不虛的,下面是筆者的一些學習筆記。
一、Open GL 2.0 的渲染管道
Created with Rapha?l 2.1.2基本處理頂點著色器圖元裝配光柵化片原著色器剪裁測試深度測試、模板測試顏色混合抖動幀緩沖1、基本處理
基本處理主要對頂點坐標、頂點顏色、頂點紋理坐標等屬性賦值,并制定繪制方式,如三角形、線段、點等。
2、頂點著色器
2.0的頂點著色器整合了 1.0 中的頂點變換、光照計算,變成了可編程的形式了,主要是進行變換、光照計算、材質的應用與計算等頂點相關的操作,并將處理后的信息傳遞給圖元裝配。
3、圖元裝配
圖元裝配主要有兩個任務,一個是圖元組裝,一個是圖元處理。圖元組裝是根據繪制方式把頂點數據組裝成完整的圖元,比如三角形,需要三個頂點組成一個圖元。圖元處理主要是對圖元進行剪裁,因為根據觀察位置和角度的不同,看到的物體形狀也不同,一個三角形可能會被剪裁成4邊形,這時候就成了四個頂點了。
4、光柵化
屏幕是2D的,在光柵化之前會把3D的物體投影到2平面上,然后后理是把連續的數學量轉換為離散的數學量,因為電子屏幕的像素點是一個一個的,這些離散的量就叫片原,其實就是候選像素。因為可能有很多的圖元,同一位置也可能有很多的片原,但是只會有一個片原成為最后的像素,所以才叫候選像素,具體的還需要進行計算對比。
5、片原著色器
片原著色器主要是執行紋理的采樣、顏色的匯總、計算霧顏色等操作,每個片原執行一次。
6、剪裁測試
如果程序設定了剪裁測試,并當前片原在幀緩存中對應的位置在剪裁窗口中就進入下一階段、否則丟棄。
7、深度測試、模板測試
如果幀緩存中同一位置有n個圖元那么深度值小的將會被送入下一階段,反之丟棄,深度就是離攝像機的距離,想象一下,距離近的肯定是擋住了距離遠的,距離遠的肯定就沒必要存在了。模板測試主要功能為將繪制區域限定在一定范圍內,一般用在湖面倒影、鏡像等場合。
8、顏色緩沖混合
若程序開啟了Alpha 混合,則根據混合因子將上一階段送來的片原與幀緩沖中對應位置的片原進行Alpha混合;否則后來的覆蓋幀緩存中當前的。
9、抖動
暫時略
10、幀緩沖
Open GL ES 中的物體并不是直接繪制在屏幕上的,而是預先在幀緩沖區進行繪制,沒繪制完一幀再把結果交換到屏幕上。幀緩沖主要包括:顏色緩沖、深度緩沖、模板緩沖。
——2018.02.03更
二、著色語言(Shading Language):
與傳統通用編程語言有很大不同的是,其提供了更加豐富的原生類型,如向量、矩陣等。這些新特性的加入使得 OpenGL ES 著色語言在處理3D圖形方面更加高效、易用。簡單倆說,OpenGL ES 著色語言包括以下特性。
- OpenGL ES 著色語言是一種高級的過程語言。
- 對頂點著色器、片元著色器使用的是同樣的語言,不做區分。
- 基于 C/C++的語言及流程控制。
- 完美支持向量與矩陣的各種操作。
- 通過類型限定符來管理輸入輸出(attribute、uniform、varying)
- 擁有大量的內置函數來提供豐富的功能(有些是基于硬件的,速度非常快)。
著色語言基礎
數據類型概述:
OpenGL ES 著色語言雖然是基于C/C++ 語言的語言,但是其與C/C++ 相比還是有很大不同的,該語言不支持 double、byte、short、long并取消了 union、enum、unsigned、以及位運算。其支持的類型主要分為:標量、向量、矩陣、采樣器、結構體、數組。
1、標量
也叫無向量,只有大小沒有方向。有 bool、int、float.
2、向量
向量可以看成是同樣類型的標量組成的,其基本類型也分為 bool、int、float 3種,在c語言或者其他語言中都可以構建相應的數據結構在實現向量,但是著色器中的向量不同,其由硬件原生支持,進行向量運算時效率提高很多。每個向量可以由2個、3個或者4個相同的標量組成,如表:
| vec2 | 包含了兩個 float 的向量 | ivec4 | 包含四個 int 的向量 |
| vec3 | 包含了3個 float 的向量 | bvec2 | 包含兩個 bool 的向量 |
| vec4 | 包含了4個 float 的向量 | bvec3 | 包含三個 bool 的向量 |
| ivec2 | 包含了兩個 int 的向量 | bvec4 | 包含四個 bool 的向量 |
| ivec3 | 包含三個 int 的向量 |
向量可以很方便的存儲顏色、位置、紋理坐標等,訪問其某個分量的語法為 <向量明>.<分量名>,根據目的不同主要分為以下幾種:
- 你要是把這個向量當成顏色來看的話,他們的分量名字就是 r、g、b、a或者r、g、b或者、r、g,其取決于定義的維度。
- 要是當成位置看的話,用 x、y、z、w 四個分量明,w表示向量的模,和上面一樣維度也決定了其分量個數。
- 若將一個向量看作紋理坐標,可以使用s、t、p、q等四個分量來表示,維度決定其分量個數。
3、矩陣
很多動畫和矩陣都有著關系,向位移、旋轉、縮放等變換都是由矩陣運算來實現的,矩陣變換其實就是物體在規定的空間按照一定的規則(規則也就是一個或者多個矩陣)就行移動或者說叫跳躍,其實移動、跳躍都不是很準確,就是一個位置跑到另外一個位置的過程。其表示方法如下:
| mat2 | 2 x 2 的浮點數矩陣 |
| mat3 | 3 x 3 的浮點數矩陣 |
| mat4 | 4 x 4 的浮點數矩陣 |
著色語言中,矩陣是按列順序組織的,也就是一個矩陣可以看成是幾個列向量組成的。例如,mat3 就可以看作由 3個vec3組成的。
對于矩陣的訪問,可以將矩陣作為列向量的數組來訪問。如 matrix 為一個 mat4,可以使用 matrix[2]取到該矩陣的第三列,其為一個 vec4。也可以使用 matrix[0][1]取得1列的第二個分量。
4、采樣器
其專門用來進行紋理采樣的相關操作。一般情況下,一個采樣器代表一副或者一套紋理貼圖,如下:
| sampler2D | 用于訪問二維紋理 | samplerCube | 包含四個 int 的向量 |
| sampler3D | 用于訪問三維紋理 |
采樣器不能在著色器中初始化,一般采樣器都是 uniform 限定符來修飾,從宿主語言接受傳遞進著色器的值。
5、結構體
著色語言的結構體和c中是差不多的。
struct info{ vec3 color; vec3 position; vec2 textureCoor; }6、數組
其使用和聲明和其他語言差不多。下面說下一些特殊的地方。
- 使用的時候可以定義一個大小不一定的數組,但在使用的時候需要為其設定大小:
- 代碼中訪問素組的下標都是編譯時常量,這時編譯器會自動創建適當大小的數組,使得數組尺寸足夠儲存看到的最大索引值對應的元素,這種系統量體裁衣、自動分配的方法若恰當采用可以提高硬件的使用效率,降低對硬件資源的消耗:
7、空類型
void
數據類型的基本使用
- 系統中很多變量的命名都是以“gl_”作為開頭的,因此用戶自定義的變量不允許使用“gl_”作為開頭。
- 一些初始化技巧:
- const 限定符修飾的變量必須在聲明的時候進行初始化。
- 屬性變量、一致變量、易變變量在聲明的時候一定不能進行初始化。(attribute、uniform、varying)
- 混合選擇,如下示例:
- 著色語言沒有提供類型的自動提升功能,并且對類型的匹配要求十分嚴格。也沒有提供類型強制轉換功能,只能使用構造函數來完成的類型的轉換。如果 float f0=1 這就會產生錯誤,可以 float f0=float(1)
限定符:
- attribute 用于描述頂點的信息,如位置、顏色、法向量等,只能用于頂點著色器中,不能在片元著色器中使用,且 attribute 限定符只能用來修飾浮點數標量、浮點數向量以及矩陣變量。2.0中規定了所有實現應該支持的屬性個數不能少于8個。
- uniform 用于指定同一組頂點的單個3D物體中中所有頂點都相同的量,一般為光源位置、當前攝像機位置、投影矩陣等。2.0中也規定了所有實現應該支持的頂點著色器中uniform不能少于128個,片元(todo…)
- varying 變量用于從頂點著色器把數據把數據出入片原著色器,如片原的顏色、法向量、紋理坐標等任意值
- const 用于聲明常量
片元著色器中浮點變量精度的指定
片元著色器中使用浮點相關類型的變量時與頂點著色器中有所不同,在頂點著色器中直接聲明使用即可,而在片元著色器中必須指定精度,若不指定精度可能會引起編譯錯誤。指定方式如下:
lowp float color; //指定名稱為color的float型變量為lowp varying mediump vec2 coord; // 指定名稱為 coord 的 vec2型變量精度為 mediump highp mat4 m; // 指定名稱為m的mat4型變量精度為 highp如果在開發中同一個片元著色器中浮點相關類型的變量都選用同意精度,則可以指定整個著色器中浮點相關類型的默認精度,語法如下:
precision <精度><類型>
特殊的內建變量
著色器提供了一些用來滿足特定需求的內建變量。這些內建變量不需要聲明即可使用,一般用來實現渲染管線固定功能部分與自定義頂點或片元著色器之間的信息交互。
內建變量根據信息傳遞的方向可以分為兩類,輸入與輸出變量。輸入變量負責將渲染管線中固定功能部分產生的信心傳遞進著色器,輸出變量負責將著色器產生的信息傳遞給渲染管線中固定功能部分。
頂點著色器中的內建變量
頂點著色器中主要是輸出變量,包含gl_Position、gl_PointSize 等。在頂點著色器中應該根據需要給這些內建變量賦值,以便由渲染管線中的圖元裝配與光柵化等后續固定功能階段進行進一步的處理。
- gl_Position 頂點著色器中經過變換后得到的新的頂點位置。類型為 vec4
- gl_PointSize 頂點著色器中可以計算一個點的大小,單位為像素,并將其賦值給 gl_PointSize,如果沒賦值默認是1,一般采用點繪制的時候才有意義。
片元著色器中的內建變量
片元著色器有輸入和輸出兩種內建變量。
1、內建輸入變量
片元著色器中的內建變量主要有gl_FragCoord 以及 gl_FrontFacing。這兩個內建變量都是只讀的。
- gl_FragCoord(vec4類型)中含有當前片元相對于窗口位置的坐標信息 x、y、z、1/w。其中z代表深度,也就是距離攝像機的距離。
- gl_FrontFacing 是一個布爾型的內建變量,通過讀取該內建變量的值可以判斷正在處理的片元是否在光柵化階段生成此片元的對應圖元的證明。如果輸入證明值就是 true.
2、內建輸出變量
片元著色器中的內建輸出變量主要有 gl_FragColor 與 gl_FragData,在片元著色器中根據情況需要給它賦值。
- gl_FragColor是 vec4類型,其是由片元著色器寫入計算完成的片元顏色值,此顏色值將送入渲染管線的后續階段進行處理。
- gl_FragData 內建變量是一個 vec4 類型數組,寫入時要給出下標。
實際開發中只需要為兩個中的一個賦值即可。
著色語言的內置函數
其內置的函數通常都是以最優方式實現的,有部分函數有硬件直接支持,效率賊高。內置函數按照設計目的可以分為以下3個類別。
- 提供獨特硬件功能的訪問接口,如紋理采樣系列函數,這些函數是用戶無法自己開發的。
- 簡單的數學函數,如 abs、floor 等
- 一些復雜的函數,如三角函數。
具體函數,不做記錄,可以參考這里http://developer.download.nvidia.com/CgTutorial/cg_tutorial_appendix_e.html。
總結
以上是生活随笔為你收集整理的OpenGL ES 2.0 入门(持续更新)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机图形学教程动画实验报告,计算机图形
- 下一篇: 标签打印机ESC光栅位图打印指令