理智的人沒(méi)有品位?

我小時(shí)候想成為任何人,除了我自己?,F(xiàn)在我愛(ài)上了你,然而你心里卻只有上帝。-《蘭陵王的騎士》

不可否認(rèn),OpenGL是一個(gè)只有成績(jī)好的學(xué)生才學(xué)的明白的課程。這也就注定了這是個(gè)小眾知識(shí)的原因。但我們程序員本身這個(gè)職業(yè)又何嘗不是呢。其實(shí)仔細(xì)思考一下,確實(shí)如此,比如我們經(jīng)常討論的問(wèn)題如下:

多目標(biāo)渲染

老絲~~,為什么我運(yùn)行同一個(gè)程序,在Win10上和Win7上的顯示結(jié)果不一樣啊,是不是有什么BUG呀?

實(shí)際上Win10上出問(wèn)題,多半是因?yàn)榧娠@卡的緣故,特別是筆記本,為了省電,在有雙顯卡的情況下,默認(rèn)會(huì)用集成顯卡。集成顯卡我們知道是會(huì)出各種問(wèn)題的,但是我們依舊可以通過(guò)一些手段去規(guī)避這些問(wèn)題。比如當(dāng)我們無(wú)法使用多目標(biāo)渲染的時(shí)候,可以按照我們的課程中多通道渲染的方式解決,也就是渲染多次。

實(shí)際上你可以通過(guò)一些查詢API去獲取當(dāng)前你運(yùn)行的顯卡可以渲染到多少個(gè)ColorBuffer。查詢辦法請(qǐng)參考我們給大家準(zhǔn)備的QuickReferenceCard,你不妨把那個(gè)卡片通讀一遍,自然會(huì)發(fā)現(xiàn)很多有用的東西,我們給大家準(zhǔn)備的課后資料不是隨便亂準(zhǔn)備的。沒(méi)有權(quán)威性的資料肯定不會(huì)給。

主題

理智的人沒(méi)有品位?

實(shí)際上這是個(gè)錯(cuò)誤的命題,藝術(shù)界不存在高低貴賤,誰(shuí)能說(shuō)什么樣的品位算是高的,什么樣的品位算是低的?實(shí)際上沒(méi)幾個(gè)人真正能說(shuō)得清楚。智力水平和見(jiàn)識(shí)不一樣,自然品位不一樣,又何必去在乎大部分臭味相投的人的眼光。

程序員的品位

世界上最強(qiáng)大的語(yǔ)言是PHP,其他的都是垃圾。Python都是些外行學(xué)的,他們不懂什么是真正的愛(ài)情。

OpenGL程序員的品位

寫(xiě)程序根本不在于你用什么語(yǔ)言,真正的樂(lè)趣在于你可以把你學(xué)到的數(shù)學(xué)、物理甚至是柏拉圖式的愛(ài)情都用在程序中。你沒(méi)學(xué)懂OpenGL程序的時(shí)候覺(jué)得他巨繁瑣,當(dāng)你學(xué)懂了它的時(shí)候,你甚至連思考普通程序的架構(gòu)都變得不一樣的,你總會(huì)讓所有可并行的東西并行。

實(shí)際上,學(xué)懂一門(mén)手藝,才能真正體會(huì)設(shè)計(jì)者的思想,這樣會(huì)反過(guò)來(lái)強(qiáng)化你本身的所有編程技能。實(shí)際上這些圖形API的設(shè)計(jì)者的編程思想是學(xué)完OpenGL后最大的收獲,而不僅僅是那幾行C++代碼。

Compute Shader

一切都是可并行的?。。。?!

與其他的Shader有明顯的不一樣,Compute Shader是個(gè)瘋子,其他種類的Shader都是為了完成渲染管線中特定的部分而存在。而Compute Shader完全沒(méi)有什么特定的任務(wù),所以比較符合我們中國(guó)人不按規(guī)矩辦事的風(fēng)格。

image.gif

Compute Shader中既沒(méi)有什么標(biāo)準(zhǔn)的輸入,也沒(méi)有必須規(guī)定的輸出。它的輸入可以是一對(duì)頂點(diǎn),也可以是來(lái)自一張圖片。所以完全可以按照設(shè)計(jì)師的想法來(lái)。

如果你是學(xué)過(guò)Cuda程序設(shè)計(jì)的,那么你會(huì)明白,Compute Shader中,你設(shè)置的那些執(zhí)行用的參數(shù)并不一定可以讓你的算法更快更高效,你必須設(shè)計(jì)一個(gè)合適的值,這個(gè)值取決于你的程序在什么樣的GPU上運(yùn)行。

那么剛才設(shè)置的這些值是指什么呢?是下面這些參數(shù)

  1. 總數(shù)據(jù)塊的大小

  2. 每個(gè)Group的大小

  3. 每次運(yùn)行的數(shù)據(jù)塊的大小

總數(shù)據(jù)塊的大小,這個(gè)也有講究的嗎?答案是肯定的。做過(guò)Cuda程序設(shè)計(jì)的人肯定知道,并不是說(shuō)你調(diào)用的時(shí)候說(shuō)請(qǐng)每次處理5億的數(shù)據(jù),那么Cuda程序就真的每次處理5億個(gè)的。你需要讓你的GPU滿負(fù)荷運(yùn)轉(zhuǎn),這才能讓你的程序最快運(yùn)行。

那么為什么參數(shù)的設(shè)置可以讓GPU變得不是滿負(fù)荷運(yùn)轉(zhuǎn)呢?這就要考慮我們的GPU中的浮點(diǎn)數(shù)運(yùn)算單元了。學(xué)完進(jìn)階課的學(xué)員肯定是知道,我們的GPU是一個(gè)并行運(yùn)算的芯片。我們假設(shè),我現(xiàn)在有一個(gè)GPU,總共有256x256個(gè)核心,我假設(shè)每個(gè)核心每個(gè)GPU時(shí)鐘周期只能做一次浮點(diǎn)運(yùn)算。那么我們?yōu)榱耸沟梦覀僄PU滿負(fù)荷運(yùn)轉(zhuǎn),我們需要讓我們的GPU的執(zhí)行的數(shù)據(jù)塊大小為256x256的,這樣才能保證GPU的核心不會(huì)發(fā)生空轉(zhuǎn)。

如果你設(shè)置的數(shù)據(jù)塊大小太大,那么會(huì)被分批次執(zhí)行,那么總會(huì)有那么幾次,部分GPU核心是空轉(zhuǎn)的。

如果設(shè)置的數(shù)據(jù)塊太小,那么肯定是有GPU在空轉(zhuǎn)的。

但是總體來(lái)說(shuō),使用GPU加速的程序,一般提速都在50~200倍之間。

因此,我們可以看出在做GPU程序設(shè)計(jì)的時(shí)候,數(shù)據(jù)塊的設(shè)計(jì)本身也是一門(mén)技術(shù)。

總數(shù)據(jù)

比如我的總數(shù)據(jù)塊設(shè)計(jì)成為1000x1000,對(duì)于上面的GPU,肯定會(huì)產(chǎn)生空轉(zhuǎn)。

但如果我的總數(shù)據(jù)塊設(shè)計(jì)成為1024x1024,對(duì)于上面的GPU,就可以在此基礎(chǔ)上設(shè)計(jì)出一套讓GPU滿負(fù)荷運(yùn)轉(zhuǎn)的調(diào)度。(因?yàn)?000x1000肯定不是256x256的整數(shù)倍,而1024x1024可以被切割成為整數(shù)個(gè)256x256大小的數(shù)據(jù)塊)

當(dāng)然這都是在極限編程的情況下。

分組

那么Group是哪里設(shè)置的呢?就是下面這個(gè)OpenGL的API

glDispatchCompute(x,y,z)

這個(gè)API就是設(shè)置的總數(shù)據(jù)被分為多少個(gè)Group,這里定義了Group的大小之后,系統(tǒng)就會(huì)自動(dòng)對(duì)總數(shù)據(jù)進(jìn)行分組了,分成若干個(gè)組(Group)。

總的數(shù)據(jù)被分組后,這些分組數(shù)據(jù)被處理的順序是不可預(yù)測(cè)的,也就是說(shuō),你不知道哪一個(gè)分組的數(shù)據(jù)會(huì)被先處理,哪一個(gè)后被處理。這里Group之間是并行的,所以你不能讓分組的數(shù)據(jù)之間產(chǎn)生跨組織的依賴性。

每次執(zhí)行多少數(shù)據(jù)

這里設(shè)置的就是,每一個(gè)Group內(nèi),每次處理多少個(gè)數(shù)據(jù)。那么這個(gè)是哪里設(shè)置的呢?是在Shader中設(shè)置的,大家可以去翻開(kāi)我們的Compute Shader課程中的shader代碼看看

layout(local_size_x=256,local_size_y=256,local_size_z=1) in;

這就是設(shè)置每次我要處理多少個(gè)數(shù)據(jù),上面的設(shè)置是,我每次要處理256x256這么大的數(shù)據(jù)塊。如果我的Group是512x512大小的,那么要處理完畢這個(gè)Group的所有數(shù)據(jù),需要使用Compute Shader對(duì)Group內(nèi)的數(shù)據(jù)迭代4次,每次處理其中一塊256x256大小的數(shù)據(jù)。

關(guān)于TransformFeedbackObject

有很多人一看到這個(gè)玩意就一頭霧水,不知道這是干嘛的。

前不久有一個(gè)同學(xué)跟我們講,骨骼動(dòng)畫(huà)的計(jì)算非常耗時(shí),怎么辦?我們給他的答案就是使用TransformFeedbackObject。實(shí)際上我們光這么講你肯定又不覺(jué)得這靠譜。

但是你們熟悉的游戲引擎Unity中就使用了這個(gè)東西對(duì)骨骼動(dòng)畫(huà)進(jìn)行處理的。不管怎么說(shuō),這種方式是被Unity驗(yàn)證過(guò)的,效果馬馬虎虎還過(guò)得去吧。

這個(gè)技術(shù)是OpenGLES3.0以后的版本就有了的,站在現(xiàn)在這個(gè)時(shí)間節(jié)點(diǎn),覆蓋率是100%。所以不要害怕自己用了特殊的技術(shù),會(huì)不被支持,至少在主流的Android和iOS上是100%被支持的。

最后,我們?cè)谶@里要指出一點(diǎn)的就是,如果有人去百度《蘭陵王的騎士》這本書(shū)了的話,你就徹底的輸了。因?yàn)檫@本書(shū)還沒(méi)有出版。

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

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

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