我小時候想成為任何人,除了我自己⊥缯眨現(xiàn)在我愛上了你由蘑,然而你心里卻只有上帝。-《蘭陵王的騎士》
不可否認(rèn)代兵,OpenGL是一個只有成績好的學(xué)生才學(xué)的明白的課程纵穿。這也就注定了這是個小眾知識的原因。但我們程序員本身這個職業(yè)又何嘗不是呢奢人。其實仔細(xì)思考一下谓媒,確實如此,比如我們經(jīng)常討論的問題如下:
多目標(biāo)渲染
老絲~~何乎,為什么我運行同一個程序句惯,在Win10上和Win7上的顯示結(jié)果不一樣啊土辩,是不是有什么BUG呀?
實際上Win10上出問題抢野,多半是因為集成顯卡的緣故拷淘,特別是筆記本,為了省電指孤,在有雙顯卡的情況下启涯,默認(rèn)會用集成顯卡。集成顯卡我們知道是會出各種問題的恃轩,但是我們依舊可以通過一些手段去規(guī)避這些問題结洼。比如當(dāng)我們無法使用多目標(biāo)渲染的時候,可以按照我們的課程中多通道渲染的方式解決叉跛,也就是渲染多次松忍。
實際上你可以通過一些查詢API去獲取當(dāng)前你運行的顯卡可以渲染到多少個ColorBuffer。查詢辦法請參考我們給大家準(zhǔn)備的QuickReferenceCard筷厘,你不妨把那個卡片通讀一遍鸣峭,自然會發(fā)現(xiàn)很多有用的東西,我們給大家準(zhǔn)備的課后資料不是隨便亂準(zhǔn)備的酥艳。沒有權(quán)威性的資料肯定不會給摊溶。
主題
理智的人沒有品位?
實際上這是個錯誤的命題充石,藝術(shù)界不存在高低貴賤莫换,誰能說什么樣的品位算是高的,什么樣的品位算是低的赫冬?實際上沒幾個人真正能說得清楚浓镜。智力水平和見識不一樣溃列,自然品位不一樣劲厌,又何必去在乎大部分臭味相投的人的眼光。
程序員的品位
世界上最強大的語言是PHP听隐,其他的都是垃圾补鼻。Python都是些外行學(xué)的,他們不懂什么是真正的愛情雅任。
OpenGL程序員的品位
寫程序根本不在于你用什么語言风范,真正的樂趣在于你可以把你學(xué)到的數(shù)學(xué)、物理甚至是柏拉圖式的愛情都用在程序中沪么。你沒學(xué)懂OpenGL程序的時候覺得他巨繁瑣硼婿,當(dāng)你學(xué)懂了它的時候,你甚至連思考普通程序的架構(gòu)都變得不一樣的禽车,你總會讓所有可并行的東西并行寇漫。
實際上刊殉,學(xué)懂一門手藝,才能真正體會設(shè)計者的思想州胳,這樣會反過來強化你本身的所有編程技能记焊。實際上這些圖形API的設(shè)計者的編程思想是學(xué)完OpenGL后最大的收獲,而不僅僅是那幾行C++代碼栓撞。
Compute Shader
一切都是可并行的1槟ぁ!H肯妗F奥!
與其他的Shader有明顯的不一樣岭粤,Compute Shader是個瘋子惜索,其他種類的Shader都是為了完成渲染管線中特定的部分而存在。而Compute Shader完全沒有什么特定的任務(wù)剃浇,所以比較符合我們中國人不按規(guī)矩辦事的風(fēng)格巾兆。
Compute Shader中既沒有什么標(biāo)準(zhǔn)的輸入,也沒有必須規(guī)定的輸出虎囚。它的輸入可以是一對頂點角塑,也可以是來自一張圖片。所以完全可以按照設(shè)計師的想法來淘讥。
如果你是學(xué)過Cuda程序設(shè)計的圃伶,那么你會明白,Compute Shader中蒲列,你設(shè)置的那些執(zhí)行用的參數(shù)并不一定可以讓你的算法更快更高效窒朋,你必須設(shè)計一個合適的值,這個值取決于你的程序在什么樣的GPU上運行蝗岖。
那么剛才設(shè)置的這些值是指什么呢侥猩?是下面這些參數(shù)
總數(shù)據(jù)塊的大小
每個Group的大小
每次運行的數(shù)據(jù)塊的大小
總數(shù)據(jù)塊的大小,這個也有講究的嗎抵赢?答案是肯定的欺劳。做過Cuda程序設(shè)計的人肯定知道,并不是說你調(diào)用的時候說請每次處理5億的數(shù)據(jù)铅鲤,那么Cuda程序就真的每次處理5億個的划提。你需要讓你的GPU滿負(fù)荷運轉(zhuǎn),這才能讓你的程序最快運行邢享。
那么為什么參數(shù)的設(shè)置可以讓GPU變得不是滿負(fù)荷運轉(zhuǎn)呢鹏往?這就要考慮我們的GPU中的浮點數(shù)運算單元了。學(xué)完進(jìn)階課的學(xué)員肯定是知道骇塘,我們的GPU是一個并行運算的芯片伊履。我們假設(shè)袜漩,我現(xiàn)在有一個GPU,總共有256x256個核心湾碎,我假設(shè)每個核心每個GPU時鐘周期只能做一次浮點運算宙攻。那么我們?yōu)榱耸沟梦覀僄PU滿負(fù)荷運轉(zhuǎn),我們需要讓我們的GPU的執(zhí)行的數(shù)據(jù)塊大小為256x256的介褥,這樣才能保證GPU的核心不會發(fā)生空轉(zhuǎn)座掘。
如果你設(shè)置的數(shù)據(jù)塊大小太大,那么會被分批次執(zhí)行柔滔,那么總會有那么幾次溢陪,部分GPU核心是空轉(zhuǎn)的。
如果設(shè)置的數(shù)據(jù)塊太小睛廊,那么肯定是有GPU在空轉(zhuǎn)的形真。
但是總體來說,使用GPU加速的程序超全,一般提速都在50~200倍之間咆霜。
因此,我們可以看出在做GPU程序設(shè)計的時候嘶朱,數(shù)據(jù)塊的設(shè)計本身也是一門技術(shù)蛾坯。
總數(shù)據(jù)
比如我的總數(shù)據(jù)塊設(shè)計成為1000x1000,對于上面的GPU疏遏,肯定會產(chǎn)生空轉(zhuǎn)脉课。
但如果我的總數(shù)據(jù)塊設(shè)計成為1024x1024,對于上面的GPU财异,就可以在此基礎(chǔ)上設(shè)計出一套讓GPU滿負(fù)荷運轉(zhuǎn)的調(diào)度倘零。(因為1000x1000肯定不是256x256的整數(shù)倍,而1024x1024可以被切割成為整數(shù)個256x256大小的數(shù)據(jù)塊)
當(dāng)然這都是在極限編程的情況下戳寸。
分組
那么Group是哪里設(shè)置的呢呈驶?就是下面這個OpenGL的API
glDispatchCompute(x,y,z)
這個API就是設(shè)置的總數(shù)據(jù)被分為多少個Group,這里定義了Group的大小之后庆揩,系統(tǒng)就會自動對總數(shù)據(jù)進(jìn)行分組了俐东,分成若干個組(Group)享潜。
總的數(shù)據(jù)被分組后疯趟,這些分組數(shù)據(jù)被處理的順序是不可預(yù)測的迄委,也就是說,你不知道哪一個分組的數(shù)據(jù)會被先處理锈拨,哪一個后被處理。這里Group之間是并行的羹唠,所以你不能讓分組的數(shù)據(jù)之間產(chǎn)生跨組織的依賴性奕枢。
每次執(zhí)行多少數(shù)據(jù)
這里設(shè)置的就是娄昆,每一個Group內(nèi),每次處理多少個數(shù)據(jù)缝彬。那么這個是哪里設(shè)置的呢萌焰?是在Shader中設(shè)置的,大家可以去翻開我們的Compute Shader課程中的shader代碼看看
layout(local_size_x=256,local_size_y=256,local_size_z=1) in;
這就是設(shè)置每次我要處理多少個數(shù)據(jù)谷浅,上面的設(shè)置是扒俯,我每次要處理256x256這么大的數(shù)據(jù)塊。如果我的Group是512x512大小的一疯,那么要處理完畢這個Group的所有數(shù)據(jù)撼玄,需要使用Compute Shader對Group內(nèi)的數(shù)據(jù)迭代4次,每次處理其中一塊256x256大小的數(shù)據(jù)墩邀。
關(guān)于TransformFeedbackObject
有很多人一看到這個玩意就一頭霧水掌猛,不知道這是干嘛的。
前不久有一個同學(xué)跟我們講眉睹,骨骼動畫的計算非常耗時荔茬,怎么辦?我們給他的答案就是使用TransformFeedbackObject竹海。實際上我們光這么講你肯定又不覺得這靠譜兔院。
但是你們熟悉的游戲引擎Unity中就使用了這個東西對骨骼動畫進(jìn)行處理的。不管怎么說站削,這種方式是被Unity驗證過的坊萝,效果馬馬虎虎還過得去吧。
這個技術(shù)是OpenGLES3.0以后的版本就有了的许起,站在現(xiàn)在這個時間節(jié)點十偶,覆蓋率是100%。所以不要害怕自己用了特殊的技術(shù)园细,會不被支持惦积,至少在主流的Android和iOS上是100%被支持的。
最后猛频,我們在這里要指出一點的就是狮崩,如果有人去百度《蘭陵王的騎士》這本書了的話,你就徹底的輸了鹿寻。因為這本書還沒有出版睦柴。