深入探索透視投影矩陣_第1頁
深入探索透視投影矩陣_第2頁
深入探索透視投影矩陣_第3頁
深入探索透視投影矩陣_第4頁
深入探索透視投影矩陣_第5頁
已閱讀5頁,還剩21頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

1、-Twinsen 編寫-本人水平有限,疏忽錯誤在所難免,還請各位數(shù)學高手、編程高手不吝賜教-email:透視投影是3D固定流水線的重要組成部分,是將相機空間中的點從視錐體(frustum)變換到規(guī)則觀察體(Canonical View Volume)中,待裁剪完畢后進行 透視除法的行為。在算法中它是通過透視矩陣乘法和透視除法兩步完成的。透視投影變換是令很多剛剛進入 3D圖形領域的開發(fā)人員感到迷惑乃至神秘的一 個圖形技術。其中的理解困難在于步驟繁瑣,對一些基礎知識過分依賴,一旦對 它們中的任何地方感到陌生,立刻導致理解停止不前。沒錯,主流的3D APIs如OpenGL、D3D的確把具體的透視投影

2、細節(jié)封裝起 來,比如gluPerspective( 就)可以根據(jù)輸入生成一個透視投影矩陣。而且在大多數(shù)情況下 不需要了解具體的內(nèi)幕算法也可以完成任務。但是你不覺得,如果想要成為一個 職業(yè)的圖形程序員或游戲 開發(fā)者,就應該真正降伏透視投影這個家伙么?我們先 從必需的基礎知識著手,一步一步深入下去(這些知識在很多地方可以單獨找 到,但我從來沒有在同一個地方 全部找到,但是你現(xiàn)在找到了 )。我們首先介紹兩個必須掌握的知識。有了它們,我們才不至于在理解透視投影變 換的過程中迷失方向(這里會使用到向量幾何、矩陣的部分知識,如果你對此不 是很熟悉,可以參考 向量幾何在游戲編程中的使用 系列文章)。齊次坐標

3、表示透視投影變換是在齊次坐標下進行的,而齊次坐標本身就是一個令人迷惑的概 念,這里我們先把它理解清楚。根據(jù)向量幾何在游戲編程中的使用 6中關于基的概念。對于一個向量 v以 及基oabc,可以找到一組坐標(v1,v2,v3),使得v = v1 a + v2 b + v3 c ( 1 )而對于一個點p,則可以找到一組坐標(p1,p2,p3 ),使得p -o = pl a + p2 b + p3 c ( 2 )從上面對向量 和點的表達,我們可以看出為了在坐標系中表示一個點(如p),我們把點的位置看作是對這個基的原點 o所進行的一個位移,即一 個向量 p -o (有的書中把這樣的向量叫做位置向量 起始

4、于坐標原點的 特殊向量),我們在表達這個向量的同時用等價的方式表達出了點p:p = o + pl a + p2 b + p3 c (3)(1)(3)是坐標系下表達一個向量 和點的不同表達方式。這里可以看出,雖然都是 用代數(shù)分量的形式表達向量和點,但表達一個點比一個向量需要額外的信息。如 果我寫出一個代數(shù)分量表達(1,4, 7),誰知道它是個向量還是個點!我們現(xiàn)在把(1 )( 3 )寫成矩陣的形式:這里(a,b,c,o)是坐標基矩陣,右邊的列向量分別是向量v和點p在基下的坐標。這樣,向量和點在同一個基下就有了不同的表達:3D向量的第4個代數(shù)分量是0 ,而3D點的第4個代數(shù)分量是1。像這種這種用4

5、個代數(shù)分量表示3D幾何 概念的方式是一種齊次坐標表示。齊次坐標表示是計算機圖形學的重要手段之一,它既能夠用來明確區(qū)分向量和點,同時也更易用于進行仿射(線性)幾何變換。 ” 一一F.S. Hill, JR 這樣,上面的(1,4, 7)如果寫成(1,4,7,0 ),它就是個向量;如果是(1,4,7,1), 它就是個點。下面是如何在普通坐標(Ordinary Coordinate)和齊次坐標(HomogeneousCoordi nate)之間進行轉換:從普通坐標轉換成齊次坐標時,如果(x,y,z)是個點,則變?yōu)?x,y,z,1);如果(x,y,z)是個向量,則變?yōu)?x,y,z,0)從齊次坐標轉換成普

6、通坐標時,如果是(x,y,z,1),則知道它是個點,變成(x,y,z);如果是(x,y, z,0),則知道它是個向量,仍然變成(x,y,z)以上是通過齊次坐標來區(qū)分向量和點的方式。從中可以思考得知,對于平移T、旋轉R、縮放S這3個最常見的仿射變換,平移變換只對于點才有意義,因為普 通向量沒有位置概念,只有大小和方向,這可以通過下面的式子清楚地看出: 而旋轉和縮放對于向量和點都有意義,你可以用類似上面齊次表示來檢測。從中 可以看出,齊次坐標用于仿射變換非常方便。址 - a.此外,對于一個普通坐標的點P=(Px, Py, Pz),有對應的一族齊次坐標(wPx, wPy,wPz, w),其中w不等于

7、零。比如,P(1,4, 7)的齊次坐標有(1,4, 7, 1)、( 2, 8, 14, 2 )、( -0.1, -0.4, -0.7, -0.1 )等等。因此,如果把一個點從普通坐標變成齊 次坐標,給x,y,z乘上同一個非零數(shù)w,然后增加第4個分量w ;如果把一個齊 次坐標轉換成普通坐標,把前三個坐標同時除以第4個坐標,然后去掉第4個分量。由于齊次坐標使用了 4個分量來表達3D概念,使得平移變換可以使用矩陣進 行,從而如F.S. Hill, JR所說,仿射(線性)變換的進行更加方便。由于圖形硬 件已經(jīng)普遍地支持齊次坐標與矩陣乘法,因此更加促進了齊次坐標使用,使得它 似乎成為圖形學中的一個標準。

8、簡單的線性插值這是在圖形學中普遍使用的基本技巧,我們在很多地方都會用到,比如2D位圖的放大、縮小,Twee ning變換,以及我們即將看到的透視投影變換等等?;?思想是:給一個x屬于a, b,找到y(tǒng)屬于c, d,使得x與a的距離比上ab長 度所得到的比例,等于y與c的距離比上cd長度所得到的比例,用數(shù)學表達式 描述很容易理解:這樣,從a到b的每一個點都與c到d上的唯個點對應。有一個 x ,就可以求得一個y。此外,如果x不在a, b內(nèi),比如x < a或者x > b,貝U得到的y也是符合y < c或 者y >d,比例仍然不變,插值同樣適用。透視投影變換好,有了上面兩個理論

9、知識,我們開始分析這次的主角一一透視投影變換。這里我們選擇Ope nGL的透視投影變換進行分析,其他的 APIs會存在一些差異,但 主體思想是相似的,可以類似地推導。經(jīng)過相機矩陣的變換,頂點被變換到了相 機空間。這個時候的多邊形也許會被視錐體裁剪,但在這個不規(guī)則的體中進行裁 剪并非那么容易的事情,所以經(jīng)過圖形學前輩們的精心分析,裁剪被安排到規(guī)則 觀察體(Canonical View Volume, CVV)中進行,CVV是一個正方體,x, y, z的范圍都是由兩步組成:1) 用透視變換矩陣把頂點從視錐體中變換到裁剪空間的CVV中。2) CVV裁剪完成后進行透視除法(一會進行解釋)。 我們一步一

10、步來,我們先從一個方向考察投影關系。上圖是右手坐標系中頂點在相機空間中的情形。設P(x,z)是經(jīng)過相機變換之后的點,視錐體由eye眼睛位置,np近裁剪平面,fp遠裁剪平面組成。N是眼睛到近裁剪平面的距離,F(xiàn)是眼睛到遠裁剪平面的距離。投影面可以 選擇任何平行于近裁剪平面的平面,這里我們選擇近裁剪平面作為投影平面。設 P' (x '是投影之后的點,則有z' =N。通過相似三角形性質,我們有關系:IMllilll同理,有這樣,我們便得到了 P投影后的點P'從上面可以看出,投影的結果 z'始終等于-N,在投影面上。實際上,z'對于投 影后的P'已

11、經(jīng)沒有意義了,這個信息點已經(jīng)沒用了。但對于 3D圖形管線來說, 為了便于進行后面的片元操作,例如 z緩沖消隱算法,有必要把投影之前的 z保 存下來,方便后面使用。因此,我們利用這個沒用的信息點存儲z,處理成:這個形式最大化地使用了 3個信息點,達到了最原始的投影變換的目的,但是它 太直白了,有一點蠻干的意味,我感覺我們最終的結果不應該是它,你說呢?我 們開始結合CVV進行思考,把它寫得在數(shù)學上更優(yōu)雅一致,更易于程序處理。 假入能夠把上面寫成這個形式:那么我們就可以非常方便的用矩陣以及齊次坐標理論來表達投影變換:其中哈,看到了齊次坐標的使用,這對于你來說已經(jīng)不陌生了吧?這個新的形式不僅 達到了上

12、面原始投影變換的目的,而且使用了齊次坐標理論,使得處理更加規(guī)范mum iiiiiiiiiiiiiiiihi化。注意在把變成的一步我們是使用齊次坐標變普通坐標的規(guī)則完成的。這一 步在透視投影過程中稱為透視除法(PerspectiveDivision),這是透視投影變換的第2步,經(jīng)過這一步,就丟棄了原始的 z值(得到了 CVV中對應的z值,后面解釋),頂點才算完成了投影。而在這兩步 之間的就是CVV裁剪過程,所以裁剪空間使用的是齊次坐標,主要原因在于透視除法會損失一些必要的信息(如原始 z,第4個-z保留的)從而使裁剪變得更 加難以處理,這里我們不討論 CVV裁剪的細節(jié),只關注透視投影變換的兩步。

13、 矩陣就是我們投影矩陣的第一個版本。你一定會問為什么要把z寫成有兩個原因:1) P'的3個代數(shù)分量統(tǒng)一地除以分母-z,易于使用齊次坐標變?yōu)槠胀ㄗ鴺藖硗?成,使得處理更加一致、高效。2)后面的CVV是一個x,y,z的范圍都為-1, 1的規(guī)則體,便于進行多邊形裁 剪。而我們可以適當?shù)倪x擇系數(shù) a和b,使得接下來我們就求出a和b :這個式子在z = -N的時候值為-1 ,而在z = -F的時 候值為1,從而在z方向上構建CVV。這樣我們就得到了透視投影矩陣的第一個版本:使用這個版本的透視投影矩陣可以從z方向上構建CVV,但是x和y方向仍然沒有限制在-1,1中,我們的透視投影矩陣的下一個版本就

14、要解決這個問題。為了能在x和y方向把頂點從Frustum情形變成CVV情形,我們開始對x和y 進行處理。先來觀察我們目前得到的最終變換結果:我們知道-Nx / z的有效范圍是投影平面的左邊界值(記為 left )和右邊界值(記 為 right) ,即卩l(xiāng)eft, right , -Ny / z 則為bottom, top。而現(xiàn)在我們想把-Nx / z 屬 于left, right映射到x屬于-1, 1中,-Ny / z屬于bottom, top映射到y(tǒng)屬于 -1, 1中。你想到了什么?哈,就是我們簡單的線性插值,你都已經(jīng)掌握了!我 們解決掉它:則我們得到了最終的投影點:下面要做的就是從這個新形

15、式出發(fā)反推出下一個版本的透視投影矩陣。注意到 是經(jīng)過透視除法的形式,而 P'只變化了 x和y分量的形式,az+b和-z是不變的,則我們做透視除法的逆處理 一一給P'每個分量乘上-z,得到而這個結果又是這么來的:M就是最終的透視變換矩陣。相機空間中的頂點,如果在視錐體中,則變換后就 在CVV中。如果在視錐體外,變換后就在 CVV夕卜。而CVV本身的規(guī)則性對于 多邊形的裁剪很有利。Ope nGL在構建透視投影矩陣的時候就使用了 M的形 式。注意到M的最后一行不是(0 0 0 1)而是(0 0 -1 0),因此可以看出透視變換 不是一種仿射變換,它是非線性的。另外一點你可能已經(jīng)想到,

16、對于投影面來 說,它的寬和高大多數(shù)情況下不同,即寬高比不為1,比如640/480。而CVV 的寬高是相同的,即寬高比永遠是1。這就造成了多邊形的失真現(xiàn)象,比如一個 投影面上的正方形在CVV的面上可能變成了一個長方形。解決這個問題的方法 就是在對多變形進行透視變換、裁剪、透視除法之后,在歸一化的設備坐標(Normalized Device Coordinates)上進行的視口 (viewport)變換中進行校正,它 會把歸一化的頂點之間按照和投影面上相同的比例變換到視口中,從而解除透視 投影變換帶來的失真現(xiàn)象。進行校正前提就是要使投影平面的寬高比和視口的寬 高比相同。便利的投影矩陣生成函數(shù)3D

17、APIs 都提供了諸如 gluPerspective(fov, aspect, near, far或者 D3DXMatrixPerspectiveFovLH(pOut, fovY, Aspect, zn, zf)這樣的函數(shù)為用戶提 供快捷的透視矩陣生成方法。我們還是用 Ope nGL的相應方法來分析它是如何運 作的。gluPerspective(fov, aspect, n ear, far)fov即視野,是視錐體在xz平面或者yz平面的開角角度,具體哪個平面都可 以。OpenGL和D3D都使用yz平面。aspect即投影平面的寬高比。 near是近裁剪平面的距離 far是遠裁剪平面的距離。3

18、步right = top x aspect使用了乘法,這也許就是為什么圖形 APIs采用yz平面的 原因吧!到目前為止已經(jīng)完成了對透視投影變換的闡述,我想如果你一直跟著我的思路下 來,應該能夠對透視投影變換有一個細節(jié)層次上的認識。當然,很有可能你已經(jīng) 是一個透視投影變換專家,如果是這樣的話,一定給我寫信,指出我認識上的不 足,我會非常感激。Bye!深入探索透視投影變換(續(xù))-潘宏-2009414-本人水平有限,疏忽錯誤在所難免,還請各位數(shù)學高手、編程高手不吝賜教-email:在上一篇文章中我們討論了透視投影變換的原理,分析了 Ope nGL所使用的透視 投影矩陣的生成方法。正如我們所說,不同的

19、圖形 API因為左右手坐標系、行向 量列向量矩陣以及變換范圍等等的不同導致了矩陣的差異,可以有幾十個不同的 透視投影矩陣,但它們的原理大同小異。這次我們準備討論一下Direct3D (以下簡稱D3D )以及J2ME平臺上的JSR184(M3G )(以下簡 稱M3G )的透視投影矩陣,主要出于以下幾個目的:(1)我們在寫圖形引擎的時候需要采用不同的圖形 API實現(xiàn),當前主要是 Ope nGL和D3D。雖然二者的推導極為相似,但 D3D的自身特點導致了一些地 方仍然需要澄清。(2)DirectX SDK的手冊中有關于透視投影矩陣的一些說明,但并不詳細,甚 至有一些錯誤,從而使初學者理解起來變得困難

20、,而這正是本文寫作的目的。(3)M3G是J2ME平臺上的3D開發(fā)包,采用了 OpenGL作為底層標準進行封 裝。它的透視投影矩陣使用 Ope nGL的環(huán)境但又進行了簡化,值得一提。本文努力讓讀者清楚地了解 D3D與M3G透視投影矩陣的原理,從而能夠知道它 與OpenGL的一些差別,為構建跨 API的圖形引擎打好基礎。需要指出的一點是 為了完全理解本文的內(nèi)容,請讀者先理解上一篇文章深入探索透視投影變換 的內(nèi)容,因為OpenGL和它們的透視投影矩陣的原理非常相似,因此這里不會像 上一篇文章從基礎知識講起,而是對比它們的差異來推導變換矩陣。我們開始!Ope nGL與D3D的基本差異yXPJ前面提到,

21、不同API的基本差異導致了最終變換矩陣的不同,而導致 OpenGL和 D3D的透視投影矩陣不同的原因有以下幾個:(1)Ope nGL默認使用右手坐標系,而 D3D默認使用左手坐標系。(2)Ope nGL使用列向量矩陣乘法而 D3D使用行向量矩陣乘法。(3)OpenGL的CVV的Z范圍是-1,1,D3D的CVV的Z范圍 是0, 1。以上這些差異導致了最終 Ope nGL和D3D的透視投影矩陣的不同。x* zl N戈 liey二一二一=> 工JV同理卩二N X z ZZZD3D的透視投影矩陣推導我們先來看最最基本的透視關系圖(上一篇文章開始的時候使用的圖):這里我們考察的是xz平面上的關系,

22、yz平面上的關系同理。這里o是相機位 置。np是近裁剪平面,也是投影平面, N是它到相機的距離。fp是遠裁剪平 面,F(xiàn)是它到相機的位置。p是需要投影的點,p'是投影之后的點。根據(jù)相似 三角形定理,我們有則有注意到OpenGL使用右手坐標系,因此應該使用-N (請參考上一篇文章的這一 步),而D3D使用左手坐標系,因此使用 N,這是二 者的不同點之一。這樣, 我們得到投影之后的點P1=n- nnIn z JFF_ N NFF_ N00N00Persp Pr oj =00a20b7 (N000>r 6c 'y0N00X=z00a1az + bkb1°0b1I z J

23、第三個信息點是變換之后的z在投影平面上的位置,也就是 N,它已經(jīng)沒用了, 我們把p'寫成從而用第三個沒用信息點它來存儲 z (如果讀者對這一點不太了解,請參考上一 篇文章)。接下來我們求出a和b,從而在z方向上構建CVV。請注意這里是OpenGL和D3D的另一個不同點, OpenGL的CVV的z范圍是-1, 1,而D3D的CVV的z范圍是0, 1。也就是說,D3D中在近裁剪平面 上的點投影之后的點會處于 CVV的z=0平面上,而在遠裁剪平面上的點投影之 后的點會在CVV的z=1平面上。這樣我們的計算方程就是從而我們得到了透視投影矩陣的第一個版本即frus t uaright _ lef

24、ibottom耳(一 1)兒碎-(-1)top-bottom 1-(1)這個時候第三個分量變換到吆 lefi _ J 1_p right - left right left 22Ny/f,/z _ bohorn _ ycvv 1 lop bottom lop - bottom 22CVV情形了,CVV的z范圍是0,1。接下來根據(jù)上一篇文章所講到的,我們要 把前兩個分量變成CVV情形,CVV的x和y范圍是-1, 1,如下圖所示:使用線性插值,我們有:這里left和right是投影平面的左右范圍,top和bottom是投影平面的上下范圍。 x cvv和y cvv是我們需要算出的在 CVV情形中的x

25、和y,也就是我們要計算出 的結果。但在算出它們之前,我們先把上面的式子寫成:rigid - left2top bottom 2Nx/7z _ sright left2*Ny/z_ yewtop-bottom2這里有一個需要注意的地方,如果投影平面在x方向上居中,則那么第一個式子就可以銷掉等號兩邊的1/2,寫成同理,如果投影平面在y方向上居中,則第二個式子可以寫成 則我們現(xiàn)在分兩種情況討論:(1)投影平面的中心和x-y平面的中心重合(在x和y方向上都居中)(2)一般情況我們分別討論:1 )特殊情況方程這組是特殊情況,方程比較簡單,但也是使用頻率最高的方式(這是D3DXMatrixPerspect

26、iveLH、2Nx(right 一 left ) z_2Ny廣27*、r卩丫(2Nr-l0QX0(rights left)2Nyyn2Na*Sp - bottom)zXVt-bwV100a1L « JJ丿I 00b。丿2祇(right®p - bottomzaz + btop - bottom )z! F-N壬L F-ND3DXMatrixPerspectiveRH、D3DXMatrixPerspectiveFovLH、D3DXMatrixPerspectiveFovRH四個方法所使用的情況)。我們導出它:則我們反推出透視投影矩陣:其中而r-l和t-b可以分別看作是投影平面

27、的寬 w和高h。最后那個矩陣就是D3D的透視投影矩陣之一。另外呢,如果我們不知道 right、left、top以及 bottom這幾個參量,也可以根據(jù)視野(FOV -Field Of View )參量來求得。下面 是兩個平面的視野關系圖:fov2Ntan = Z4 =一 = cot-2 N w2*; m? = r -Z2N jovvcot-一巴22N神二,盤cot -_2同理= cot-其中 d E h22Nfov*=c&t-匸t b2L 2NiTcot-一-2aspect _ ratio 二 h二 w 二為 x asp&ct _ ratio或者aspect _ ratiota

28、p-bottom妙 二”rightleft22bottom _ 人1十lopbottom 22其中,兩個fov分別是在x-z以及y-z平面上的視野。如果只給了一個視野,也 可以通過投影平面的寬高比計算出來:用一個視野算出w或者h,然后用寬高比算出h或者w。(2)一般情況的方程這組方程比較繁瑣,但更具一般性(和Ope nGL 般矩陣的推導一致,這也是D3DXMatrixPerspectiveOffCe nterLH 和D3DXMatrixPerspectiveOffCe nterRH兩個方法所使用的情況)。我們導出它:CVV right + leftright _ left right left

29、吆top-bottomycvvcvv top 一 bottom top bottom2N% right kjt 'right - hjt right 亠 UJt*tap -i- bottomtcp - b oitofii top-b Qitomazbrights left r right - l£fi right - left l/Jy也p + b沁弗tztop - bottom top - bottomaz+ b/+ r7T710t -bb嚴b-foQ)J F-N, NF b L F-N我們繼續(xù)反推出透視投影矩陣:其中最后那個矩陣就是D3D的一般透視投影矩陣。好了,目前為止,我們已經(jīng)導出了 D3D的兩個透視投影矩陣。下面我把上一篇導出的Ope nGL的透視投影矩陣寫出來,大家可以拿它和剛剛導出的D3D的一般性透視投影矩陣做一個對比。(2N0r+l0r-lr-l02N£4&0

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論