OpenGL學(xué)習(xí)之著色器與渲染管線

OpenGL學(xué)習(xí)之著色器與渲染管線

看此篇之前請(qǐng)看http://www.lxweimin.com/p/68ee05d6106a

著色器與渲染管線

渲染管線一般是有顯示芯片(GPU)內(nèi)部處理圖形信號(hào)的并行處理單元組成。這些并行處理單元兩兩之間是相互獨(dú)立的,在不同型號(hào)的硬件上獨(dú)立處理單元的數(shù)量也有很大的差異。

圖中陰影部分是可編程的部分

enter image description here
  1. 基本處理
    該階段設(shè)定3D空間中物體的頂點(diǎn)坐標(biāo),頂點(diǎn)對(duì)應(yīng)的顏色,頂點(diǎn)的紋理坐標(biāo)等屬性,并且指定繪制方式。

  2. 頂點(diǎn)著色器
    頂點(diǎn)著色器是一個(gè)可編程的處理單元,功能為執(zhí)行頂點(diǎn)的變換,光照,材質(zhì)的應(yīng)用于計(jì)算等頂點(diǎn)的相關(guān)操作。工作過(guò)程為首先將原始的頂點(diǎn)幾何信息及其他屬性傳送到頂點(diǎn)著色器中,經(jīng)過(guò)自己開(kāi)發(fā)的頂點(diǎn)著色器處理后產(chǎn)生紋理坐標(biāo),顏色,點(diǎn)位置等后繼流程需要的各項(xiàng)頂點(diǎn)屬性信息,然后將其傳遞給圖元裝配階段。
    頂點(diǎn)著色器的輸入主要為待處理頂點(diǎn)相應(yīng)的attribute變量,uniform變量,采樣器以及臨時(shí)變量;輸出主要為經(jīng)過(guò)頂點(diǎn)著色器生成的varying變量及一些內(nèi)建輸出變量。

頂點(diǎn)著色器的輸入數(shù)據(jù)由下面組成:
Attributes:使用頂點(diǎn)數(shù)組封裝每個(gè)頂點(diǎn)的數(shù)據(jù),一般用于每個(gè)頂點(diǎn)都各不相同的變量,如頂點(diǎn)位置、顏色等。
Uniforms:頂點(diǎn)著色器使用的常量數(shù)據(jù),不能被著色器修改,一般用于對(duì)同一組頂點(diǎn)組成的單個(gè)3D物體中所有頂點(diǎn)都相同的變量,如當(dāng)前光源的位置。
Samplers:這個(gè)是可選的,一種特殊的uniforms,表示頂點(diǎn)著色器使用的紋理。
Shader program:頂點(diǎn)著色器的源碼或可執(zhí)行文件,描述了將對(duì)頂點(diǎn)執(zhí)行的操作。

輸出變量-易變比那里在頂點(diǎn)著色器賦值后并不是將賦的值送入后后繼的片元著色器中,而是在光柵化階段由管線根據(jù)片元所屬頂點(diǎn)對(duì)應(yīng)的頂點(diǎn)著色器對(duì)此易變變量的賦值情況及片元與各項(xiàng)頂點(diǎn)的位置插值產(chǎn)生。

enter image description here

下面是一個(gè)用opengl es著色器語(yǔ)言編寫的頂點(diǎn)著色器源碼,這個(gè)頂點(diǎn)著色器使用一個(gè)position和跟它相關(guān)聯(lián)的color數(shù)據(jù)作為輸入數(shù)據(jù),通過(guò)一個(gè)4×4矩陣變換位置,然后輸出變換后的位置和顏色數(shù)據(jù)。

 // uniforms used by the vertex shader
 uniform mat4 u_mvpMatrix; // matrix to convert P from model
 // space to normalized device space.
 
 // attributes input to the vertex shader
 attribute vec4 a_position; // position value
 attribute vec4 a_color; // input vertex color

 // varying variables – input to the fragment shader
 varying vec4 v_color; // output vertex color
 void main() {
 v_color = a_color;
 gl_Position = u_mvpMatrix * a_position;
 }
  1. 圖元裝配(primitive assembly)
    頂點(diǎn)著色器之后,渲染管線的下一個(gè)階段是圖元裝配,圖元是一個(gè)能用OpenGL ES繪圖命令繪制的幾何體,繪圖命令指定了一組頂點(diǎn)屬性,描述了圖元的集合形狀和圖元類型。頂點(diǎn)著色器使用這些頂點(diǎn)屬性計(jì)算頂點(diǎn)的位置,顏色以及紋理坐標(biāo),這樣才能傳到片元著色器。
    這個(gè)階段主要有兩個(gè)任務(wù),一個(gè)是圖元組裝,另一個(gè)是圖元處理。
    圖元組裝是指頂點(diǎn)數(shù)據(jù)根據(jù)設(shè)置的繪制方式被結(jié)合成完整的圖元,例如,點(diǎn)繪制方式下僅需要一個(gè)單獨(dú)的頂點(diǎn),每個(gè)頂點(diǎn)為一個(gè)圖元;線段繪制方式則需要兩個(gè)頂點(diǎn),每?jī)蓚€(gè)頂點(diǎn)構(gòu)成一個(gè)圖元。
    圖元處理最重要的工作是剪裁,對(duì)于每個(gè)圖元,必須確定它是否位于視椎體內(nèi)(3維空間顯示在屏幕上的可見(jiàn)區(qū)域),如果圖元部分在視椎體中,需要進(jìn)行裁剪,如果圖元全部在視椎體外,則直接丟棄圖元。裁剪之后,頂點(diǎn)位置轉(zhuǎn)換成了屏幕坐標(biāo)。背面剔除操作也會(huì)執(zhí)行,它根據(jù)圖元是正面還是背面,如果是背面則丟棄該圖元。經(jīng)過(guò)裁剪和背面剔除操作后,就進(jìn)入渲染流水線的下一個(gè)階段:光柵化。

  2. 光柵化(Rasterization)
    光柵化階段把圖元轉(zhuǎn)換成片元集合,之后會(huì)提交給片元著色器處理,這些片元集合表示可以被繪制到屏幕的像素。如下圖所示:

enter image description here
  1. 片元著色器
    片元著色器是用于處理片元值及相關(guān)數(shù)據(jù)的可編程單元,其可以執(zhí)行紋理的采樣,顏色的匯總,計(jì)算霧顏色等操作。片元著色器主要功能為通過(guò)重復(fù)執(zhí)行(每片元一次)將3D物體中的圖元光柵化后產(chǎn)生的每個(gè)片元的顏色等屬性計(jì)算出來(lái)送入后繼階段;
    片元著色器對(duì)光柵化階段產(chǎn)生的每個(gè)片元進(jìn)行操作,需要的輸入數(shù)據(jù)如下:
    • Varying variables:頂點(diǎn)著色器輸出的varying變量經(jīng)過(guò)光柵化插值計(jì)算后產(chǎn)生的作用于每個(gè)片元的值。
    • Uniforms:片元著色器使用的常量數(shù)據(jù)
    • Samplers:一種特殊的uniforms,表示片元著色器使用的紋理。
    • Shader program:片元著色器的源碼或可執(zhí)行文件,描述了將對(duì)片元執(zhí)行的操作。

片元著色器也可以丟棄片元或者為片元生成一個(gè)顏色值,保存到內(nèi)置變量gl_FragColor。光柵化階段產(chǎn)生的顏色、深度、模板和屏幕坐標(biāo)(Xw, Yw)成為流水線中pre-fragment階段(FragmentShader之后)的輸入。如下圖:

enter image description here
  • Varting0~n值的是從頂點(diǎn)著色器傳遞到片元活色器的易變數(shù)據(jù)變量,它是由系統(tǒng)在頂點(diǎn)著色器后的光柵化階段自動(dòng)插值產(chǎn)生,其個(gè)數(shù)不一定。

  • gl_FragColor值的是計(jì)算后此片元的顏色。一般在片元著色器的最后都需要對(duì)gl_FragColor進(jìn)行賦值。

    下面是一個(gè)簡(jiǎn)單的片元著色器源碼,可以跟上面的頂點(diǎn)著色器源碼結(jié)合繪制一個(gè)高洛德著色的三角形。

    precision mediump float;
    varying vec4 v_color; // input vertex color from vertex shader
    void main(void) {
    gl_FragColor = v_color;
    }

  1. 追個(gè)片元操作階段(Per-Fragment Operations)
    片元著色器之后就是追個(gè)片元操作階段,包括一系列的測(cè)試階段。一個(gè)光柵化階段產(chǎn)生的具有屏幕坐標(biāo)(x,y)的片元,只能修改framebuffer(幀緩沖)中位置在(x,y)的像素。下圖是Opengl es 2.0逐片元操作的過(guò)程:
enter image description here

Pixel ownership test:像素所有權(quán)測(cè)試,決定framebuffer中某一個(gè)(Xw, Yw)位置的像素是否屬于當(dāng)前Opengl ES的context,比如:如果一個(gè)Opengl ES幀緩沖窗口被其他窗口遮住了,窗口系統(tǒng)將決定被遮住的像素不屬于當(dāng)前Opengl ES的context,因此也就不會(huì)被顯示。
Scissor test:裁剪測(cè)試,決定位置為(Xw, Yw)的片元是否位于裁剪矩形內(nèi),如果不在,則被丟棄。
Stencil and depth tests:模板和深度測(cè)試,傳入片元的模板和深度值,決定是否丟棄片元。
Blending:將新產(chǎn)生的片元顏色值和framebuffer中某個(gè)(Xw, Yw)位置存儲(chǔ)的顏色值進(jìn)行混合。
Dithering:抖動(dòng),可以用來(lái)最大限度的減少使用有限精度存儲(chǔ)顏色值到framebuffer的工件。
逐片元操作之后,片元要么被丟棄,要么一個(gè)片元的顏色,深度或者模板值被寫入到framebuffer的(Xw, Yw)位置,不過(guò)是否真的會(huì)寫入還得依賴于write masks啟用與否。write masks能更好的控制顏色、深度和模板值寫入到合適的緩沖區(qū)。例如:顏色緩沖區(qū)中的write mask可以被設(shè)置成沒(méi)有紅色值寫入到顏色緩沖區(qū)。另外,Opengl ES 2.0提供從framebuffer中獲取像素的接口,不過(guò)需要記住的是像素只能從顏色緩沖區(qū)讀回,深度和模板值不能讀回。

注意:Opengl ES 2.0 的Per-Fragment Operations已經(jīng)不再支持Alpha test 和 LogicOp了,這兩個(gè)步驟在 OpenGL 2.0 和 OpenGL ES 1.x中是存在的。Alpha test 階段不再需要的原因是片元著色器可以丟棄片元,所以可以在片元著色器中執(zhí)行Alpha test。 LogicOp因?yàn)楹苌偈褂茫圆辉僦С至恕?/p>

  1. 幀緩沖
    OpeGL ES中的物體繪制并不是直接在屏幕上進(jìn)行的,而是預(yù)先在幀緩沖區(qū)中進(jìn)行繪制,每繪制玩一幀再將繪制的結(jié)果交換到屏幕上。因此,在每次繪制新的一幀時(shí)都需要清除緩沖區(qū)中的相關(guān)數(shù)據(jù),否則有可能產(chǎn)生不正確的繪制效果。
    同時(shí),微課應(yīng)對(duì)不同方面的需要,幀緩沖是由一套組件組成的,主要包括顏色緩沖,深度緩沖以及模板緩沖
    • 顏色緩沖用于存儲(chǔ)每個(gè)片元的顏色值,每個(gè)顏色值包括RGBA 4個(gè)色彩通道,應(yīng)用程序運(yùn)行時(shí)在屏幕上看到的就是顏色緩沖中的內(nèi)容。
    • 深度緩沖用來(lái)存儲(chǔ)每個(gè)片元的深度值,所謂深度值是指以特定的內(nèi)部格式表示的從片元處到觀察點(diǎn)(攝像機(jī))的距離。在啟用深度測(cè)試的情況下,新片元想進(jìn)入幀緩沖時(shí)需要將自己的深度值與幀緩沖中對(duì)應(yīng)位置的片元的深度值進(jìn)行比較,若結(jié)果小于才可能進(jìn)行緩沖,否則丟棄。
    • 模板緩沖用來(lái)存儲(chǔ)每個(gè)片元的模板值,供模板測(cè)試使用。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評(píng)論 6 533
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,556評(píng)論 3 418
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 176,463評(píng)論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 63,009評(píng)論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,778評(píng)論 6 410
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 55,218評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 42,436評(píng)論 0 288
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,969評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,795評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,993評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評(píng)論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,229評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 34,659評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 35,917評(píng)論 1 286
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,687評(píng)論 3 392
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,990評(píng)論 2 374

推薦閱讀更多精彩內(nèi)容