攝像機矩陣和投影矩陣推導課件_第1頁
攝像機矩陣和投影矩陣推導課件_第2頁
攝像機矩陣和投影矩陣推導課件_第3頁
攝像機矩陣和投影矩陣推導課件_第4頁
攝像機矩陣和投影矩陣推導課件_第5頁
已閱讀5頁,還剩113頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

3DStudyNotes向量和矩陣變換Linguohua2012/7/11攝像機矩陣和投影矩陣推導說明主要是為了備忘,本文記錄了我學習向量和矩陣過程中遇到的一些基礎(chǔ)知識以及數(shù)學證明。數(shù)學證明大多是我自己的想法,所以一些過程并不是最簡的,原因之一是我在空間和微分幾何方面的知識積累甚少。如果你有更簡單的方法,請讓我知道。攝像機矩陣和投影矩陣推導說明先記錄向量和向量的運算,以及點乘和叉乘的證明。然后簡要記錄若干個重要的坐標空間。接著詳細推導View矩陣和Projection矩陣。最后是記錄DirectX的一個旋轉(zhuǎn)立方體的Tutorial。攝像機矩陣和投影矩陣推導說明寫記錄最艱難莫過于公式編輯了,每一個數(shù)學式子,都是從Word里面用公式編輯器編輯好,再復制過來,更悲劇的事情是PPT貌似不支持公式,它把復制過來的公式直接變成圖片了??梢娢沂嵌嘤眯?。攝像機矩陣和投影矩陣推導點和(方向)向量數(shù)值上,都是用{x,y,z}表示。前者表示位置,后者表示方向。因表征意義不同,圖形庫一般以Point類和Vector類表達兩者,但它們在數(shù)值層面是一致的。因方向向量的核心是方向,故兩個方向向量的x,y,z數(shù)值可能不同,但方向卻是一樣的,我們認為這兩個方向向量等價。攝像機矩陣和投影矩陣推導點和(方向)向量方向向量C和B等價,因它們表達的方向是相同的。數(shù)值上點A和向量B相等,但物理意義不同xy點A{5,2,6}向量B{5,2,6}z向量C攝像機矩陣和投影矩陣推導(位移)向量雖然多數(shù)時候向量純粹表達方向,但事實上它還帶有長度的信息,向量{x,y,x}在3D空間的長度是。故,可以把向量理解為在一個方向上長度為的位移。例如兩點之間的距離向量,就是一個典型的位移向量。我們通常結(jié)合上下文,來判斷向量是純粹方向的還是位移的向量。攝像機矩陣和投影矩陣推導向量的基本運算:加法向量的加法法則定義為:加法結(jié)果還是一個向量,從數(shù)值上看,結(jié)果向量的每一個分量均“變大”了(嚴格來說這取決于b的符號)。攝像機矩陣和投影矩陣推導加法向量A加向量B,先把A或者B平移(在A和B所確定的平面上平移),使得A和B成首尾相接

xyz向量A向量B攝像機矩陣和投影矩陣推導加法平移向量A得到向量A’,這樣向量B和向量A’首尾相接,連接向量B的起點和向量A’的終點,即可得到結(jié)果:向量C。平移向量B也會得到同樣的結(jié)果。xyz向量A向量B向量C向量A’攝像機矩陣和投影矩陣推導向量的基本運算:減法向量的減法法則定義為:減法結(jié)果還是一個向量,從數(shù)值上看,結(jié)果向量的每一個分量均“變小”了(嚴格來說這取決于b的符號)。攝像機矩陣和投影矩陣推導減法向量A減向量B,先把A或者B平移(在A和B所確定的平面上平移),使得A和B成首首相接

xyz向量A向量B攝像機矩陣和投影矩陣推導減法xyz向量A向量B向量A’向量C平移向量A到向量A’,由于是A-B,所以連接B的尾部到A’的尾部,使得結(jié)果向量指向被減數(shù),所得的向量即是A-B平移向量B也能得到同樣的結(jié)果攝像機矩陣和投影矩陣推導向量的基本運算:點乘DotProduct,又叫點乘或點積,定義為:如上式所示,點乘的結(jié)果是一個標量。后面我們將要證明該標量和

相關(guān),其中是這兩個向量的夾角,也即是說,從兩個向量點乘的結(jié)果能得出它們之間的夾角。這就是點乘的價值所在。攝像機矩陣和投影矩陣推導點乘的證明xyz向量A向量C向量B攝像機矩陣和投影矩陣推導點乘的證明如上圖所示,向量A是,向量B是。它們的夾角為,向量C的是多少呢?由圖示以及向量減法法則,可得向量C為:向量A,B,C構(gòu)成一個三角形,而三角形的余弦定理,注意余弦定理等式中的A,B,C是指三角形的邊長,均是標量。攝像機矩陣和投影矩陣推導點乘的證明余弦恒等式用到的邊長即是向量A,B,C的模,據(jù)此,分別求三個向量的模并代入余弦定理得:等式的|A|和|B|表示向量的模?;喌仁郊纯傻玫街庇^的結(jié)果,見下頁攝像機矩陣和投影矩陣推導點乘的證明化簡前面等式得到:上式左邊即是點乘的定義。至此,我們看出點乘和成正比,可用下式表示:其中是向量A和向量B的點乘,而是兩個向量的模的乘積。攝像機矩陣和投影矩陣推導點乘的證明因此,如果兩個向量的點乘結(jié)果是零,可知它們相互垂直。由上面的夾角的等式,可以求得兩個向量的夾角。攝像機矩陣和投影矩陣推導向量的基本運算:叉乘CrossProduct,又叫叉乘或叉積,定義為:嗯,不易看出規(guī)律,看下頁攝像機矩陣和投影矩陣推導叉乘注意下圖的顏色和箭頭左邊同顏色箭頭所連接的元素,構(gòu)成右邊同顏色的元素。這些箭頭是交叉的。這可能就是叉乘名字的由來吧。攝像機矩陣和投影矩陣推導叉乘可以用xyzzy方法記憶叉乘公式:其中xyz表示3個軸的坐標值,簡單起見設(shè)左邊第一個向量為A,第二個為B,右邊的結(jié)果向量為C,依照xyzzy:接著求,需要按照x->y->z->x的規(guī)則變換xyzzy成yzxxz,得:同樣可以求得攝像機矩陣和投影矩陣推導叉乘和點乘比較,點乘得到的結(jié)果是一個標量,但叉乘得到的是3個標量所構(gòu)成的一個向量,這個差異很大。既然叉乘得到一個向量,那么這個向量具有什么性質(zhì)呢?嗯,直接觀察不易,我覺得從線性代數(shù)和矩陣論的范疇,應該能夠簡單地得到結(jié)論。不過,我們可以利用點乘來得出叉乘的一些性質(zhì)。攝像機矩陣和投影矩陣推導叉乘性質(zhì)證明讓叉乘的兩個向量分別和叉乘的結(jié)果向量進行點乘運算,得:攝像機矩陣和投影矩陣推導叉乘性質(zhì)證明由上面兩式和點乘的性質(zhì),得知叉乘的結(jié)果向量和原來的兩個向量都垂直。我們知道原來的兩個向量確定了一個平面,也即是說叉乘的結(jié)果向量垂直于這個平面。這就是叉乘的重要幾何意義。下面我們分析叉乘結(jié)果向量的模。攝像機矩陣和投影矩陣推導叉乘結(jié)果向量的模由點乘公式:等式兩邊平方,然后用三角等式代換后并整理得到:攝像機矩陣和投影矩陣推導叉乘結(jié)果向量的模注意到上式左邊是叉乘結(jié)果向量的模的平方,所以對等式兩邊開平方,即得:上式便是關(guān)于叉乘的模的等式。至此,我們知道叉乘會得到一個垂直于原來兩個向量(以及它們所在平面)的向量,且這個向量的長度滿足上述等式。但仍有一個問題:這個垂直向量朝向那個方向呢?攝像機矩陣和投影矩陣推導叉乘xyz向量A向量C向量B攝像機矩陣和投影矩陣推導叉乘向量的方向如上圖所示,向量C方向朝上還是朝下(注意:不管朝向如何,它終歸都會垂直于原來的兩個向量)?一個簡單的判斷方法,見下頁的圖示。注意如果是左手坐標系,就用左手,如果是右手坐標系,那么需要用右手。攝像機矩陣和投影矩陣推導叉乘向量的方向攝像機矩陣和投影矩陣推導點乘和叉乘用途至此,我們知道點乘得到一個標量,這個標量跟原來兩個向量的夾角相關(guān)。所以,在3D圖形學中常通過兩個向量的點乘得到它們之間的夾角。我們知道叉乘得到一個垂直于原來兩個向量的新向量,3D圖形學中常用這種方式求垂直于平面/三角面/多邊形等的向量。例如法線(凹凸)貼圖時,需要求出垂直于頂點的法線。攝像機矩陣和投影矩陣推導Wiki叉乘和點乘都是由JosiahWillardGibbs在1881年提出的。Dotproduct:Scalarproduct,Crossproduct:Vectorproduct,攝像機矩陣和投影矩陣推導左手和右手坐標系在3D空間中存在這樣的兩種坐標系,不管怎么翻轉(zhuǎn),都不能從一種坐標系變換到另一種坐標系。這兩種坐標系我們用左手坐標系和右手坐標系來稱呼和區(qū)分它們。DirectX常用左手坐標系,OpenGL則慣用右手坐標系。不要擔心,事實上他們的x,y坐標軸完全一樣,只是z軸一個向里,一個向外。如下圖所示:攝像機矩陣和投影矩陣推導左手和右手坐標系攝像機矩陣和投影矩陣推導坐標系和坐標系轉(zhuǎn)換3D模型從建模到渲染最后階段——輸出到屏幕需要經(jīng)歷多個坐標系,從一個坐標系到另一個坐標系則需要一個轉(zhuǎn)換過程。這個過程是由一個轉(zhuǎn)換矩陣來實施的。本節(jié)簡要記錄一些關(guān)鍵坐標系(坐標空間),和相應的轉(zhuǎn)換說明,然后以DirectX為例,記錄和推導幾個重要的轉(zhuǎn)換矩陣。攝像機矩陣和投影矩陣推導Model坐標系模型坐標系,也叫Local坐標系。例如我們在3DMax,MAYA等建模工具中建立我們的人物模型時,模型中的頂點坐標值就是Model坐標系的值。設(shè)想我們有多個人物模型,那么每一個模型都有屬于自己的Model坐標系。攝像機矩陣和投影矩陣推導World坐標系World坐標系也是很直觀的,我們把若干個模型放在一起組成一張場景,場景的坐標系就是World坐標系,這就像我們現(xiàn)實世界一樣。一個模型放置到World坐標系之后,它的頂點坐標值就需要從Model坐標系轉(zhuǎn)換為World坐標系中的值。如下頁圖示:攝像機矩陣和投影矩陣推導World坐標系Model坐標系和World坐標系頂點P在Model坐標系中的值和在World坐標系中的值是不同的頂點P攝像機矩陣和投影矩陣推導Camera坐標系Camera坐標系是人眼觀察World坐標系時,以人眼為原點,視線方向為Z軸建立的新坐標系,這個坐標系以觀察者(眼睛)為中心,為視野裁剪和投影等做好鋪墊。隨著觀察者眼睛位置的變化,或者視線方向的變化,Camera坐標系也同時變換。攝像機矩陣和投影矩陣推導Projection坐標系Projection即投影坐標系基于Camera坐標系變換而來的新坐標系,這個新坐標系把視野外的東西剔除掉,把視野內(nèi)的東西投影到屏幕(近裁面)上,并且離眼睛越遠的東西看起來越小。攝像機矩陣和投影矩陣推導tangent坐標系還有很多具有專門用途的坐標空間,例如Tangent即切線坐標系,它適合于根據(jù)高度圖(Heightmap)計算法向圖(Normalmap)。此處就不一一列舉其他坐標空間了,事實上我知道的太少了,列舉不出來呀。攝像機矩陣和投影矩陣推導坐標系的轉(zhuǎn)換抄錄自MSDN,Transformpipeline攝像機矩陣和投影矩陣推導WikiTransformpipeline,(v=vs.85).aspx攝像機矩陣和投影矩陣推導坐標系的轉(zhuǎn)換和矩陣任意兩個坐標系的轉(zhuǎn)換都經(jīng)由一個轉(zhuǎn)換矩陣完成。例如從Model坐標系到World坐標系,需要經(jīng)過World轉(zhuǎn)換矩陣進行變換。World矩陣主要用于伸縮,平移,和旋轉(zhuǎn)。伸縮/平移較為直觀,而旋轉(zhuǎn)會有幾種方式,例如構(gòu)造矩陣旋轉(zhuǎn),或歐拉角旋轉(zhuǎn),或四元數(shù)旋轉(zhuǎn)。限于篇幅就不詳細記錄了。將來如有需要,再單獨記錄。攝像機矩陣和投影矩陣推導坐標系的轉(zhuǎn)換和矩陣后續(xù)的內(nèi)容主要記錄World坐標系轉(zhuǎn)換之后的Camera坐標系,Projection坐標系的轉(zhuǎn)換。接下來記錄的轉(zhuǎn)換矩陣推導,是用DirectX來舉例。事實上,這些推導過程在OpenGL上也是一樣的,如果有差別,也是一些數(shù)值上的細微差別,例如DirectX的遠近裁剪面定為[0~1],而OpenGL的定為[-1~1]。攝像機矩陣和投影矩陣推導DirectXViewMatrix推導從World坐標系轉(zhuǎn)換到Camera坐標系需要一個轉(zhuǎn)換矩陣幫忙,這個矩陣叫View矩陣。攝像機矩陣和投影矩陣推導DirectXViewMatrix推導View矩陣是一個4X4的矩陣,作用是將頂點從World坐標系轉(zhuǎn)換到Camera坐標系。Camera坐標系是一個這樣的坐標系:以眼睛的位置為原點,視線方向為Z軸的一個坐標系。新坐標系的X軸朝向觀察者的右手方向,Y軸朝向觀察者頭頂方向。在World坐標系的頂點經(jīng)過View矩陣轉(zhuǎn)換后,得到一個位于Camera坐標系的新坐標。攝像機矩陣和投影矩陣推導DirectXViewMatrix推導運算過程:注意運算時采用的是齊次坐標,各個分量取值是基于Camera坐標系的,它們相對的原點是Camera坐標系的原點,也即是觀察者眼睛的位置。下面我們推導View矩陣。攝像機矩陣和投影矩陣推導DirectXViewMatrix推導推導View矩陣分兩步,首先確立Camera坐標系,也即確立Camera坐標系的X,Y,Z軸。然后構(gòu)造一個矩陣,該矩陣能夠把World坐標系的頂點映射到Camera坐標系。簡明起見,我們需要定義若干變量:設(shè)眼睛所在的點為ptEye,眼睛注視的點為ptAt,注意到ptEye和ptAt都是World坐標系中的點。然后我們還需要World坐標系的Y軸方向向量,設(shè)為Up。攝像機矩陣和投影矩陣推導DirectXViewMatrix推導為什么需要Up向量呢?非常正規(guī)的含義我也不清楚。但從運算角度來說,如果沒有Up向量,我們就沒有辦法確定Camera的X,Y軸(Z軸是視線方向,是已經(jīng)確定的)??赡苡肬p向量更加符合我們的感官世界吧。單純從運算角度來看,提供World坐標系的X,Z軸向量都等價于提供Up向量。攝像機矩陣和投影矩陣推導DirectXViewMatrix推導那么,Camera坐標系,Z軸等于:Normal表示標準化ptAt-ptEye向量,使得它的模為1。因為約定Up和Z’共面(Z’=0的平面),所以X軸由Up和Z’的叉乘得到:最后,Y’則由Z’和X’叉乘得到:注意Y’不再需要標準化,因為X’和Z’都是單位向量攝像機矩陣和投影矩陣推導DirectXViewMatrix推導

XYZWorldspaceCameraspaceX’Z’Y’ptAtptEye攝像機矩陣和投影矩陣推導DirectXViewMatrix推導得到Camera坐標系的3個坐標軸的單位向量后,我們就可以開始構(gòu)造View矩陣了。攝像機矩陣和投影矩陣推導DirectXViewMatrix推導

XYZX’Z’Y’P向量eye向量P向量PN攝像機矩陣和投影矩陣推導DirectXViewMatrix推導觀察上圖,各個重要的向量已經(jīng)標出:黃色向量eye表示W(wǎng)orld坐標系中眼睛位置向量;紅色向量P表示W(wǎng)orld坐標系中點P的向量;綠色向量PN表示Camera坐標系中點P的向量,我們目標就是求PN。如上圖所示,我們考察World坐標系中的點P,在World坐標系中它的向量是紅色的P,而在Camera坐標系中它的向量是PN,單獨考察它在Camera坐標系的X’分量,也即是向量PN在X’軸上的投影,攝像機矩陣和投影矩陣推導DirectXViewMatrix推導只要我們能夠求出點P在Camera坐標系中X’,Y’,Z’分量,再把這幾個分量組成{x,y,z}形式就是點P在Camera坐標系中的新坐標值。不難看出,PN=P-eye(向量減法),即向量PN在X’軸的投影等于eye在X’軸的投影加上向量P在X’軸的投影。這個發(fā)現(xiàn)非常重要,據(jù)此我們就可以求出點P在X’軸的投影(即向量PN在X’軸的投影),然后用同樣的方法便可以求出PN在Y’,Z’的投影。三個投影值確定后,PN也就確定了。攝像機矩陣和投影矩陣推導DirectXViewMatrix推導回想點乘公式:如果上式的A是單位向量,則|A|=1,所以得到:,這相當于得到B在A方向的投影長度。如下圖所示:向量B向量A攝像機矩陣和投影矩陣推導DirectXViewMatrix推導因此,我們就用點乘公式來求向量PN在X’的投影,因PN=P-eye,所以:上式[X’]是Camera坐標系的X’軸的單位向量。上式等價于下面的齊次向量點乘:攝像機矩陣和投影矩陣推導DirectXViewMatrix推導上式的成立是容易看出的。其中,,和是Camera坐標系的X軸X’單位向量在World坐標系中的x,y,z三個分量。至此,我們已經(jīng)成功求出PN在X’軸的投影,同樣的,我們可以求出PN在Y’,Z’軸的投影:攝像機矩陣和投影矩陣推導DirectXViewMatrix推導點P在Camera坐標系的3個軸上的投影都已求出,我們把這3個等式組合成齊次4X4矩陣:至此我們已經(jīng)看到View矩陣了。攝像機矩陣和投影矩陣推導DirectXViewMatrix推導View矩陣:嗯,這就是我們的View矩陣。所有World坐標系中的點P經(jīng)過View矩陣轉(zhuǎn)換后,變成Camera坐標系中的點。攝像機矩陣和投影矩陣推導DirectXViewMatrix推導DirectX為了免除我們構(gòu)造View矩陣的繁瑣,提供了API:D3DXMatrixLookAtLH和D3DXMatrixLookAtRH,LH和RH后綴表示lefthand和righthand左右手坐標系的意思。也就是說前者構(gòu)造左手坐標系的View矩陣,后者構(gòu)造右手坐標系的View矩陣。下面我從MSDN拷貝一下它對這兩個函數(shù)的描述。攝像機矩陣和投影矩陣推導DirectXViewMatrix推導D3DXMATRIX*D3DXMatrixLookAtLH(__inout

D3DXMATRIX*pOut,__in

constD3DXVECTOR3*pEye,__in

constD3DXVECTOR3*pAt,__in

constD3DXVECTOR3*pUp);pOut

[in,out]Type:

D3DXMATRIX*Pointertothe

D3DXMATRIX

structurethatistheresultoftheoperation.攝像機矩陣和投影矩陣推導DirectXViewMatrix推導pEye

[in]Type:

const

D3DXVECTOR3*Pointertothe

D3DXVECTOR3

structurethatdefinestheeyepoint.Thisvalueisusedintranslation.pAt

[in]Type:

const

D3DXVECTOR3*Pointertothe

D3DXVECTOR3

structurethatdefinesthecameralook-attarget.攝像機矩陣和投影矩陣推導DirectXViewMatrix推導pUp

[in]Type:

const

D3DXVECTOR3*Pointertothe

D3DXVECTOR3

structurethatdefinesthecurrentworld'sup,usually[0,1,0].攝像機矩陣和投影矩陣推導DirectXViewMatrix推導MSDN描述的DirectXView矩陣構(gòu)造算法:攝像機矩陣和投影矩陣推導DirectXViewMatrix推導嗯,事實上我推導View矩陣之前首先是看了MSDN的View矩陣的,它沒有提供推導過程,只提供一個結(jié)果,但理解了這個結(jié)果之后,推導過程就很清晰了。攝像機矩陣和投影矩陣推導WikiD3DXMatrixLookAtLH,(v=vs.85).aspxViewTransform,(v=vs.85).aspx攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導首先說一下我對投影矩陣的感覺:由于我是初學者,目前我認為投影矩陣主要有兩個意義,第一是令離我們眼睛越遠的物體看起來越小,這個意義很大,因為它真實地模擬了現(xiàn)實中的視覺(想起我們看天上的飛機嗎?它和小鳥一樣小,因為它離我們很遠)。第二個意義是經(jīng)過投影變換后,更加方便裁剪那些不在視錐截體內(nèi)的頂點。攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導下面說一下視錐截體這個東西。事實上我們辛辛苦苦變換到Camera坐標系,就是為了它。眼睛望遠處時,視野形成一個視錐體,然后設(shè)想:離眼睛很近處存在一個平面,只要物體落在平面之前,就看不到,這個平面我們叫做近截面;同樣在遠處存在一個遠截面,只要物件在遠截面之后,我們也看不到。攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導這兩個截面將視錐體截斷成了一個菱臺體,叫做視錐截體。關(guān)于視錐截體,首先現(xiàn)實中我們的視錐體是一個圓錐,但計算機中它是一個4面錐體;現(xiàn)實中的確存在遠裁面,不過很遠,人眼在好天氣時可以看到20多公里,也存在近裁面,不過很近,貼近眼皮了。所以對遠近裁面,我也是不甚理解??赡苁强紤]到減少渲染物體的數(shù)量吧。攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導好,定義了視錐截體后,所有在視錐截體之外的頂點都被裁剪掉,不參與渲染了。見下頁的圖示。攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導

攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導把上圖平面化,也即只觀察YZ平面,如下:ZY攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導考察上圖的幾個頂點,根據(jù)視錐截體的定義,我們很容易把紅色的頂點裁剪掉,因為只需要比較他們的y分量或者z分量即發(fā)現(xiàn)它們不可能落在視錐截體之內(nèi)。但是對于藍色的那個頂點,就不容易了,因為需要判斷點落在視錐截體斜邊上方還是下方,這可能需要計算斜邊的方程(我覺得需要)。但如果借助投影矩陣,藍色點的裁剪會變得跟紅色點一般容易。攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導投影矩陣的目的是將視錐截體內(nèi)的點,都投影到近裁面(投影長方體)中。因為這個目的,它成功地使得:物體越遠看起來越??;以及方便裁剪頂點。我們由一個幅圖開始證明這兩點。簡明起見,我們把視錐截體平面化,仍然僅考慮YZ平面視圖,理解了YZ平面視圖后也就自然理解了XZ平面視圖了。如下圖所示:攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導

ZYP1P2eyeN-PlaneF-Planey1y2攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導如上圖所示,考察落在視錐截體內(nèi)的P1和P2兩點,它們的高度(也即Y值)是一樣的,但Z值不同,P2的Z值更大,也即是離眼睛更遠。但是,它們在近裁面N-Plane的投影點的Y值卻不同,P1的為y1,P2的為y2,顯然y1>y2,也即是在Y方向上,P1看起來要比P2高!這就是投影矩陣的第一目標:越遠越小。攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導y1為什么大于y2呢?嗯,首先從圖上可以直觀獲得結(jié)論。也可從數(shù)學上,我們通過相似三角形得到等式:上面前兩等式左右相除,注意到,即得第三個等式:又攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導至于投影矩陣讓頂點裁剪更方便,這點是非常明了的:因為經(jīng)過投影矩陣變換后,所有位于視錐截體內(nèi)的點,它們的X,Y坐標都被映射到近裁面N-Plane中(也即是映射后的坐標值X’,Y’小于或等于N-Plane的寬高),而N-Plane是一個長方形(事實上在投影坐標系里面它是一個邊長為2的正方形),所以只需要比較X和Y分量是否在N-Plane的寬高范圍內(nèi)即可!這個映射可以用下圖形象的表示出來:攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導

XYZ投影坐標系Camera坐標系投影長方體視錐截體攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導上圖視錐截體從一個菱臺經(jīng)過投影矩陣變換后,成為一個長方體,就像是投影矩陣把遠裁面F-Plane壓縮到跟N-Plane相同大小一般。這是因為投影矩陣使得菱臺內(nèi)所有點的X,Y經(jīng)過投影后,都<=N-Plane的寬高。另外,N-Plane的Z坐標轉(zhuǎn)換為0,也即是在投影坐標系中,原點不再是Camera坐標系的眼睛位置,而是N-Plane平面中心點。攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導事實上,投影長方體的邊長是既定的:DirectX約定,投影長方體的X,Y取值從-1到1,也即長度為2,而Z取值從0到1,也即長度為1。為了滿足DirectX這個約定,我們需要把點的X,Y坐標除以N-Plane的寬和高,Z則除以F-Plane和N-Plane的距離,這樣新得到的X,Y,Z都滿足了>=-1且<=1的約定。為什么DirectX會這樣約定呢?這個我也不甚清楚,可能是為方便后續(xù)裁剪等運算吧攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導至此,我們知道投影矩陣的目的以及其原理了。下面我們構(gòu)造投影矩陣:目標是讓視錐截體內(nèi)的點映射到投影長方體內(nèi),注意這個映射函數(shù)必須是嚴格單調(diào)的,也即不允許視錐截體內(nèi)多個點映射到投影長方體內(nèi)同一個點。和推導View矩陣一樣,我們對X,Y,Z軸逐個推導,然后再復合成一個矩陣。攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導

ZYPeyeN-PlaneF-PlaneyNPzHF攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導如上圖所示,考察YZ平面視圖,對視錐截體內(nèi)的點P,Y坐標為,我們來推導它在N-Plane平面投影的y值。圖中N表示近裁面N-Plane的距離,角表示視野在YZ平面的夾角,這個英文叫fov(fieldofview)。我們依據(jù)相似三角形構(gòu)造恒等式:,所以y為:前面提到y(tǒng)需要滿足DirectX的取值[-1~1]約定,所以我們對y除以N-Plane的一半高度攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導也即:,因為,故y的最終表示為:上面等式中,Py是P點在Camera坐標系中的Y值,可以是任意數(shù)字,例如1萬。而y是投影坐標系中P點的Y值,它的取值范圍已經(jīng)變?yōu)閇-1~1],跟1萬沒有關(guān)系了。這是因為我們對Py除以了H。H是N-Plane一半的高度。攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導求得P點在投影坐標系的Y值后,可以用同樣的方法求得它在投影坐標系的X值,這個就不畫圖了,我們可以輕易想象出來,只要把上圖的Y軸換成X軸,H換成W(W表示N-Plane一半的寬度),且換成,注意是指視野在YZ平面的夾角,而是視野在XZ平面的夾角,它們在現(xiàn)實中可以認為是相等的(因為現(xiàn)實中視錐是一個圓錐),但在計算機中他們往往是不等的,因為它們依賴于計算機屏幕的寬高比例。攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導好,這樣我們又得到x的表達式:上式也可以用來表達x,這是因為這兩個角度依賴于屏幕的寬高比例:現(xiàn)在只剩下z的表達式了。投影矩陣實際上并不關(guān)心z,但是由于我們的z必須滿足攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導DirectX對它的要求:取值范圍[0~1],所以,對z除以F-Plane與N-Plane之間的距離即可,也即:其中F-N表示兩個裁面之間的距離,此處Pz需要減去N一是因為在投影坐標系中原點變?yōu)镹-Plane的中心點,而不是眼睛點,二是除以F-N才會<=1。事實上,上式根本不滿足矩陣要求,這里記錄下來作為一個思考的過程。攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導至此,我們的投影矩陣差不多出來了,它現(xiàn)在看起來像這樣:但這個矩陣內(nèi)含變量Pz,我們知道轉(zhuǎn)換矩陣是不能含有未知量的。怎么辦呢?攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導因為未知量是,我們自然想到把它提到矩陣外,類似這樣:但是這個矩陣仍然有兩個問題,第一z分量并沒有消除Pz,第二是點變換已不能由一個矩陣相乘解決,還需多一個標量相乘。攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導先來解決第二個問題,由于4D齊次向量變換回3D向量時,會用w(也即最后一個分量)除以所有分量,以確保w分量一定是1,這個是在轉(zhuǎn)換管線的最后階段由硬件完成(參看前面MSDN的轉(zhuǎn)換管線)。那么我們可以利用這個特性來解決第二個問題。攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導也即:讓我們的頂點經(jīng)過投影矩陣轉(zhuǎn)換后,X,Y,Z分量都多帶了一個Pz因子的,但這不要緊,因為W分量也是Pz,而我們知道最后頂點會被除以W也即除以Pz,這樣我們的頂點的X,Y,Z就恢復到正確的數(shù)值了。攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導根據(jù)這個思想,修改我們那個半成品矩陣,把x,y,z的去掉,同時讓w分量成Pz(令第4列3行的元素為1):嗯,現(xiàn)在看起來帥一些了,只剩下第一問題了,見矩陣紅色部分:仍然有未知量Pz攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導下面我們來改造z的表達式,使得它滿足矩陣的要求。事實上,先理解表達式的問題所在:因為w的分量是Pz,也即z最終會被除以Pz,那么矩陣相乘后z應該為:只有這樣,才能在最后除以W時得到攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導問題是這個表達式無論如何都不可通過矩陣乘法獲得,因為它含有Pz的二次方。除非矩陣元素含有Pz,但這又使得矩陣含有未知量了。我們可以在紙上算一下,即可確認這個事實:當轉(zhuǎn)換矩陣不含有Pz時,我們的頂點向量和矩陣相乘絕對不可能得到Pz的二次方,只能得到Pz的一次方,或者0。也就是說,這個映射函數(shù)不能滿足我們要求。我們需要構(gòu)建新的映射函數(shù)。攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導我們需要構(gòu)造一個新函數(shù),和一樣,值域是[0~1],且嚴格單調(diào)遞增,當Pz等于N時取得最小值0,當Pz等于F時取得最大值1。依據(jù)矩陣乘法規(guī)律,我們的點向量和矩陣相乘后,z分量可表述為:經(jīng)過4D到3D的除法(除w)后,成這樣:攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導我們?nèi)绻芮蟪鍪阶又械暮?,把它們填入矩陣即可完成z的轉(zhuǎn)換。我們怎樣求解這兩個變量呢?根據(jù)前面的約定,也該是嚴格單調(diào)遞增的,而且當Pz=N時取得最小值0,當Pz=F時取得最大值1,由此我們可以用此信息構(gòu)建方程組,把和解出來。攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導當Pz等于N時,,當Pz等于F時,聯(lián)合兩個等式成二元方程組:解得到:攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導那么:顯然z是嚴格單調(diào)遞增的。且Pz等于N時z=0,Pz等于F時z=1。攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導嗯,z的表達式終于確定了。那么最終的投影矩陣是這樣子:攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導和View矩陣一樣,DirectX為了免除我們構(gòu)造投影矩陣的繁瑣,它也提供了3組API來構(gòu)造左右手坐標系的投影矩陣,事實上這3組函數(shù)原理相同,其矩陣的構(gòu)造算法和我們的推導過程一致。這里我們抄錄D3DXMatrixPerspectiveFovLH作為示例。攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導D3DXMATRIX*D3DXMatrixPerspectiveFovLH(__inout

D3DXMATRIX*pOut,__in

FLOATfovy,__in

FLOATAspect,__in

FLOATzn,__in

FLOATzf);pOut

[in,out]Type:

D3DXMATRIX*Pointertothe

D3DXMATRIX

structurethatistheresultoftheoperation.

攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導fovy

[in]Type:

FLOATFieldofviewintheydirection,inradiansAspect

[in]Type:

FLOATAspectratio,definedasviewspacewidthdividedbyheight.攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導zn

[in]Type:

FLOATZ-valueofthenearview-plane.zf

[in]Type:

FLOATZ-valueofthefarview-plane.攝像機矩陣和投影矩陣推導DirectXProjectionMatrix推導MSDN給出的DirectX的投影矩陣構(gòu)造攝像機矩陣和投影矩陣推導WikiViewportsandClipping,(v=vs.85).aspxProjectionTransform,(v=vs.85).aspx攝像機矩陣和投影矩陣推導DirectXViewport轉(zhuǎn)換矩陣非視錐截體內(nèi)的頂點會被投影轉(zhuǎn)換過程裁剪掉,而視錐截體內(nèi)的頂點經(jīng)過投影矩陣變換到投影坐標系后,它的X,Y坐標取值范圍是[-1~1],Z坐標取值范圍是[0~1]。接下來要將這些點繪制到屏幕上。屏幕的寬度W高度H需要我們給定,通過設(shè)置DirectX的Viewport屬性,來告知DirectX如何將點繪制到屏幕上。攝像機矩陣和投影矩陣推導DirectXViewport轉(zhuǎn)換矩陣DirectX的對應API為:SetViewport。HRESULTSetViewport([in]

constD3DVIEWPORT9*pViewport);pViewport

[in]Type:

const

D3DVIEWPORT9*Pointertoa

D3DVIEWPORT9

structure,specifyingtheviewportparameterstoset.攝像機矩陣和投影矩陣推導DirectXViewport轉(zhuǎn)換矩陣關(guān)鍵是填充D3DVIEWPORT9結(jié)構(gòu)體。攝像機矩陣和投影矩陣推導DirectXViewport

溫馨提示

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

評論

0/150

提交評論