入門(mén)AR,VR,OpenGL必備知識(shí)--3D圖形學(xué)基礎(chǔ)理論

引言

請(qǐng)不要質(zhì)疑你的眼睛,文章的題目就是“3D圖形學(xué)基礎(chǔ)理論”。可能有人要疑惑了,作為一個(gè) iOS 開(kāi)發(fā)者為什么要來(lái)學(xué)習(xí)什么 3D 圖像學(xué)相關(guān)的東西,莫非這是要轉(zhuǎn)行的節(jié)奏。開(kāi)玩笑,怎么可能呢? 作為一個(gè)對(duì)技術(shù)有追求的人,怎么可能轉(zhuǎn)行。接下來(lái)讓我告訴你,為什么要學(xué)習(xí)3D圖形學(xué)的一些基礎(chǔ)理論。

  • 1、遠(yuǎn)的先不說(shuō),就拿 iOS來(lái)說(shuō)。iOS 中在做一些基本動(dòng)畫(huà)開(kāi)發(fā)的過(guò)程中,相信絕大多數(shù)開(kāi)發(fā)者都是用過(guò) Core Graphics 框架中的 CGAffineTransform 這個(gè)類,雖然只是普通的平面動(dòng)畫(huà),但其實(shí)現(xiàn)原理和 3D 圖形學(xué)中的矩陣很類似。有多少開(kāi)發(fā)者想過(guò)其中的各種動(dòng)畫(huà)效果諸如縮放、旋轉(zhuǎn)、平移等是如何做到的?
  • 2、當(dāng)然看到CGAffineTransform這個(gè)類,自然很容易想到CATransform3D這個(gè)類,這里既然是3D動(dòng)畫(huà),肯定和3D圖形學(xué)有關(guān)了。
  • 3、再說(shuō)一個(gè)很火的名詞 AR,Apple 已經(jīng)讓一部分開(kāi)發(fā)者早先接觸了 ARKit 。ARKit 在接下來(lái)的一段時(shí)間中必然會(huì)很火。其實(shí)簡(jiǎn)單用 ARKit 實(shí)現(xiàn)一個(gè) AR 的 Demo 很簡(jiǎn)單,因?yàn)?蘋(píng)果封裝的 ARKit 十分簡(jiǎn)單易用。學(xué)習(xí)ARKit重點(diǎn)在于理解 ARKit 中各個(gè)類的關(guān)系、運(yùn)行原理。其中運(yùn)行原理就涉及到 3D 圖像學(xué)相關(guān)的知識(shí)。
  • 4、說(shuō)到AR,自然會(huì)想到VR,VR全景視頻、全景圖片自然也會(huì)涉及到3D場(chǎng)景。
  • 5、除此之外,還有 OpenGL ,當(dāng)然這個(gè)屬于相對(duì)比較片底層的技術(shù)了。iOS 中的各種控件的底層再底層都是基于其實(shí)現(xiàn)的。AR、VR技術(shù)都和其脫不了干系。筆者目前所在的公司,就有一套公司自己的OpenGL繪圖引擎,基于高德地圖在地圖上繪制各種各樣的炫酷模型。
  • 6、還有蘋(píng)果的3D游戲開(kāi)發(fā)框架ScenceKit,毫無(wú)疑問(wèn)會(huì)涉及。
    除了上述所講到的這些,3D 圖像學(xué)在實(shí)際開(kāi)發(fā)中涉及了還有很多。所以還是有必要稍稍了解下。學(xué)一些大學(xué)的高數(shù)知識(shí)。

一、3D成像原理

三維(3D)這個(gè)術(shù)語(yǔ)表示顯示的物體具有三個(gè)維度:寬度、高度和深度。如放在書(shū)桌上的紙張是一個(gè)二維物體,因?yàn)樗鼪](méi)有讓人感覺(jué)到所謂的深度。而一罐可口可樂(lè)放在桌上卻是有一定的深度。

幾個(gè)世紀(jì)以來(lái),藝術(shù)家已經(jīng)知道如何讓一幅畫(huà)看上去有深度。本質(zhì)上來(lái)說(shuō),畫(huà)其實(shí)是一個(gè)二維物體,只是顯示在計(jì)算機(jī)屏幕上的二維圖像或畫(huà)板上的水墨,但是卻可以提供深度的錯(cuò)覺(jué)。

有這樣一個(gè)公式:2D + 透視 = 3D 通過(guò)下面這幅圖,就可以看懂這個(gè)公式。我們可以看到 12 條線段組成了一個(gè)三維立方體的圖像。

實(shí)際上為了真正的看到 3D 圖像需要用兩個(gè)眼睛觀察一個(gè)物體或者為每只眼睛分別提供某個(gè)特定物體的一副獨(dú)立而又唯一角度的圖像。實(shí)際上人的每一只眼睛看到的是一副獨(dú)立的二維圖像,非常類似于每個(gè)視網(wǎng)膜(位于眼睛的后半部分)上顯示了一副臨時(shí)照片。隨后大腦對(duì)這兩幅圖像進(jìn)行圖像組合,在腦海中形成一副合成的 3D 圖片。中所周知現(xiàn)在的iPhone基本都是雙攝像頭,蘋(píng)果之所以早在 iPhone7 Plus 就增加了雙攝,其實(shí)那時(shí)已經(jīng)是在為AR埋下伏筆了。因?yàn)橥搜垡粯樱瑸榱俗R(shí)別 3D 場(chǎng)景,AR 需要雙攝像頭的硬件設(shè)備。那些不在雙攝像頭的硬件上運(yùn)行AR場(chǎng)景的在筆者認(rèn)為是偽 AR ,因?yàn)楣P者認(rèn)為AR的核心是在于場(chǎng)景的識(shí)別和分析,而這一點(diǎn)就要依賴于雙攝;再說(shuō)一個(gè)典型的例子,VR 應(yīng)用的頭盔,一般都會(huì)分為左右屏,左右屏的實(shí)時(shí)圖片或視頻場(chǎng)景是有一定視角差的,正式基于此,佩戴頭盔的玩家才能體驗(yàn)到 3D 場(chǎng)景。

單憑透視本身就足以創(chuàng)建三維的外觀,但是如果長(zhǎng)時(shí)間盯著上面的立方體看的話,會(huì)產(chǎn)生線條錯(cuò)亂的幻覺(jué)。我們?nèi)绻檬终谧∫恢谎劬θタ船F(xiàn)實(shí)世界,仍然是三維的,也不會(huì)產(chǎn)生錯(cuò)亂的幻覺(jué),這是因?yàn)楝F(xiàn)實(shí)世界中有關(guān)。如果上面的立方體通過(guò)紋理貼圖、光照效果處理等就不會(huì)再產(chǎn)生錯(cuò)亂的感覺(jué)。

二、3D編程基本原則

2.1 坐標(biāo)系統(tǒng)

笛卡爾坐標(biāo)系統(tǒng)相信很多人都了解,被熟悉的主要有 2D 和 3D 笛卡爾坐標(biāo)系。關(guān)于這兩個(gè)坐標(biāo)系統(tǒng)不用做過(guò)多解釋,很容易理解。這里我主要想說(shuō)兩個(gè)概念坐標(biāo)裁剪和視口。

  • 坐標(biāo)裁剪
    窗口(電腦屏幕)是以像素為單位度量的。開(kāi)始在窗口繪制點(diǎn)、線或形狀之前,必須告訴編程框架如何把制定的坐標(biāo)翻譯為屏幕坐標(biāo)。我們可以通過(guò)指定占據(jù)窗口的笛卡爾控件區(qū)域完成這個(gè)任務(wù),這個(gè)區(qū)域就稱為裁剪區(qū)域。如下圖顯示了兩種常見(jiàn)的裁剪區(qū)域。
  • 視口: 把繪圖左邊映射到窗口坐標(biāo)
    裁剪區(qū)域的寬度和高度很少和窗口的寬度或高度相匹配(以像素為單位)。因此,坐標(biāo)系統(tǒng)必須從笛卡爾坐標(biāo)系映射到物理屏幕像素坐標(biāo)。這個(gè)映射就是通過(guò)視口的設(shè)置來(lái)指定的。視口就是窗口內(nèi)部用于繪制裁剪區(qū)域的客戶端區(qū)域。視口簡(jiǎn)單的把裁剪區(qū)域映射到窗口的一個(gè)區(qū)域。通常視口被定義為整個(gè)窗口,但這并非是嚴(yán)格的。如下面兩幅圖所示,視口分別被定義為裁剪區(qū)域的兩倍、與裁剪區(qū)域相同的大小。

2.2 從3D到2D(投影)

不管我們覺(jué)得自己的眼睛看到的三維圖像有多么真實(shí),但是屏幕上的像素實(shí)際上是二維的。所以我們要理解的第一個(gè)概念是投影。通過(guò)指定投影,可以指定在窗口的視景體,并制定如何對(duì)它進(jìn)行變換。投影主要分為兩種:正投影和透視投影。

如下圖所示,兩種投影方式,一種是平行投影也叫作正投影,正投影的特點(diǎn)是所有的投影線都是平行的,另外一種則是透視投影,透視投影的特點(diǎn)是投影線是相交于一點(diǎn)的,相交于這個(gè)點(diǎn)叫做投影中心。這一點(diǎn)在現(xiàn)實(shí)生活中可以得到很好的驗(yàn)證,想想此刻你順著平行的火車軌道望去,會(huì)發(fā)現(xiàn)隨著距離的增加,火車的軌道原來(lái)越靠近。在后面我會(huì)專門(mén)抽出一個(gè)模塊來(lái)說(shuō)一下透視投影的幾何原理,這里暫時(shí)知道即可。

正投影和透視投影

三、向量

3.1 向量基本介紹

說(shuō)道這里就涉及到一些數(shù)學(xué)知識(shí)了,不要害怕,我會(huì)結(jié)合實(shí)際的空間來(lái)說(shuō),高等數(shù)學(xué)中關(guān)于向量和矩陣的知識(shí)并不是那么的難。實(shí)際上作為開(kāi)發(fā)者的我們也只要掌握一些基礎(chǔ)的便足夠。

3D 笛卡爾坐標(biāo)系中的一個(gè)點(diǎn),是通過(guò)三個(gè)值如(x,y,z)來(lái)表示的。這三個(gè)值組合起來(lái)實(shí)際上表示兩個(gè)重要的值:方向數(shù)量。如下圖所示的(X,Y,Z)實(shí)際上表示了一個(gè)方向,方向是朝箭頭方向。一個(gè)向量的數(shù)量就是這個(gè)向量的長(zhǎng)度。對(duì)于 x 軸向量(1,0,0)來(lái)說(shuō),向量長(zhǎng)度是 1。我們把長(zhǎng)度為 1 的向量稱為單位向量。

OpenGL 中的 math3d 庫(kù)有這樣的兩個(gè)數(shù)據(jù)類型M3DVector3f 和 M3DVector4f 。前者是一個(gè)三維向量(x,y,z);后者是一個(gè)四維向量(x,y,z,w),典型情況下 w 值為 1.0 ,x、y、z 值通過(guò)除以 w 進(jìn)行縮放。明明就是 3D 圖形學(xué),又不是 4D 圖像學(xué),為何要使用 4 個(gè)分量來(lái)表示一個(gè)向量 ?之所以這樣做是因?yàn)?3D 頂點(diǎn)變化是要乘以一個(gè) 4 * 4 的變換矩陣。有個(gè)規(guī)則是必須用一個(gè)四分量向量乘以一個(gè) 4 * 4 的矩陣,后面講到矩陣時(shí)會(huì)詳細(xì)說(shuō)明。

3.2 向量的運(yùn)算

向量可以進(jìn)行加法、減法運(yùn)算,也可以簡(jiǎn)單的通過(guò)減法、減法進(jìn)行縮放。然而這里主要說(shuō)關(guān)于向量有趣的兩個(gè)運(yùn)算: 點(diǎn)乘和叉乘。

  • 點(diǎn)乘
    兩個(gè)三分量之間的點(diǎn)乘運(yùn)算將得到一個(gè)標(biāo)量(只有一個(gè)值),它表示兩個(gè)向量之間夾角對(duì)應(yīng)的三角函數(shù) Cos 值。
  • 叉乘
    兩個(gè)向量之間叉乘所得的結(jié)果是另外一個(gè)向量,這個(gè)新向量與原來(lái)兩個(gè)向量定義的平面垂直。和點(diǎn)乘不同,在進(jìn)行叉乘運(yùn)算的時(shí)候向量的順序非常重要,不同的叉乘順序會(huì)得到兩個(gè)方向相反的向量。

四、矩陣及其空間變化

4.1 理解場(chǎng)景變化

4.1.1 視覺(jué)坐標(biāo)

視覺(jué)坐標(biāo)是相對(duì)于觀察則而言的,無(wú)論進(jìn)行何種變換,都可以將它視為絕對(duì)的屏幕坐標(biāo)。這樣,視覺(jué)坐標(biāo)就表示一個(gè)虛擬固定的坐標(biāo)系,通常作為參考坐標(biāo)系使用。

4.1.2 兩種變換

在說(shuō)矩陣之前,先來(lái)說(shuō)一下3D場(chǎng)景中的一些變化。關(guān)于變化,主要有兩種變換視圖變換和模型變換。

  • 視圖變換
    所謂的視圖就是觀察者或相機(jī)的位置。視圖變換允許我們把觀察點(diǎn)放置在任何希望的位置,允許在任何方向上觀察。確定視圖變換就像在場(chǎng)景中放置照相機(jī)并讓它指定某個(gè)方向。
    總的來(lái)說(shuō)在任何其他模型變換之前,必須先進(jìn)行視圖變換。這是因?yàn)閷?duì)視覺(jué)坐標(biāo)系而言,視圖變化就移動(dòng)了當(dāng)前的工作坐標(biāo)系,后續(xù)的一切變換隨后都是基于新調(diào)整的坐標(biāo)系進(jìn)行的。
  • 模型變換
    模型變換用于操作模型和其中的特定的對(duì)象。模型變換通常是現(xiàn)將模型對(duì)象移動(dòng)到需要的位置上,然后再對(duì)他們進(jìn)行旋轉(zhuǎn)和移動(dòng)。就拿先旋轉(zhuǎn)后平移和先平移后旋轉(zhuǎn)來(lái)說(shuō)得到的是兩種不同情況。如下圖所示,無(wú)論是先執(zhí)行旋轉(zhuǎn)還是平移,后一個(gè)操作(旋轉(zhuǎn)或平移)都是基于第一個(gè)操作結(jié)果產(chǎn)生的坐標(biāo)系進(jìn)行下一步操作。

4.2模型視圖矩陣

與其說(shuō)矩陣的幾何意義這么生澀難懂,不如說(shuō)的是矩陣在幾何中到底是有什么作用呢?一般來(lái)說(shuō),方陣可以描述任意的線性變換。也就說(shuō),在幾何當(dāng)中,我們用矩陣表示幾何體的空間變換。比如我們?cè)诔绦蛑谐S玫钠揭啤⑿D(zhuǎn)、縮放等等

模型視圖矩陣是一個(gè) 4 * 4 矩陣,它表示一個(gè)變化后的坐標(biāo)系,可以用來(lái)放置對(duì)象和確定對(duì)象的位置。頂點(diǎn)作為一個(gè)單列矩陣(也就是一個(gè)響亮)的形式來(lái)表示,并乘以一個(gè)模型視圖矩陣來(lái)獲得一個(gè)相對(duì)視覺(jué)坐標(biāo)系的經(jīng)過(guò)變換的新坐標(biāo)。

如下代碼所形成的矩陣計(jì)算所示,一個(gè)包含單個(gè)頂點(diǎn)數(shù)據(jù)的矩陣乘以模型視圖矩陣后得到新的視覺(jué)坐標(biāo)。頂點(diǎn)數(shù)據(jù)實(shí)際是4個(gè)數(shù)據(jù),其中包含一個(gè)附加值 w ,它表示一個(gè)縮放因子,默認(rèn)情況下是 1.0 ,一般情況下很少去改動(dòng)。

[x]        [a  b  c  d]          [x0]
[y]        [a  b  c  d]          [y0]
[z]  *    [a  b  c  d]   =     [z0]
[w]       [a  b  c  d]          [w0]

接下來(lái)我們就來(lái)詳細(xì)說(shuō)明,上面是矩陣計(jì)算是怎么做到:將一個(gè)頂點(diǎn)乘以一個(gè)矩陣來(lái)對(duì)它進(jìn)行變換。

4.2.1 矩陣構(gòu)造

矩陣的前三列的前三個(gè)元素只是方向向量,表示空間上 x y z 軸上的方向(在這里用向量來(lái)表示一個(gè)方向)。一般情況下這三個(gè)向量之前總是成 90 度夾角,并且通常為單位長(zhǎng)度。數(shù)學(xué)書(shū)中中稱之為標(biāo)準(zhǔn)正交(向量為單位長(zhǎng)度)和正交(向量不是單位長(zhǎng)度)。如下圖對(duì)矩陣進(jìn)行了標(biāo)注。另外要注意下圖的矩陣最后一行都為 0 ,只有一個(gè)元素為 1。



如果有一個(gè)包含不同坐標(biāo)系的位置和方向的 4 * 4 矩陣,然后用一個(gè)表示原來(lái)坐標(biāo)系的向量(表示為一個(gè)矩陣或向量)乘以這個(gè)矩陣,得到的結(jié)果是一個(gè)轉(zhuǎn)換到新坐標(biāo)系下的新向量。這就意味著,空間中任何位置和方向都可以由一個(gè) 4 * 4矩陣唯一確定。如果一個(gè)對(duì)象的所有向量乘以這個(gè)矩陣,那么我們將得到整個(gè)對(duì)象變換到的空間中的位置和方向。

4.2.2 單位矩陣

在講矩陣的變化之前,先簡(jiǎn)單說(shuō)下單位矩陣的概念。將一個(gè)向量乘以一個(gè)單位矩陣,就相當(dāng)于用這個(gè)向量乘以 1 ,不會(huì)發(fā)生任何變化。單位矩陣中除了一條對(duì)角線上的元素為 1,其他元素全為 0 。

4.3 矩陣變化操作

矩陣的變化操作主要分為縮放、平移、旋轉(zhuǎn)。為了更好的理解矩陣的變化操作,以及矩陣是怎么形成的,筆者就直接從縮放講起。把縮放講清除,之后的平移以及旋轉(zhuǎn)都是按照同樣的套路進(jìn)行推導(dǎo)。

4.3.1 縮放

為了更好的理解縮放,我先從 2D 環(huán)境說(shuō)起,之后在延伸到3D環(huán)境。



如果沿著坐標(biāo)軸進(jìn)行縮放,那么每一個(gè)坐標(biāo)軸都有縮放因子,所以2D環(huán)境下有兩個(gè)縮放因子Kx和Ky,那么基向量p和q根據(jù)縮放因子的影響,我們可以得到下面公式。


根據(jù)變化,可以得到在2D環(huán)境下的縮放矩陣。如下所示:


同理,通過(guò)2D環(huán)境下的縮放矩陣,我們可以得到3D環(huán)境下的縮放矩陣。

4.3.2 平移

一個(gè)平移矩陣僅僅是將頂點(diǎn)沿著 3 個(gè)左邊軸中的一個(gè)或者多個(gè)進(jìn)行移動(dòng)。這個(gè)應(yīng)該是很好理解的,這里就不做過(guò)多解釋。列如在 OpenGL的 math3d 庫(kù)中,我們就可以通過(guò)m3dTranslationMatrix44 函數(shù)使用矩陣直接做平移操作。

4.3.3 旋轉(zhuǎn)

關(guān)于旋轉(zhuǎn)操作的矩陣實(shí)際上推導(dǎo)起來(lái)稍稍有些麻煩,需要通過(guò)大量的圖解和注釋來(lái)說(shuō)明。筆者感覺(jué)沒(méi)必要進(jìn)行詳細(xì)的推導(dǎo),畢竟我們不是專業(yè)研究數(shù)學(xué)的,只要知旋轉(zhuǎn)矩陣形成過(guò)程和縮放以及平移的原理是一樣,只是推到起來(lái)會(huì)更麻煩些。這里我就簡(jiǎn)單的列出一些推到結(jié)果。當(dāng)然,有興趣的同學(xué)可以自行研究下。

五、關(guān)于CGAffineTransform的實(shí)現(xiàn)

在Core Graphics框架圖形繪制的時(shí)候,經(jīng)常會(huì)有對(duì)圖形進(jìn)行平移、縮放、旋轉(zhuǎn)這樣的要求。那么我們?cè)撊绾螌?shí)現(xiàn)呢?這就需要Core Graphics框架中的CGAffineTransform(矩陣)這個(gè)結(jié)構(gòu)體來(lái)進(jìn)行實(shí)現(xiàn)了。下面我們就對(duì)CGAffineTransform這個(gè)矩陣結(jié)構(gòu)體,進(jìn)行簡(jiǎn)單的說(shuō)明。

// CGAffineTransform結(jié)構(gòu)體樣式
struct CGAffineTransform {
  CGFloat a, b, c, d;
  CGFloat tx, ty;
};

齊次坐標(biāo)概念

所謂的其次坐標(biāo)就是把一個(gè)圖形用一個(gè)三維矩陣表示,其中第三列總是(0,0,1),用來(lái)作為坐標(biāo)系的標(biāo)準(zhǔn)。也就是z軸,是不發(fā)生改變的。

|a  b  0|
|c  d  0|
|tx ty 1|

接下來(lái)就來(lái)看看二維空間中的點(diǎn)坐標(biāo)是如和借助齊次坐標(biāo)進(jìn)行仿射變化。具體運(yùn)算原理如下:

               |a  b  0|

  [X,Y,  1]    |c  d  0|   =  [aX + cY + tx   bX + dY + ty  1] ;

                |tx ty 1|

運(yùn)算原理就是如此簡(jiǎn)單。CGAffineTransform的平移、旋轉(zhuǎn)、縮放操作,都是借助這個(gè)公式進(jìn)行計(jì)算的,只不過(guò)平移、旋轉(zhuǎn)、縮放只不過(guò)是其中的一些特殊情況而已。

CGAffineTransform的平移、旋轉(zhuǎn)、縮放變換。

  • 平移變換
    條件: a = d = 1 ,b = c = 0
              |1  0  0|

  [X,Y,  1]    |0  1  0|   =  [X + tx   ,  Y + ty  , 1] ;

                |tx ty 1|

坐標(biāo)由 [X,Y, 1] 變成了 [X + tx , Y + ty , 1],與原坐標(biāo)相比,z軸沒(méi)發(fā)生任何的改變,x 軸方向平移了 tx 個(gè)單位, y 軸方向平移了 ty 個(gè)單位。平移對(duì)應(yīng)Core Graphics框架中的CGAffineTransformMakeTranslation(CGFloat tx,CGFloat ty)API。

  • 縮放變換
    條件: b = c = 0 ,tx = ty = 0。
               |a  0  0|

  [X,Y,  1]    |0  d  0|   =  [aX  ,  dY  ,1] ;

                |0 0 1|

坐標(biāo)由[X,Y, 1]變?yōu)?[aX , dY ,1] ,X軸擴(kuò)大了 a 倍,Y 軸擴(kuò)大了 d 倍。縮放對(duì)應(yīng)Core Graphics框架中的 GAffineTransformMakeScale(CGFloat sx, CGFloat sy) API。

  • 旋轉(zhuǎn)變換
    條件 : tx=ty=0,a=cos?,b=sin?,c=-sin?,d=cos?
           |cos?   sin?  0|

  [X,Y,  1]    |-sin?  cos?  0|   = [Xcos? - Ysin? ,   Xsin? + Ycos? , 1] ;

                |tx     ty    1|

其中 ? 是旋轉(zhuǎn)的角度,逆時(shí)針為正,順時(shí)針為負(fù)。旋轉(zhuǎn)對(duì)應(yīng)Core Graphics框架中的 CGAffineTransformMakeRotation(CGFloat angle) API。

六、關(guān)于CATransform3D實(shí)現(xiàn)

回想一下前面所說(shuō)的矩陣的相關(guān)知識(shí),如下圖是 3D 仿射變化矩陣,和我們前面在矩陣那一塊講的結(jié)果一致。


3D仿射變化矩陣

先來(lái)看一下這個(gè)結(jié)構(gòu)體長(zhǎng)什么樣。

//CATransform3D基本結(jié)構(gòu)體
struct CATransform3D{
   CGFloat m11, m12, m13, m14;
   CGFloat m21, m22, m23, m24;
   CGFloat m31, m32, m33, m34;
   CGFloat m41, m42, m43, m44;
};

下面的代碼是 CATransform3D 實(shí)現(xiàn) 3D 效果的簡(jiǎn)單使用。

-(CATransform3D)getTransForm3DWithAngle:(CGFloat)angle{
    CATransform3D transform =CATransform3DIdentity;//獲取一個(gè)標(biāo)準(zhǔn)默認(rèn)的CATransform3D仿射變換矩陣
    transform.m34=1.0/-2000;//透視效果
    transform=CATransform3DRotate(transform,angle,0,1,0);//獲取旋轉(zhuǎn)angle角度后的rotation矩陣。
    return transform;
}

上面最重要的是m34這個(gè)屬性,CATransform3DRotate獲取的旋轉(zhuǎn)如果之前聯(lián)合的transform不支持透視,那在x、y軸上做旋轉(zhuǎn)是只有frame放大縮小的變化,我們需要的是在旋轉(zhuǎn)的時(shí)候要使得離視角近的地方放大,離視角遠(yuǎn)的地方縮小,就是所謂的視差來(lái)形成3D的效果。


根據(jù)前面的講解,通過(guò)上圖不難看到 m34 實(shí)際上影響了 z 軸方向的translation(移動(dòng)) ,所以實(shí)際開(kāi)發(fā)中為了實(shí)現(xiàn) 3D 效果,我們只需要簡(jiǎn)單控制 m34 這個(gè)參數(shù)即可。除了 m34 這個(gè)參數(shù)之外,另外幾個(gè)參數(shù)各有其用,有興趣的可以看下這篇文章。另外, 要知道,m34= -1/D, 默認(rèn)值是0,也就是說(shuō)D無(wú)窮大,這意味layer in projection plane(投射面)和 layer in world coordinate 重合了。D越小透視效果越明顯。所謂的D,是eye(觀察者)到投射面的距離。

結(jié)語(yǔ)

本文顯示介紹了 3D 成像原理、3D編程基本原則,之后介紹了向量和矩陣,矩陣這一塊對(duì)平移、旋轉(zhuǎn)、縮放進(jìn)行了簡(jiǎn)單的推到。最后基于前面所講的這些基礎(chǔ)知識(shí)和 iOS 中的CGAffineTransform、CATransform3D做了簡(jiǎn)單的關(guān)聯(lián)和解釋。
該篇文章僅僅只能作為 3D 圖像學(xué)的簡(jiǎn)單入門(mén),對(duì)于向接觸 AR、VR等相關(guān) 3D 方向的開(kāi)發(fā)者來(lái)說(shuō),這些都是工作必備的知識(shí)。歡迎指正!!!!!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,238評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,430評(píng)論 3 415
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 176,134評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 62,893評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,653評(píng)論 6 408
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,136評(píng)論 1 323
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,212評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,372評(píng)論 0 288
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,888評(píng)論 1 334
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,738評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,939評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,482評(píng)論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,179評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,588評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,829評(píng)論 1 283
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,610評(píng)論 3 391
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,916評(píng)論 2 372

推薦閱讀更多精彩內(nèi)容

  • 1 前言 OpenGL渲染3D模型離不開(kāi)空間幾何的數(shù)學(xué)理論知識(shí),而本篇文章的目的就是對(duì)空間幾何進(jìn)行簡(jiǎn)單的介紹,并對(duì)...
    RichardJieChen閱讀 7,058評(píng)論 1 11
  • 1 前言 一直想沿著圖像處理這條線建立一套完整的理論知識(shí)體系,同時(shí)積累實(shí)際應(yīng)用經(jīng)驗(yàn)。因此有了從使用AVFounda...
    RichardJieChen閱讀 5,715評(píng)論 5 12
  • >*很不幸,沒(méi)人能告訴你母體是什么,你只能自己體會(huì)* --駭客帝國(guó) 在第四章“可視效果”中,我們研究了一些增強(qiáng)圖層...
    夜空下最亮的亮點(diǎn)閱讀 1,669評(píng)論 0 2
  • 變換(Transformations) 我們可以嘗試著在每一幀改變物體的頂點(diǎn)并且重設(shè)緩沖區(qū)從而使他們移動(dòng),但這太繁...
    IceMJ閱讀 4,157評(píng)論 0 1
  • 謝康樂(lè)出身名門(mén),富有才學(xué),但仕途坎坷,因而他的情感寄托多在乎于山水,山水之樂(lè),雖仍受到東晉玄言詩(shī)的影響,間或有《周...
    王家人寧閱讀 372評(píng)論 0 0