序言
最近筆者剛學(xué)習(xí)到OpenGLES,在這里也對所學(xué)的知識做一個總結(jié)谁帕,有不對的地方峡继,希望大佬們拍板!
OpenGLES
在這里既然是學(xué)習(xí)OpengGLES匈挖,相信很多人會有疑問碾牌,什么是OpenGLES ? 筆者在這里先賣一個關(guān)子。細(xì)心的應(yīng)該發(fā)現(xiàn)了儡循,OpengGLES 和OpenGL簡直太像了舶吗,難道他們有什么關(guān)系嘛?是的择膝,OpenGL是一種應(yīng)用程序編程接口誓琼,它是一種可以對圖形硬件設(shè)備特性進(jìn)行訪問的軟件庫。而且它也是跨平臺的‰茸剑現(xiàn)在的主要應(yīng)用領(lǐng)域:視頻 圖形圖片處理腹侣,2D/3D游戲引擎開發(fā),科學(xué)可視化齿穗,醫(yī)學(xué)軟件的開發(fā)傲隶,CAD(計算機輔助技術(shù)),虛擬實境(AR VR)缤灵,AI人工智能伦籍。那OpenGLES是什么呢?OpenGL ES是OpenGL的子集腮出,針對手機帖鸦、PDA和游戲主機嵌入式設(shè)備而設(shè)計。筆者理解的就比較簡單了——OpenGL包太大了胚嘲,當(dāng)運用到移動平臺太消耗運行作儿,有些又不實用,就把里面比較有用的提取出來馋劈,就誕生了OpenGLES
著色語言(Shader)
著色器(Shader)是運行在GPU上的小程序攻锰,從基本意義上來說晾嘶,著色器只是一種把輸入轉(zhuǎn)化為輸出的程序。現(xiàn)在我們會用一種更加廣泛的形式詳細(xì)解釋著色器娶吞,特別是OpenGL著色器語言(GLSL)垒迂。
GLSL
著色器是使用一種叫GLSL的類C語言寫成的监右。GLSL是為圖形計算量身定制的便斥,它包含一些針對向量和矩陣操作的有用特性秧廉。
數(shù)據(jù)類型
既然是一門自己的編程語言暮芭,肯定有一些自己的規(guī)范该酗。GLSL中包含C等其他語言纽门,大部門的基礎(chǔ)數(shù)據(jù)類型為:int没炒、float浓领、double陶耍、Uint奋蔚、bool。在GLSL也有二種容器類型烈钞,在實際運用中會使用很多泊碑,分別是向量(Vector)和矩陣(Matrix)
向量
這個筆者第一次接觸在高中,沒想到在這里也會運用到棵磷,哈哈蛾狗。GLSL中的向量可以包含1、2仪媒、3沉桌、4個分量的容器,分量分量的類型可以是基本類型的一個
類型????????????含義
vecn?????????包含 n 個float分量的默認(rèn)向量
bvecn????????包含 n 個bool分量的向量
ivecn????????包含 n 個int分量的向量
uvecn????????包含 n 個unsigned int分量的向量
dvecn????????包含 n 個double分量的向量
在一個向量的分量中算吩,你可以通過 vec.x 這種方式獲取留凭,這里 x 是指這個向量的第一個分量。比如在4向量中(位置偎巢、顏色)蔼夜,可以通過 .x、.y压昼、.z求冷、.w(齊次坐標(biāo))、.r窍霞、.g...等來獲取響應(yīng)的分量的值匠题。當(dāng)然你也可以通過4個任意字母任意組合,創(chuàng)建一個自己想要的向量
vec4 vect = vec4(0.5f, 0.7f,1.0f,2.0f);
頂點著色器
頂點著色器(vertex?shader)提供頂點操作的通用可編程方法.執(zhí)行頂點變換但金、紋理坐標(biāo)變換韭山、光照、材質(zhì)等相關(guān)操作。這里就很靈活了钱磅,開發(fā)者可以根據(jù)自己的需求進(jìn)行開發(fā)
uniform mat4 uMVPMatrix;???????? //總變換矩陣
attribute vec3 aPosition;????????//位置
attribute vec2 aTexCoor;?????????//紋理
varying vec2 vTextureCoord;??????//傳入片元著色器紋理值
void main()
{ ??? ?gl_Position = uMVPMatrix * vec4(aPosition,1);
????????vTextureCoord = aTexCoor;
}
在頂點著色器中我們能夠看到三個變量uniform梦裂、attribute、varying:
uniform:該變量是外部應(yīng)用程序傳遞給頂點著色器和片元著色器的變量.
該變量一般用來表示:變換矩陣盖淡,材質(zhì)年柠,光照參數(shù)和顏色等信息。
attribute:該變量只能在頂點著色器中使用禁舷,不能在片元著色器中使用彪杉。一般用來表示矩陣毅往、光照參數(shù)牵咙、紋理采樣器等。
varying:變量是從頂點著色器傳遞到片元著色器的數(shù)據(jù)變量攀唯。在此需要注意的是洁桌,在頂點著色器中和片元著色器中必須相同。(說白了就是在頂點著色器中得到變換的值侯嘀,傳給片元著色器)
片元著色器
片元著色器(fragment shader)實現(xiàn)了一個通用的可編程操作片段的方法另凌。此片元著色器的主要功能為根據(jù)接收的記錄片元紋理坐標(biāo)的易變變量中的紋理坐標(biāo),調(diào)用texture2D內(nèi)建函數(shù)從采樣器中進(jìn)行紋理采樣戒幔,得到此片元的顏色值吠谢。最后,將采樣到的顏色值傳給gl_FragColor內(nèi)建變量诗茎,完成片元的著色工坊。
precision mediump float;
varying vec2 vTextureCoord; ????????????????????//從頂點接收的紋理值
uniform sampler2D sTexture; //采樣器
void main(){
????????gl_FragColor= texture2D(sTexture, //采樣器:對紋理進(jìn)行采樣的
???????????????????????????????vTextureCoord); //紋理坐標(biāo)
}
在這段代碼中,最后將通過采樣器將值傳給gl_FragColor內(nèi)建變量中敢订。片元著色器可執(zhí)行紋理的訪問王污、顏色的匯總、霧等操作楚午。
在上面的頂點著色器中昭齐,相信很多小伙伴會發(fā)現(xiàn)一遍變量gl_Position 和gl_FragColor,沒有聲明就在使用矾柜,肯定很困惑阱驾。筆者剛開始學(xué)也一樣,下面給大家分析
內(nèi)建變量
就是在OpenGL ES中內(nèi)部定義的量(筆者是這樣理解的)怪蔑,內(nèi)建變量分為二種:頂點著色器中的變量和片元著色器中的變量里覆。著色器通過內(nèi)建變量同這些固定功能進(jìn)行通信,內(nèi)建變量具有全局作用域饮睬。
頂點著色器
頂點著色器中有g(shù)l_Position租谈,gl_PointSize等
gl_Position :只能用在頂點著色器中,在正常的頂點著色器中,都應(yīng)該給該變量傳一個值割去,可以在運行時傳入一個新值窟却,也可以讀取他的值,這個值可以用在頂點處理開始之后的圖元裝配呻逆,剪裁夸赫,剔除和其他操作圖元的固定功能上。如果頂點著色器已經(jīng)執(zhí)行咖城,但是并沒有寫入gl_Position茬腿,那么gl_Position的值是未定義的。
gl_PointSize :只能用在頂點語言中宜雀,頂點著色器用它來寫入將要光柵化的點的尺寸切平,單位是像素。
片元著色器
片元著色器中有g(shù)l_FragColor辐董、gl_FragData悴品、gl_FragCoord、gl_FrontFacing简烘、gl_PointCoord等
在介紹片元著色器之前先介紹一個關(guān)鍵字discard,這個關(guān)鍵字當(dāng)執(zhí)行時苔严,會discard命令會導(dǎo)致丟棄片元(這個筆者也沒用過,只是知道)
gl_FragColor:片元著色器中的可寫變量孤澎,為了指明隨后固定功能管線要用到的片元顏色值
gl_FragData:片元著色器中的可寫變量届氢,變量值是一個數(shù)組。gl_FragData[n]寫入數(shù)據(jù)時為了指明后續(xù)固定功能管線要使用的片元數(shù)據(jù)n覆旭。
如果著色器靜態(tài)地給gl_FragColor賦值退子,那么它就不會給gl_FragData的任何元素賦值。如果著色器靜態(tài)地給gl_FragData的任何元素賦值姐扮,那么它就不會給gl_FragColor賦值絮供。也就是說,著色器不會同時給gl_FragColor和gl_FragData變量都賦值茶敏。
gl_FragCoord:片元著色器中的只讀變量壤靶,它保存了片元相對窗口的坐標(biāo)位置:x, y, z, 1/w。這個值是頂點處理產(chǎn)生片元后固定功能內(nèi)插圖元的結(jié)果惊搏。
gl_FrontFacing:片元著色器的內(nèi)建只讀變量贮乳,如果片元屬于一個當(dāng)前圖元,那么這個值就為true恬惯。這個變量的一個用法就是來模擬兩面光向拆,通過選擇由頂點著色器計算的兩個顏色中的一個。
?gl_PointCoord:片元著色器的內(nèi)建只讀變量酪耳,它的值是當(dāng)前片元所在點圖元的二維坐標(biāo)浓恳。點的范圍是0.0到1.0刹缝。如果當(dāng)前的圖元不是一個點,那么從gl_PointCoord讀出的值是未定義的颈将。
講到這里梢夯,相信小伙伴對著色器有初始的認(rèn)識了。在最后晴圾,筆者給講解一下著色器整個的渲染過程颂砸,為方便小伙伴更好的理解
可編程管線的編程階段(著色器運行流程)
1.頂點數(shù)據(jù):這里就是基本的頂點數(shù)據(jù)
2.頂點著色器:接收頂點數(shù)據(jù),單獨處理每個頂點
3.細(xì)分著色器:描述物體的形狀死姚,在管線中生成新的幾何體人乓,處理(平順)模型,生成最終狀態(tài)都毒。在細(xì)分著色器中分為二步:細(xì)分控制著色器和細(xì)分計算著色器
4.幾何著色器:對所有的圖像進(jìn)行修改色罚,改變幾何圖元的類型,或者放棄掉所有的圖元
5.圖元設(shè)置:是圖形軟件包中用來描述各種圖形元素的函數(shù)温鸽,對圖形函數(shù)的操作
6.裁剪:裁剪掉視口之外的繪制
7.光柵化:將輸入圖元的數(shù)學(xué)描述保屯,轉(zhuǎn)換為與屏幕位置對應(yīng)的像素片元(實際位置坐標(biāo)轉(zhuǎn)化為圖像的過程)
8.片元著色器:片元顏色以及深度值,然后傳遞到片元測試和混合模板
9.效果