OpenGLES渲染管道,頂點(diǎn)著色器(VertexShader) 拒名,片元著色器(FragmentShader)

著色器只能用在OpenGLES 2.X以上等可編程管道里吩愧,而在OpenGLES 1.X是不能使用的。

管線增显,Pipeline雁佳,顯卡執(zhí)行的、從幾何體到最終渲染圖像的同云、數(shù)據(jù)傳輸處理計(jì)算的過程

OpenGLES1.X中它是固定管道糖权,整體式封閉的,中間的各道工藝按固定的流程順序走炸站。如圖所示:

從上圖可以看出温兼,這些工藝順序是固定的,整個(gè)過程又分為:處理頂點(diǎn)武契,處理片元,驗(yàn)證片元信息并存入內(nèi)存

Rasterizer:光柵化處理,當(dāng)頂點(diǎn)處理完咒唆,會交給rasterizer來進(jìn)行光柵化處理届垫,結(jié)果會吧頂點(diǎn)的坐標(biāo)信息轉(zhuǎn)換成能在屏幕顯示的像素信息,即片元(Fragments)

生成片元后全释,接下來就是對fragments片元的各種驗(yàn)證装处,即過濾掉無用的片元,裁剪掉不在視野內(nèi)的片元浸船,最終把有效片元存儲入內(nèi)存中妄迁。

光柵化處理過程,就是把矢量圖轉(zhuǎn)化成像素點(diǎn)的過程李命。我們屏幕上顯示的畫面都是由像素組成登淘,而三維物體都是點(diǎn)線面構(gòu)成的。要讓點(diǎn)線面變成能在屏幕上顯示的像素封字,就需要Rasterizer這個(gè)過程黔州。

OpenGLES2.X可編程管道,由兩VertexShader(頂點(diǎn)著色器)阔籽、FragmentsShader(片元著色器)組成流妻,分別對應(yīng)上圖中的Coordinates 和Texture等藍(lán)色塊

OpenGLES2.0可渲染管道圖:

VertexShader:頂點(diǎn)著色器

頂點(diǎn)著色器輸入包括:

著色器程序——描述頂點(diǎn)上執(zhí)行操作的頂點(diǎn)著色器程序源代碼或者可執(zhí)行文件

頂點(diǎn)著色器輸入(或?qū)傩?——用頂點(diǎn)數(shù)組提供的每個(gè)頂點(diǎn)的數(shù)據(jù)

統(tǒng)一變量(uniform)——頂點(diǎn)(或片段)著色器使用的不變數(shù)據(jù)

采樣器——代表頂點(diǎn)著色器使用紋理的 特殊統(tǒng)一變量類型

頂點(diǎn)著色器的輸出在OpenGLES2.0稱作可變變量(varying),但在OpenGLES3.0中改名為頂點(diǎn)著色器輸出變量笆制。

在光柵化階段绅这,為每個(gè)生成的片段計(jì)算頂點(diǎn)著色器輸出值,并作為輸入傳遞給片段著色器在辆。

插值:光柵器對從頂點(diǎn)著色器傳遞的變量進(jìn)行插值

為了在屏幕上真正顯示证薇,必須將頂點(diǎn)著色器vs的輸出變量設(shè)置為gl_Position,gl_Position是一個(gè)保存著頂點(diǎn)齊次坐標(biāo)的4維向量开缎。ZYZ分量被W分量分割(稱作視角分割)并且XYZ分量上超過單位化盒子([-1, 1])的部分會被裁剪掉棕叫。最終的結(jié)果會被轉(zhuǎn)換到屏幕坐標(biāo)系然后三角形(或其它圖元類型)被光柵器生成對應(yīng)的像素。

OpenGLES3.0新增了一個(gè)功能——變換反饋奕删,使頂點(diǎn)著色器輸出可以選擇性地寫入一個(gè)輸出緩沖區(qū)(除了傳遞給片段著色器之外俺泣,也可用這種傳遞替代)

頂點(diǎn)著色器的輸入和輸出如下圖所示:

先看看腳本:

private final String mVertexShader =

"uniform mat4 uMVPMatrix;\n" +

"attribute vec4 aPosition;\n" +

“attribute vec4 a_color;\n” +

"attribute vec2 aTextureCoord;\n" +

"varying vec2 vTextureCoord;\n” +

“out vec4 v_color;\n"

"void main() {\n" +

" gl_Position = uMVPMatrix * aPosition;\n" +

"?vTextureCoord = aTextureCoord;\n" +

“ v_color = a_color;\n"

"}\n";

private final String mFragmentShader =

"precision mediump float;\n" +

"varying vec2 vTextureCoord;\n" +

"uniform sampler2D sTexture;\n" +

"void main() {\n" +

"gl_FragColor = texture2D(sTexture, vTextureCoord);\n” +

"}\n”;

其中腳本語句關(guān)鍵字:

attribute:使用頂點(diǎn)數(shù)組封裝每個(gè)頂點(diǎn)的數(shù)據(jù),一般用于每個(gè)頂點(diǎn)都各不相同的變量完残,如頂點(diǎn)位置伏钠、顏色等

uniform:頂點(diǎn)著色器使用的常量數(shù)據(jù),不能被著色器修改谨设,一般用于對同一組頂點(diǎn)組成的單個(gè)3D物體中所有頂點(diǎn)都有相同的變量熟掂,如當(dāng)前光源位置

sampler:這是可選的,一種特殊的uniform扎拣,表示頂點(diǎn)著色器使用的紋理

mat4:表示4x4浮點(diǎn)數(shù)矩陣赴肚,該變量存儲了組合模型視圖和投影矩陣

vec4:表示包含了4個(gè)浮點(diǎn)數(shù)的向量

varying:用于從頂點(diǎn)著色器傳遞到片元或FragmentsShader傳遞到下一步的輸出變量

uMVPMatrix * aPosition:通過4x4 的變換位置后素跺,輸出給gl_Position,gl_Position是頂點(diǎn)著色器內(nèi)置的輸出變量誉券。

gl_FragColor:片元著色器內(nèi)置的輸出變量

PrimitiveAssembly:圖元裝配

圖元即圖形指厌,在OpenGL有幾個(gè)基本圖元:點(diǎn)、線踊跟、三角形踩验,其他的復(fù)雜圖元都是基于這些基本圖元來繪制而成。

在圖元裝配階段商玫,那些經(jīng)過頂點(diǎn)著色器(VertexShader)處理過的頂點(diǎn)數(shù)組或緩沖區(qū)的數(shù)據(jù)(VertexArrays/BufferObjects)箕憾,被組裝到一個(gè)個(gè)獨(dú)立的幾何圖形中(點(diǎn),線拳昌,三角形)

對裝配好的沒個(gè)圖元袭异,都必須確保它在世界坐標(biāo)系中,而對于不在世界坐標(biāo)系中的圖元地回,就必須進(jìn)行裁剪扁远,使其處于在世界坐標(biāo)系中才能流到下一道工序(光柵化處理)

這里還有一個(gè)剔除操作(Cull),前提是這個(gè)功能的開關(guān)是打開的:GLES20.glEnable(GLES20.GL_CULL_FACE); 剔除的是圖元的背影刻像,陰影畅买,背面等。

Rasterization:光柵化

光柵化階段繪制對應(yīng)的圖元(點(diǎn)细睡、線谷羞、三角形),將圖元轉(zhuǎn)化為一組二維數(shù)組的過程溜徙,然后傳遞給片段著色器處理湃缎。這些二維數(shù)組代表屏幕上繪制的像素

(PS:上圖中的點(diǎn)精靈光柵化應(yīng)該是點(diǎn)光柵化)

FragmentShader:片元著色器

片元著色器主要是對光柵化處理后生成的片元逐個(gè)進(jìn)行處理。接收頂點(diǎn)著色器輸出的值蠢壹,需要傳入的數(shù)據(jù)嗓违,以及它經(jīng)過變換矩陣后輸出值存儲位置。

著色器程序——描述片元所執(zhí)行的片元著色器程序源代碼

輸入變量——光柵器對頂點(diǎn)著色器插值后的輸出值

統(tǒng)一變量——片元(或頂點(diǎn))著色器使用的不變的數(shù)據(jù)

采樣器——代表片元著色器所用紋理的一種特殊的統(tǒng)一變量類型

片元著色器輸入和輸出關(guān)系如下圖所示:

因?yàn)楣鈻呕幚砗笸济常瑘D元只是在屏幕上有了像素蹂季,卻沒有進(jìn)行顏色處理,還是看不到東西疏日。

因此FragmentsShader主要的作用是告訴GPU如何處理光照偿洁、陰影、遮擋沟优、環(huán)境等涕滋,然后將結(jié)果輸出到gl_FragColor變量中

FragmentsShader只輸出一個(gè)顏色值——gl_FragColor,是片元著色器內(nèi)置的輸出變量

片元著色器腳本示例:

#version 300 es

precision mediump float; // 設(shè)置精度限定符

in vec4 v_color;

out vec4 fragColor;

void main()

{

fragColor = v_color;

gl_FragColor = fragColor;

}

光柵化階段生成的顏色挠阁、深度宾肺、模板和屏幕坐標(biāo)位置(Xw, Yw)將會變成逐片元操作階段的輸入值

Pre-Fragment Operations:逐片元操作階段

在片元著色器對片元進(jìn)行綜合的處理溯饵,并最終為片元生成一個(gè)顏色值,并儲存在gl_FragColor變量后爱榕,接下來就是逐個(gè)對片元進(jìn)行一些列的測試瓣喊。

光柵化處理時(shí),它由于時(shí)把頂點(diǎn)從世界坐標(biāo)系轉(zhuǎn)換到屏幕坐標(biāo)系黔酥,因此在光柵處理后,每個(gè)片元在屏幕上都有個(gè)坐標(biāo)(Xw, Yw)洪橘。且存儲在了幀緩沖區(qū)(FrameBuffer)跪者,

包括片元著色器也是對(Xw, Yw)這個(gè)坐標(biāo)的片元進(jìn)行處理

Pixel ownership test——像素歸屬測試,它決定FrameBuffer中某個(gè)(Xw, Yw)位置的像素是否屬于當(dāng)前Context

Scissor test——裁剪測試熄求,決定一個(gè)位置(Xw, Yw)的片元是否位于裁剪舉行內(nèi)渣玲,如果不在,則被丟棄

Stencil test/Depth test——模版和深度測試弟晚,傳入片元的模板和深度值忘衍,決定是否丟棄片

Blending——混合,將FragmentShader 新產(chǎn)生的片元顏色值和FrameBuffer中某個(gè)位置(Xw, Yw)的片元存儲的顏色值進(jìn)行混合

Dithering——抖動卿城,對可用顏色較少的系統(tǒng)枚钓,可以犧牲分辨率為代價(jià),通過顏色值的抖動來增加可用顏色值瑟押。抖動操作和硬件相關(guān)搀捷,OpenGL允許程序員所有的操作就只有打開或關(guān)閉都懂操作。默認(rèn)情況下抖動是激活的

在逐片元操作階段的最后多望,片元要么被舍棄嫩舟,要么將顏色、深度怀偷、模板值寫入到幀緩沖區(qū)(Xw, Yw)位置家厌,寫入的值取決于啟用的寫入掩碼

寫入掩碼可以更精細(xì)地控制寫入的顏色、深度椎工、模板值饭于。

備注:Alpha測試和邏輯操作不再是逐片元操作的一部分,這兩個(gè)階段存在于OpenGL2.0盒OpenGL1.x中晋渺。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末镰绎,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子木西,更是在濱河造成了極大的恐慌畴栖,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件八千,死亡現(xiàn)場離奇詭異吗讶,居然都是意外死亡燎猛,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進(jìn)店門照皆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來士嚎,“玉大人,你說我怎么就攤上這事良狈≌抛悖” “怎么了?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵瘟滨,是天一觀的道長候醒。 經(jīng)常有香客問我,道長杂瘸,這世上最難降的妖魔是什么倒淫? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮败玉,結(jié)果婚禮上敌土,老公的妹妹穿的比我還像新娘。我一直安慰自己运翼,他們只是感情好返干,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著南蹂,像睡著了一般犬金。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上六剥,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天晚顷,我揣著相機(jī)與錄音,去河邊找鬼疗疟。 笑死该默,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的策彤。 我是一名探鬼主播栓袖,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼店诗!你這毒婦竟也來了裹刮?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤庞瘸,失蹤者是張志新(化名)和其女友劉穎捧弃,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡违霞,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年嘴办,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片买鸽。...
    茶點(diǎn)故事閱讀 40,561評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡涧郊,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出眼五,到底是詐尸還是另有隱情妆艘,我是刑警寧澤,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布弹砚,位于F島的核電站双仍,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏桌吃。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一苞轿、第九天 我趴在偏房一處隱蔽的房頂上張望茅诱。 院中可真熱鬧,春花似錦搬卒、人聲如沸瑟俭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽摆寄。三九已至,卻和暖如春坯门,著一層夾襖步出監(jiān)牢的瞬間微饥,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工古戴, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留欠橘,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓现恼,卻偏偏與公主長得像肃续,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子叉袍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評論 2 359

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

  • 第三章 管線一覽 本章我們會學(xué)到什么 OpenGL管線的每個(gè)階段做什么的 如果連接著色器和固定功能管線階段 如果創(chuàng)...
    葭五閱讀 6,269評論 2 18
  • 在頂點(diǎn)著色器處理圖元頂點(diǎn)之后進(jìn)入圖元裝配階段始锚。這一階段,執(zhí)行裁剪喳逛、透視分割和Viewport變換操作瞧捌。 光柵化是將...
    cain_huang閱讀 5,368評論 0 4
  • 1 前言 一直想沿著圖像處理這條線建立一套完整的理論知識體系,同時(shí)積累實(shí)際應(yīng)用經(jīng)驗(yàn)艺配。因此有了從使用AVFounda...
    RichardJieChen閱讀 5,677評論 5 12
  • 目錄結(jié)構(gòu): 第一步察郁,明確要干嘛 第二步衍慎,怎么去畫(純理論) 第三步,怎么去畫(實(shí)戰(zhàn)) 第四步皮钠,練練手 第一步稳捆,明確...
    半紙淵閱讀 8,088評論 18 57
  • 一時(shí)興起,聚三五好友麦轰,竟組團(tuán)參加了北歐游乔夯。我們這個(gè)小組,既有夫妻同行款侵,又有姑嫂結(jié)伴末荐,更有同事相攜,真是一個(gè)創(chuàng)...
    鳳落梧桐閱讀 634評論 0 2