OpenGL著色器的簡單介紹

上一節(jié),已經(jīng)可以看見三角形了,一個白色的三角形,顯示在我們正確的頂點(diǎn)位置上,這是怎么出現(xiàn)的呢?

答案就是:如果你沒有提供自己的著色器的話,GPU驅(qū)動會向你提供默認(rèn)的著色器。但這事實(shí)上是基于你的驅(qū)動的。

opengl標(biāo)準(zhǔn)里面沒有內(nèi)容,這實(shí)際上只取決于gpu制造商,它們說,嘿,you know what 如果你不提供著色器,那我們就寫一個最基本的給你,所以你至少可以比較容易一些地調(diào)試你的代碼,或者其它一些別的。

第一個問題,著色器是什么?

著色器基本上只是一個程序,它運(yùn)行在GPU上面,這就是所有了。你應(yīng)該取考慮,當(dāng)你通過程序去考慮著色器時,我的意思是這就像一塊代碼,這塊代碼我們可以在我們的電腦上寫成文本,寫成一個字符串,然后我們可以給opengl,我們可以發(fā)送到顯卡然后像別的程序一樣編譯它,像別的程序一樣鏈接他,像別的程序一樣運(yùn)行,但不同點(diǎn)在于它是運(yùn)行在我們的gpu上,在我們的顯卡上,而不是像C++程序一樣運(yùn)行在cpu上。

所以為什么我們需要實(shí)際運(yùn)行在gpu上的程序,為什么我們不得不寫代碼然后運(yùn)行在gpu上?

很明顯,我們在學(xué)習(xí)圖形編程的相關(guān)內(nèi)容,因此顯卡扮演一個主要角色。
但明確的原因是,我們想要給GPU編程,是因?yàn)槲覀兿胍軌蚋嬖VGPU要做什么,我們想利用GPU的性能去在屏幕上實(shí)際畫出圖形,這不是說我們要做的每一件事都需要在gpu上做,一些東西是CPU更快的。隨著本系列的深入,我們可能會發(fā)現(xiàn)一些我們更喜歡在CPU上做的事情。但不可否認(rèn)的是,有一堆和圖形有關(guān)的事情,GPU運(yùn)行起來會更快,這就是著色器派上用場的地方。

現(xiàn)在不僅僅是我們想從CPU獲取一些東西把它們放到GPU上,而且從根本上說我們需要能夠編程GPU,因?yàn)榧词挂岳L畫的形式,只是畫一個簡單的三角形,我仍然想要能夠告訴GPU如何去畫這個三角形,像是頂點(diǎn)位置在哪,這個三角形的顏色應(yīng)該是什么,應(yīng)該怎么畫,所有的這些東西。當(dāng)我們在一個更加復(fù)雜的3d場景時,光照是一個很好的為什么我們想要編程GPU的例子,光照應(yīng)該如何工作,所有的這些東西,我不想我自己說得太超前,但是所有的這些東西需要去編程,gpu是不知道如何做到這些的。我們需要告訴GPU,我們發(fā)給它的這些數(shù)據(jù)要做什么,這就是著色器的本質(zhì)。

現(xiàn)在這一節(jié)還有對于大多數(shù)openGL和大多數(shù)圖形編程來說,我們需要注意兩種類型的著色器,頂點(diǎn)著色器和片段著色器。片段著色器有時候也叫像素著色器。所以這兩種著色器類型是目前為止(2017)最流行的兩種類型,可能是90%的時間都會用到的類型,還有其它類型的著色器:細(xì)分著色器、幾何著色器,如果你做的和其它事情完全一樣的話,那么這種事情就是計(jì)算著色器。有很多不同類型的著色器,我們不用去考慮這些,現(xiàn)在我們要做的就是頂點(diǎn)著色器和片段著色器,這就是全部。還有更多,當(dāng)你開始學(xué)習(xí)更高級的東西的時候,它們就派上用場了,當(dāng)然這個系列以后我們也會覆蓋到這些類型的著色器,當(dāng)我們需要獲取更復(fù)雜的圖形時。

但是現(xiàn)在,90%的著色器編程,你要解決的都是頂點(diǎn)著色器,片段著色器(像素著色器)。

什么是頂點(diǎn)著色器、片段著色器?為什么它們是兩種類型?我們怎么用它們?

現(xiàn)在我們沒有真正地覆蓋到opengl的管線,或者是一種圖像渲染管線的標(biāo)準(zhǔn),但是粗略地說是如何工作的呢,在你腦海里面應(yīng)該有一副畫面,就是我們在CPU上寫了一大堆數(shù)據(jù),我們把數(shù)據(jù)發(fā)給了GPU,我們發(fā)出了一個調(diào)用,我們綁定了一些狀態(tài),在你開始調(diào)用之前。最后我們進(jìn)入了著色階段,或者更確切的說,GPU開始實(shí)際處理調(diào)用并在屏幕上繪制一些東西。然后我們在屏幕上得到了三角形,這個具體的過程實(shí)際上就是渲染管線。

我們?nèi)绾螐挠袛?shù)據(jù)到屏幕上有結(jié)果呢?

現(xiàn)在,著色器就派上用場了,當(dāng)GPU開始繪制三角形時,頂點(diǎn)著色器和片段著色器四兩種沿著管線不同類型的著色器,所以當(dāng)我們發(fā)出一個繪制調(diào)用。頂點(diǎn)著色器會獲得調(diào)用,片段著色器會get called,然后我們會在屏幕上看到結(jié)果。(為了簡單這樣敘述,其實(shí)在頂點(diǎn)著色器之前有很多階段,在頂點(diǎn)著色器和片段著色器之間以及片段著色器和恢復(fù)階段之間,所有的這些東西)

頂點(diǎn)著色器

頂點(diǎn)著色器:獲取了每一個我們想要渲染的頂點(diǎn)的調(diào)用。這個例子上,我我們有三個頂點(diǎn),這就意味著頂點(diǎn)著色器會調(diào)用三次,每個頂點(diǎn)各一次。一個頂點(diǎn)著色器的基本目的就是告訴opengl你想要那個頂點(diǎn)在顯示器的哪里,簡單的說就是窗口的哪里。在你的電腦上,你有一個窗口開著,這就是你用來渲染圖形的地方。

再次說一下,那里有一個頂點(diǎn)著色器,有些人就會認(rèn)為它像是和光照、陰影或別的的有關(guān),不是的,它只是一個程序,這就是全部了。這甚至于實(shí)際的圖形沒有任何關(guān)系,從傳統(tǒng)圖形的顏色或別的角度來說。無論如何,所有頂點(diǎn)著色器制定了你想要的位置。雖然如此,它也用來解析從屬性到下一個階段的數(shù)據(jù),在我們這個例子里面,下一個階段是片段著色器。頂點(diǎn)著色器實(shí)際上會帶著所有我們指定在緩沖區(qū)里面的頂點(diǎn)的屬性。

片段著色器

(片段和像素在術(shù)語上有一點(diǎn)點(diǎn)不同,但是我們像現(xiàn)在不深入糾結(jié)這個,你可以認(rèn)為片段就是像素)

片段著色器:片段著色器會為每一個像素運(yùn)行一次(thats needs to get rasterized?)光柵化,我說的光柵化實(shí)際上是畫在屏幕上。

我們的窗口實(shí)際上是由像素組成的,他就像一個像素?cái)?shù)組,需要發(fā)生什么,就是我們指定的,組成我們的三角形的三個頂點(diǎn)現(xiàn)在需要去充滿我們的像素,這就是光柵化階段所作的。片段著色器或者是像素著色器會為每一個像素調(diào)用一次,在我們的三角形里面這需要用來去填充,并且我們的片段著色器或者是像素著色器的基本目的就是決定像素的顏色是什么。它就只是為我們的像素決定顏色和輸出的顏色,因此像素可以獲得正確的顏色進(jìn)行著色。可以把它當(dāng)成一本彩色書,里面有一些顏色的輪廓,但你需要給它涂上正確的顏色,這就是片段著色器負(fù)責(zé)的。

頂點(diǎn)著色器和片段著色器的區(qū)別

現(xiàn)在你可以注意到這兩者之間有一點(diǎn)不一樣,頂點(diǎn)著色器調(diào)用三次,片段著色器調(diào)用成百上千次,這取決于我們的三角形在我們的屏幕上占用了多大空間,如果你有一個細(xì)小的三角形,在你的窗口上一個真的很小的三角形,那可能會調(diào)用額外的50次。如果你有一個巨大的三角形,這充滿了你的屏幕,這可能是有一百萬像素或者50萬像素,那就意味著片段著色器要調(diào)用50萬次。

我希望你們從一開始就意識到這一點(diǎn),如果我做5乘以5的事情,等于是我在頂點(diǎn)著色器里面計(jì)算5乘5,然后值是25,這個計(jì)算過程會發(fā)生三次。因?yàn)樵阡秩具@個三角形的過程中,頂點(diǎn)著色器會調(diào)用3次。如果我們有一個大的三角形,我們在片段著色器里面做5乘5的計(jì)算,然后片段著色器會500000次,突然我們做500000次乘法而不是3次,這就是巨大的不同點(diǎn)。

當(dāng)涉及優(yōu)化

當(dāng)涉及到優(yōu)化的時候,想想性能,這其實(shí)是一致存在的,你會開始注意到我應(yīng)該在頂點(diǎn)著色器而不是片段著色器中執(zhí)行一些關(guān)鍵操作,并且你也可以將數(shù)據(jù)從頂點(diǎn)著色器傳遞到片段著色器。這里只是想提一下,只是為了讓你們記住片段著色器里面的東西往往會花銷更多,因?yàn)槠沃魇且o每一個像素運(yùn)行一次的,也就是說很明顯這要給每個像素進(jìn)行計(jì)算。
所以我們喜歡提起以一個很好的例子,這個明確地是帶有片段著色器的例子,就是光照。如果你計(jì)算光照,每一個像素都會有一個顏色值,這取決a number of things,舉個例子,光照、環(huán)境、紋理以及提供給表面的材料,所有的這些東西組合在一起,決定了一個明確的像素的正確顏色。很明顯,這將取決于a number of input,像是相機(jī)的位置在哪里和我說得所有的表面屬性、環(huán)境屬性、所有這些東西組合一起,所有你在片段著色器中決定的,只是一個像素的顏色,這就是片段著色器做的。它是一個程序,它運(yùn)行起來去決定著各像素應(yīng)該是什么顏色,一旦片段說則其計(jì)算了,基本上就會將你的顏色顯示到屏幕上。

小零碎

很多游戲引擎,當(dāng)然還有各種大型游戲引擎,都會根據(jù)游戲中發(fā)生的事情,還有根據(jù)你選擇的實(shí)踐設(shè)置,動態(tài)的生成著色器,所以在游戲引擎中,實(shí)時生成著色器和復(fù)雜化是非常常見的,所以總得來說,你可以用著色器做一大堆很酷的事情。

像opengl中的其它東西一樣,著色器工作是基于機(jī)器的狀態(tài),這意味著當(dāng)你想要實(shí)現(xiàn)一個著色器去畫一個三角形,你想它用某個著色器去畫三角形,你實(shí)現(xiàn)了那個著色器,你可能也會發(fā)送一個數(shù)據(jù)到那個服務(wù)器,就好像我們在一個頂點(diǎn)緩沖前從cpu給GPU發(fā)送頂點(diǎn)數(shù)據(jù),我們也可以用一些叫uniform的東西調(diào)發(fā)送給我們的著色器,這也可以是來自CPU,所以我們設(shè)置了所有狀態(tài)去實(shí)現(xiàn)著色器然后我們畫出了一個三角形。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容