一步步學(xué)習(xí)計(jì)算機(jī)視覺(jué) in IOS(一)計(jì)算機(jī)視覺(jué)基礎(chǔ)

計(jì)算機(jī)視覺(jué),按字面上理解,就是計(jì)算機(jī)上用來(lái)處理人眼觀測(cè)的技術(shù)。對(duì)于IOS而言,可以簡(jiǎn)單理解為在屏幕上繪制的技術(shù)。

對(duì)IOS App開(kāi)發(fā)而言,在手機(jī)屏幕上展示的是一個(gè)個(gè)UIView,而大多數(shù)同學(xué)了解UIView的繪制是通過(guò)CALayer來(lái)完成的。我們平時(shí)使用的繪制API都是基于這套系統(tǒng)的。但是,對(duì)于硬件而言,圖片實(shí)際上是通過(guò)GPU計(jì)算出渲染數(shù)據(jù),通過(guò)顯卡在屏幕上渲染像素。

對(duì)一般的App而言,CALayer提供的Api足以處理視覺(jué)上的需求,但是對(duì)游戲開(kāi)發(fā),視頻開(kāi)發(fā)而言,手機(jī)屏幕上很少能展示規(guī)則的圖形,而且其UI變化率遠(yuǎn)高于普通App。這時(shí)我們就需要操作底層繪制組件來(lái)進(jìn)行自己的繪制。

OpenGL, OpenGL ES, Metal

OpenGL(Open Graphics Library)是一個(gè)跨編程語(yǔ)言、跨平臺(tái)的編程圖形程序接口,它將計(jì)算機(jī)的資源抽象稱(chēng)為一個(gè)個(gè)OpenGL的對(duì)象,對(duì)這些資源的操作抽象為一個(gè)個(gè)的OpenGL指令。

OpenGL ES(OpenGL for Embedded Systems)是 OpenGL 三維圖形 API 的子集,針對(duì)手機(jī)、PDA和游戲主機(jī)等嵌入式設(shè)備而設(shè)計(jì),去除了許多不必要和性能較低的API接口。

Metal 是一個(gè)是蘋(píng)果出品類(lèi)似的面向底層的圖形編程接口,可以直接操作GPU;支持iOS和OS X,提供圖形渲染和通用計(jì)算能力。蘋(píng)果在ios 13上已經(jīng)不再提供OpenGL ESKit,使用Metal來(lái)替換。

OpenGL

上下文(Context)

上下文Context在Android,UIGraphicsRenderer上都有應(yīng)用,其意義是指執(zhí)行代碼的容器。對(duì)OpenGL而言,Context是指一個(gè)OpenGL狀態(tài)機(jī),在執(zhí)行渲染、變換等視覺(jué)操作之前,需要先初始化這個(gè)容器狀態(tài)機(jī)。這里要注意的是,OpenGL Context十分復(fù)雜,像UIGraphicsRenderer那樣,每次繪制圖片創(chuàng)建一個(gè)上下文不太合適,在實(shí)際應(yīng)用中,系統(tǒng)可能在啟動(dòng)時(shí)初始化許多Context備用。

渲染管線

渲染管線也稱(chēng)為渲染流水線或像素流水線或像素管線,顯示芯片內(nèi)部處理圖形信號(hào)相互獨(dú)立的的并行處理單元。在實(shí)際應(yīng)用中,渲染管線大致可以理解為渲染的步驟:

image.png

首先,我們以數(shù)組的形式傳遞3個(gè)3D坐標(biāo)作為圖形渲染管線的輸入,用來(lái)表示一個(gè)三角形,這個(gè)數(shù)組叫做頂點(diǎn)數(shù)據(jù)(Vertex Data);頂點(diǎn)數(shù)據(jù)是一系列頂點(diǎn)的集合。
當(dāng)其存儲(chǔ)在內(nèi)存時(shí),稱(chēng)為頂點(diǎn)數(shù)組;而其存儲(chǔ)在顯存時(shí),則稱(chēng)為頂點(diǎn)緩存
一個(gè)頂點(diǎn)(Vertex)是一個(gè)3D坐標(biāo)的數(shù)據(jù)的集合。而頂點(diǎn)數(shù)據(jù)是用頂點(diǎn)屬性(Vertex Attribute)表示的,它可以包含任何我們想用的數(shù)據(jù),但是簡(jiǎn)單起見(jiàn),我們還是假定每個(gè)頂點(diǎn)只由一個(gè)3D位置(譯注1)和一些顏色值組成的吧。

1,頂點(diǎn)著色器

它把一個(gè)單獨(dú)的頂點(diǎn)作為輸入。頂點(diǎn)著色器主要的目的是把3D坐標(biāo)轉(zhuǎn)為另一種3D坐標(biāo)(后面會(huì)解釋?zhuān)瑫r(shí)頂點(diǎn)著色器允許我們對(duì)頂點(diǎn)屬性進(jìn)行一些基本處理。

2,圖元裝配階段

將頂點(diǎn)著色器輸出的所有頂點(diǎn)作為輸入(如果是GL_POINTS,那么就是一個(gè)頂點(diǎn)),并所有的點(diǎn)裝配成指定圖元的形狀;

3,幾何著色器

圖元裝配階段的輸出會(huì)傳遞給幾何著色器(Geometry Shader)。幾何著色器把圖元形式的一系列頂點(diǎn)的集合作為輸入,它可以通過(guò)產(chǎn)生新頂點(diǎn)構(gòu)造出新的(或是其它的)圖元來(lái)生成其他形狀。

4,光柵化階段

幾何著色器的輸出會(huì)被傳入光柵化階段(Rasterization Stage),這里它會(huì)把圖元映射為最終屏幕上相應(yīng)的像素,生成供片段著色器(Fragment Shader)使用的片段(Fragment)。在片段著色器運(yùn)行之前會(huì)執(zhí)行裁切(Clipping)。裁切會(huì)丟棄超出你的視圖以外的所有像素,用來(lái)提升執(zhí)行效率。

5,片段著色器

片段著色器的主要目的是計(jì)算一個(gè)像素的最終顏色,這也是所有OpenGL高級(jí)效果產(chǎn)生的地方。通常,片段著色器包含3D場(chǎng)景的數(shù)據(jù)(比如光照、陰影、光的顏色等等),這些數(shù)據(jù)可以被用來(lái)計(jì)算最終像素的顏色。

6,測(cè)試與混合

在所有對(duì)應(yīng)顏色值確定以后,最終的對(duì)象將會(huì)被傳到最后一個(gè)階段,我們叫做Alpha測(cè)試和混合(Blending)階段。這個(gè)階段檢測(cè)片段的對(duì)應(yīng)的深度(和模板(Stencil))值(后面會(huì)講),用它們來(lái)判斷這個(gè)像素是其它物體的前面還是后面,決定是否應(yīng)該丟棄。這個(gè)階段也會(huì)檢查alpha值(alpha值定義了一個(gè)物體的透明度)并對(duì)物體進(jìn)行混合(Blend)。所以,即使在片段著色器中計(jì)算出來(lái)了一個(gè)像素輸出的顏色,在渲染多個(gè)三角形的時(shí)候最后的像素顏色也可能完全不同。

固定管線與可編程管線

固定管線,也可稱(chēng)為可配置管線,其中的繪制渲染的算法不可配置,只能根據(jù)提供的Api進(jìn)行配置。
可編程管線中,渲染算法是由傳入的著色器程序shader來(lái)決定的。

著色器程序shader

Shader其實(shí)就是一段代碼,這段代碼的作用是告訴GPU具體怎樣去繪制模型的每一個(gè)頂點(diǎn)的顏色以及最終每一個(gè)像素點(diǎn)的顏色。
Shader是一段代碼,那必然要用一種語(yǔ)言來(lái)書(shū)寫(xiě)它,目前主流的有三種語(yǔ)言:
1)基于OpenGL的OpenGL Shading Language,簡(jiǎn)稱(chēng)GLSL。
2)基于DirectX的High Level Shading Language,簡(jiǎn)稱(chēng)HLSL。
3)基于C的C for Graphic,簡(jiǎn)稱(chēng)Cg語(yǔ)言
根據(jù)上面中提到的著色器流程,Shader有以下幾種:
1)頂點(diǎn)著色器
圖形有幾個(gè)頂點(diǎn)執(zhí)行有幾次,用于處理理圖形每個(gè)頂點(diǎn)變換(旋轉(zhuǎn)/平移/投影等),坐標(biāo)系變換。
2)幾何著色器
幾何著色器能夠產(chǎn)生0個(gè)以上的基礎(chǔ)圖元,它能起到一定的裁剪作用、同時(shí)也能產(chǎn)生比頂點(diǎn)著色器輸入更多的基礎(chǔ)圖元。
3)(像素)片段著色器
用于繪制圖形中每一個(gè)像素點(diǎn)。

渲染/交換緩沖區(qū)(SwapBuffer)

幀緩沖區(qū)(顯存):是由像素組成的二維數(shù)組,每一個(gè)存儲(chǔ)單元對(duì)應(yīng)屏幕上的一個(gè)像素,整個(gè)幀緩沖對(duì)應(yīng)一幀圖像即當(dāng)前屏幕畫(huà)面。

值得注意的是,如果每個(gè)窗?口只有?一個(gè)緩沖區(qū),那么在繪制過(guò)程中屏幕進(jìn)?行行了了刷新,窗?口可能顯 示出不不完整的圖像。因此引入了交換緩沖區(qū)。

常規(guī)的OpenGL程序?至少都會(huì)有兩個(gè)緩沖區(qū)。顯示在屏幕上的稱(chēng)為屏幕緩沖區(qū),沒(méi)有顯示的稱(chēng)為離屏緩沖區(qū)。在一個(gè)緩沖區(qū)渲染完成之后,通過(guò)將屏幕緩沖區(qū)和離屏緩沖區(qū)交換,實(shí)現(xiàn)圖像 在屏幕上的顯示。交換一般會(huì)等待顯示器器刷新完成的信號(hào),在顯示器器兩次刷新的間隔中進(jìn)?行行交換,這個(gè)信 號(hào)就被稱(chēng)為垂直同步信號(hào),這個(gè)技術(shù)被稱(chēng)為垂直同步。

最后編輯于
?著作權(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)容