前言
計(jì)算機(jī)圖形學(xué)是一門(mén)很有趣的學(xué)科,但是它涉及的知識(shí)面太廣,不僅包含軟件方面還有硬件方面也有滲透汞斧。而對(duì)于軟件開(kāi)發(fā)來(lái)說(shuō)滔驶,學(xué)習(xí)OpenGL無(wú)疑是接近計(jì)算機(jī)圖形學(xué)的最便捷方式遇革。
從這篇文章開(kāi)始,會(huì)出一系列OpenGL的文章揭糕,還包括了移動(dòng)開(kāi)發(fā)中的OpenGL ES萝快、Metal。文章的目的很簡(jiǎn)單著角,就是作為一種筆記來(lái)復(fù)習(xí)從OpenGL到OpenGL ES學(xué)習(xí)中的知識(shí)點(diǎn)揪漩,筆記實(shí)際應(yīng)用開(kāi)發(fā)中能否用到OpenGL也得看業(yè)務(wù)需求。同時(shí)也希望能夠幫助到還未入門(mén)的小伙伴吏口。
在文章中奄容,如果出現(xiàn)了一些知識(shí)點(diǎn)有錯(cuò)誤冰更、或是有遺漏的地方,希望小伙伴們能夠在文章末尾留言指出嫩海,不勝感激冬殃。
本文主要講述OpenGL的基礎(chǔ)知識(shí),包括它的應(yīng)用叁怪、子集审葬、部分專(zhuān)業(yè)名稱(chēng)、固定管線奕谭、可編程管線等涣觉。從下篇文章開(kāi)始編碼,動(dòng)手去繪制一些圖元血柳、圖形等官册。
學(xué)習(xí)過(guò)程中參考書(shū)籍:《OpenGL超級(jí)寶典 第5版》、《3D數(shù)學(xué)基礎(chǔ):圖形與游戲開(kāi)發(fā)》难捌、《OpenGL ES 3.0》膝宁。其中3D數(shù)學(xué)只需看前9章。
一根吁、OpenGL是什么
1.OpenGL
用一句話概括员淫,OpenGL是一個(gè)代碼庫(kù)。它是基于C語(yǔ)言開(kāi)發(fā)的一組可跨平臺(tái)的圖形API击敌,它是程序員最接近GPU的方式介返,它是界面渲染的主要成員,它肩負(fù)著圖形圖像顯示到屏幕上的重任沃斤。但OpenGL從本質(zhì)上講圣蝎,還是一個(gè)代碼庫(kù),只不過(guò)我們不僅要會(huì)用它衡瓶,還要了解圖形的渲染流程徘公。
2.DirectX
DirectX是與OpenGL齊名的另一組庫(kù),能做OpenGL做的事哮针。它活躍在PC上关面,且只支持windows系統(tǒng),這里知道下就OK诚撵,畢竟筆者也不怎么了解DirectX缭裆。
3.OpenGL ES
從命名上看多少能猜出它和OpenGL的關(guān)系,沒(méi)錯(cuò)寿烟,OpenGL ES是OpenGL的子集澈驼,活躍在移動(dòng)端,目前Android和iOS的渲染都用到了OpenGL ES筛武。不過(guò)蘋(píng)果總有些騷操作缝其,在2014年開(kāi)始布局Metal挎塌,到2018年宣布3D圖形用Matal渲染,據(jù)說(shuō)能提高10倍的渲染速度内边,我相信是真的??榴都。目前比較流行的flutter,2D渲染用的是skia漠其,3D渲染用的是OpenGL ES嘴高。對(duì)于移動(dòng)開(kāi)發(fā)者來(lái)說(shuō),掌握OpenGL ES還是利好的和屎。
二拴驮、OpenGL中的專(zhuān)業(yè)名詞
OpenGL中的專(zhuān)業(yè)名詞有很多,這里只列舉比較常見(jiàn)的五個(gè)名詞:光柵化柴信、紋理套啤、著色器、顏色混合随常、深度測(cè)試潜沦。直接去理解這些名詞其實(shí)是不好理解的,而且這里沒(méi)有涉及到上下文所以如果理解上有困難是正常的绪氛,在后面會(huì)將這些名詞代表的過(guò)程連串起來(lái)唆鸡,那時(shí)才能真正理解它們的意義,這里只是預(yù)理解钞楼。
1.光柵化
OpenGL中組成圖像的基本圖元有點(diǎn)喇闸、線袄琳、三角形询件、線帶、線環(huán)唆樊、三角帶宛琅、三角環(huán),但最終還是由點(diǎn)逗旁、線嘿辟、三角形組成。那么當(dāng)你給出三個(gè)不在同一直線上的點(diǎn)讓OpenGL去繪制一個(gè)三角形時(shí)片效,三角形范圍內(nèi)點(diǎn)的位置計(jì)算的過(guò)程叫光柵化红伦,這是用通俗的語(yǔ)言來(lái)描述的。
專(zhuān)業(yè)一點(diǎn)的解釋?zhuān)?br> ? 光柵化是把頂點(diǎn)數(shù)據(jù)轉(zhuǎn)換為?元的過(guò)程淀衣,具有將圖轉(zhuǎn)化為?個(gè)個(gè)柵格組成的圖象的作?昙读,特點(diǎn)是每個(gè)元素對(duì)應(yīng)幀緩沖區(qū)中的?像素。
? 光柵化就是把頂點(diǎn)數(shù)據(jù)轉(zhuǎn)換為?元的過(guò)程膨桥。?元中的每?個(gè)元素對(duì)應(yīng)于幀緩沖區(qū)中的?個(gè)像素蛮浑。
? 光柵化其實(shí)是?種將?何圖元變?yōu)?維圖像的過(guò)程唠叛。該過(guò)程包含了兩部分的?作。第?部分?作:決定窗?坐標(biāo)中的哪些整型柵格區(qū)域被基本圖元占?沮稚;第?部分?作:分配?個(gè)顏?值和?個(gè)深度值到各個(gè)區(qū)域艺沼。光柵化過(guò)程產(chǎn)?的是?元。
? 把物體的數(shù)學(xué)描述以及與物體相關(guān)的顏?信息轉(zhuǎn)換為屏幕上?于對(duì)應(yīng)位置的像素及?于填充像素的顏?蕴掏,這個(gè)過(guò)程稱(chēng)為光柵化障般,這是?個(gè)將模擬信號(hào)轉(zhuǎn)化為離散信號(hào)的過(guò)程。
如果看到這里還是一頭污水盛杰,沒(méi)有關(guān)系剩拢,繼續(xù)往后,能找到你想要的答案饶唤。
2.紋理
如果說(shuō)紋理你不好理解徐伐,那我說(shuō)個(gè)你肯定知道的,那就是圖片募狂。沒(méi)錯(cuò)办素,紋理你可以理解成就是圖片,只不過(guò)OpenGL中通常稱(chēng)為紋理祸穷。
3.著色器
著色器性穿,對(duì)圖形的頂點(diǎn)以及光柵化之后的片元進(jìn)行位置顏色計(jì)算的程序。固定管線下有多種著色器雷滚,具體可以參考這篇文章http://www.reibang.com/p/8005dcd0dec7需曾。在這里我簡(jiǎn)單說(shuō)下頂點(diǎn)著色器和片元著色器,而這兩種著色器也是我們唯一能夠編程的著色器祈远。
a.頂點(diǎn)著色器
顧名思義呆万,頂點(diǎn)著色器是對(duì)圖形的頂點(diǎn)進(jìn)行計(jì)算的,包括平移车份、旋轉(zhuǎn)谋减、縮放等矩陣變換的計(jì)算。例如扫沼,一個(gè)三角形發(fā)生一次旋轉(zhuǎn)出爹,頂點(diǎn)著色器會(huì)對(duì)其進(jìn)行3次計(jì)算,三角形有三個(gè)頂點(diǎn)缎除,就是這個(gè)原因严就。總的來(lái)講器罐,頂點(diǎn)著色器用來(lái)對(duì)頂點(diǎn)的一些屬性進(jìn)行計(jì)算梢为。
b.片元著色器
片元可以理解成像素,也就是圖形上每一個(gè)像素點(diǎn)。而片元著色器是對(duì)每一個(gè)像素點(diǎn)進(jìn)行計(jì)算的抖誉。光柵化過(guò)程將頂點(diǎn)轉(zhuǎn)化成了片元殊轴,例如,將一個(gè)三角形內(nèi)部的每個(gè)點(diǎn)的坐標(biāo)和顏色值計(jì)算出來(lái)后交給了片元著色器袒炉,這時(shí)就開(kāi)始了片元著色器的操作旁理。制作濾鏡就是在片元著色器程序中完成的,利用顏色混合我磁,達(dá)到不同的濾鏡效果孽文。
注意:由于一個(gè)圖形可能是多個(gè)三角形組成,而每個(gè)圖形內(nèi)部的像素點(diǎn)特別多夺艰,如果是串行去出來(lái)每個(gè)點(diǎn)的計(jì)算芋哭,那么對(duì)于用戶(hù)將是一場(chǎng)災(zāi)難,因?yàn)槟憧赡苄枰却龜?shù)秒才能看到屏幕成像郁副。GPU對(duì)頂點(diǎn)减牺、片元的計(jì)算都是并行的,這也是它擅長(zhǎng)的工作存谎。
4.顏色混合
顏色混合是將不同的顏色值通過(guò)一些算法拔疚,最終得到一個(gè)顏色值。比如rgba(0.4, 0.5, 0.6, 0.4)和rgba(0.6, 0.1, 0.0, 0.7)進(jìn)行混合既荚,可能得到rgba(0.55, 0.3, 0.2, 0.56)稚失,這個(gè)結(jié)果是隨便寫(xiě)的,僅限方便理解恰聘。通過(guò)顏色混合我們可以實(shí)現(xiàn)不同的濾鏡句各,圖片灰度、馬賽克等晴叨。顏色混合一般發(fā)生在片元著色器中凿宾。
5.深度測(cè)試
深度測(cè)試用一句容易理解的說(shuō)話來(lái)概述,它就是3D空間坐標(biāo)(x,y,z)中的z值篙螟。屏幕是二維的菌湃,如何渲染3D圖形问拘,使那些圖形看起來(lái)像3D遍略,就需要開(kāi)啟深度測(cè)試,這樣OpenGL通過(guò)投影算法骤坐,將z值參與計(jì)算绪杏,才能達(dá)到3D的效果∨ι埽總的來(lái)說(shuō)蕾久,深度測(cè)試就是讓圖形每個(gè)點(diǎn)坐標(biāo)(x,y,z)中的z有意義,否則不管設(shè)置z是多少拌夏,它都會(huì)被當(dāng)做0處理僧著。
三履因、管線渲染流程
管線,初次見(jiàn)到這個(gè)名詞其實(shí)是很難理解的盹愚,但是我們用另一個(gè)大家都熟悉的詞來(lái)描述栅迄,流水線。對(duì)皆怕,管線就像流水線一樣毅舆,每一步都已經(jīng)設(shè)計(jì)好了,GPU按照固定的流程去渲染圖形愈腾。有些工廠流水線上全是機(jī)器操作不需要人為干預(yù)憋活,這種叫固定管線;還有一些部分流程可以讓人去干預(yù)虱黄,這種叫可編程管線悦即。OpenGL中的可編程管線就是頂點(diǎn)著色器和片元著色器。我們來(lái)看一看管線的渲染流程橱乱,從頂點(diǎn)著色器到片元著色器盐欺,如圖1所示。
以一個(gè)三角形為例仅醇,從可編程管線的流程出發(fā)冗美,一起看看我們能做的是什么。
畫(huà)一個(gè)三角形需要傳入三角形的三個(gè)頂點(diǎn)析二,傳給頂點(diǎn)著色器之后粉洼,頂點(diǎn)著色器是可編程的,所以這里我們可以對(duì)其進(jìn)行操作叶摄。比如圖片翻轉(zhuǎn)中属韧,改變頂點(diǎn)和紋理坐標(biāo)的對(duì)應(yīng)關(guān)系可實(shí)現(xiàn)圖片翻轉(zhuǎn)。
頂點(diǎn)著色器到片元著色器中間的過(guò)程我們是無(wú)法改變的蛤吓,他們是固定管線宵喂,到了片元著色器也是可編程的。在片元著色器中会傲,需要計(jì)算每個(gè)片元對(duì)應(yīng)的顏色锅棕,這時(shí)片元著色器會(huì)從頂點(diǎn)的顏色值去取,或者從紋理中取淌山。這一步也是可以編程的裸燎,在這一步我們可以實(shí)現(xiàn)不同的濾鏡效果,上面已經(jīng)說(shuō)過(guò)很多次了泼疑。
總結(jié)
這一篇文章主要是簡(jiǎn)單介紹了OpenGL相關(guān)的知識(shí)德绿,以及講述了濾鏡實(shí)現(xiàn)的可行性。后續(xù)開(kāi)始OpenGL的圖元繪制,從下一篇文章開(kāi)始將加入繪制的部分代碼移稳。