寫(xiě)給大家看的“透視除法” —— 齊次坐標(biāo)和投影

3D投影

圖片來(lái)源:Joachim Baecker.

術(shù)語(yǔ)

在大多數(shù)3D工作中针贬,我們參照的依據(jù)是歐幾里得幾何學(xué)中的三維空間(X, Y, Z)赴背。但在某些情況下,參照投影幾何更適用嫉称,除了 X, Y, Z 分量外,增加一個(gè) W 分量灵疮,這個(gè)四維空間叫做“投影空間”织阅,在四維空間中的坐標(biāo)叫“齊次坐標(biāo)”。
為了達(dá)到3D軟件的目的始藕,“投影的” 和 “齊次的” 可以理解為 "4D"蒲稳。

不是四元數(shù)

雖然四元數(shù)跟齊次坐標(biāo)長(zhǎng)得很像氮趋,都是 4D 矢量伍派,通常用(X, Y, Z, W)來(lái)表示江耀。但是,四元數(shù)和齊次坐標(biāo)是不同的概念诉植,適用的領(lǐng)域也不同祥国。
這篇文章跟“四元數(shù)”沒(méi)有一毛錢(qián)關(guān)系。

類(lèi)比2D

了解3D之前晾腔,我們先看看2D的投影是怎么回事兒舌稀。
想象投影儀在一個(gè)屏幕上投影一張2D圖片,很容易就可以得到投影圖片的 X, Y 分量灼擂。


在屏幕上投影2D圖片

現(xiàn)在壁查,看投影儀和屏幕之間,你就可以發(fā)現(xiàn) W 分量了剔应。
W 分量是投影儀到屏幕的距離

W分量

那么 W 分量的作用是什么呢睡腿?想象一下,如果我們移動(dòng)投影儀的位置峻贮,來(lái)增加或減少 W分量的值席怪,那么投影出的2D圖片會(huì)發(fā)生什么?如果將投影儀靠近屏幕纤控,2D圖片縮小挂捻,如果投影儀遠(yuǎn)離屏幕,2D圖片放大船万。沒(méi)錯(cuò)刻撒,這就是 W 分量的作用。

W 分量的值耿导,影響了投影出 2D 圖片的大小

投影儀靠近屏幕

應(yīng)用到3D

到目前為止声怔,還沒(méi)有一個(gè)3D投影儀,很難想象3D中的投影幾何碎节,但是 3D 下的 W 分量與 2D 的作用相同捧搞。當(dāng) W 增大,坐標(biāo)被拉伸狮荔;W 縮小胎撇,坐標(biāo)被壓縮, W 對(duì)3D坐標(biāo)做縮放變換殖氏。

W = 1時(shí)

通常晚树,給3D編程初學(xué)者的建議是,無(wú)論什么時(shí)候?qū)?3D 坐標(biāo)轉(zhuǎn)換為 4D 坐標(biāo)時(shí)雅采,讓 W=1爵憎。原因是慨亲,當(dāng)縮放坐標(biāo)的 W 為1時(shí),坐標(biāo)不會(huì)增大或縮小宝鼓,保持原有的大小刑棵。所以,當(dāng) W=1愚铡,不會(huì)影響到 X, Y, Z 分量的值蛉签。
因此,當(dāng)談?wù)摰?3D 計(jì)算機(jī)圖形學(xué)時(shí)沥寥,當(dāng)坐標(biāo)中 W=1時(shí)被稱作“正確”碍舍。如果渲染使用 W>1 的坐標(biāo),每一個(gè)3D物體看起來(lái)都會(huì)變大邑雅,反之片橡,W<1 的坐標(biāo)中,3D物體會(huì)變谢匆啊捧书;如果渲染時(shí)試圖讓 W=0,那么你的程序會(huì)奔潰录煤,當(dāng)做透視除法的時(shí)候除數(shù)為0鳄厌;如果 W<0,每一個(gè)物體都會(huì)上下翻轉(zhuǎn)妈踊,水平翻轉(zhuǎn)了嚎。
在數(shù)學(xué)中,沒(méi)有所謂的“不正確”的齊次坐標(biāo)廊营,使用齊次坐標(biāo)時(shí)讓 W=1 僅僅是用于計(jì)算機(jī)圖形學(xué)中的投影轉(zhuǎn)換歪泳。

數(shù)學(xué)原理

現(xiàn)在,讓我們來(lái)看一些例子露筒,了解數(shù)學(xué)原理
在距屏幕3米遠(yuǎn)的位置放一個(gè)投影儀呐伞,投影出一個(gè)點(diǎn)(15, 21)在 2D 圖像中,相應(yīng)的投影坐標(biāo)中的向量為 (X, Y, W)=(15, 21, 3)慎式。


距屏幕3米遠(yuǎn)投影一個(gè)點(diǎn)

現(xiàn)在伶氢,想象推動(dòng)投影儀向屏幕靠近,直到距離1米瘪吏,越靠近屏幕投影癣防,投影出的圖像越小。投影儀靠近了3倍掌眠,因此圖像縮小了3倍蕾盯。如果我們將原向量的 X, Y, W 分量都除以 3,我們得到一個(gè)新向量 W=1:


W=1的新向量

投影出的點(diǎn)在坐標(biāo)中的新位置(5, 7)


同一個(gè)點(diǎn)在距屏幕1米遠(yuǎn)處投影

這就是怎樣將一個(gè)“不正確”齊次坐標(biāo)轉(zhuǎn)換到一個(gè)“正確”坐標(biāo)的方法:所有分量除以 W蓝丙,這個(gè)過(guò)程對(duì) 2D 和 3D 同樣適用级遭。
通過(guò)給向量乘以 W 的倒數(shù)望拖,來(lái)實(shí)現(xiàn)向量的所有分量除以 W,下面是一個(gè)4D的例子:


透視除法

用 GLM 庫(kù)編寫(xiě)挫鸽,類(lèi)似如下實(shí)現(xiàn):

glm::vec4 coordinate(10, 20, 30, 5);
glm::vec4 correctCoordinate = (1.0/coordinate.w) * coordinate;
//now, correctCoordinate == (2,4,6,1) 

在計(jì)算機(jī)圖形學(xué)中使用齊次坐標(biāo)

就像開(kāi)始提到的说敏,針對(duì)3D 計(jì)算機(jī)圖形學(xué)中,有些情況下使用齊次坐標(biāo)很有用掠兄,下面我們來(lái)看看這些情況:

3D 坐標(biāo)中的轉(zhuǎn)換矩陣

旋轉(zhuǎn)縮放的轉(zhuǎn)換矩陣只需要3列像云,但是為了處理平移锌雀,至少需要4列矩陣蚂夕,這就是為什么矩陣變換通常用4×4的矩陣。然而腋逆,4列矩陣不能與3維向量相乘婿牍,只能與4維向量相乘,這就是為什么我們使用齊次的4維向量取代3維向量惩歉。

4列矩陣只能與4維向量相乘等脂,這就是為什么我們常常使用齊次的4維向量取代3維向量。

通過(guò)齊次坐標(biāo)處理矩陣變化撑蚌,第4維 W 分量通常不用改變上遥。從3D轉(zhuǎn)換到4D,只需將 W 分量設(shè)置為1争涌,并且經(jīng)過(guò)變換矩陣處理后粉楚,W 分量的值任為1,這意味著我們忽略 W 分量即可轉(zhuǎn)換回 3D坐標(biāo)亮垫。這個(gè)對(duì)目前為止大多數(shù)的矩陣變化都適用模软,如平移旋轉(zhuǎn)饮潦、縮放燃异。需要注意的例外是投影矩陣會(huì)影響 W 分量。

透視變換

在 3D 世界继蜡,物體離相機(jī)越遠(yuǎn)看起來(lái)越小回俐,這個(gè)現(xiàn)象叫做透視。在鏡頭中稀并,如果貓離相機(jī)足夠近仅颇,遠(yuǎn)處的大山會(huì)比貓看上去小。

透視稻轨,遠(yuǎn)處的大山比鏡頭前的貓看上去小

在3D計(jì)算機(jī)圖形學(xué)中灵莲,透視是通過(guò)變換矩陣改變向量的 W 分量來(lái)實(shí)現(xiàn)的。在變換到相機(jī)空間后(對(duì)向量應(yīng)用了相機(jī)矩陣)殴俱,還沒(méi)有進(jìn)行投影變換(還沒(méi)有對(duì)向量應(yīng)用投影矩陣)政冻,每個(gè)向量的 Z 分量表示了距離相機(jī)的距離枚抵。因此,Z 分量越大明场,矢量應(yīng)該越小汽摹。W 分量影響這個(gè)縮放,所以投影矩陣用 Z 分量的值改變 W 分量的值苦锨。

在3D計(jì)算機(jī)圖形學(xué)中逼泣,透視是通過(guò)投影矩陣變換,改變每一個(gè)向量中 W 分量的值來(lái)實(shí)現(xiàn)透視的

下面看一個(gè)透視例子舟舒,通過(guò)投影矩陣變換到齊次坐標(biāo)拉庶。


投影矩陣變化到齊次坐標(biāo)

注意投影矩陣是怎樣用 Z 分量改變 W 分量的。
經(jīng)過(guò)投影矩陣透視變換后秃励,每一個(gè)向量即經(jīng)過(guò)了“透視除法”氏仗。

透視除法只是將齊次坐標(biāo)中的 W 分量轉(zhuǎn)換為1的專(zhuān)用名詞

繼續(xù)上面的例子,透視除法這步如下:


透視除法

完成透視除法后夺鲜,W分量就沒(méi)用了皆尔,我們就得到了一個(gè)完全符合3D透視投影規(guī)則的3D坐標(biāo)。
在GLM中币励,透視投影矩陣可以通過(guò)使用 glm::perspectiveglm::frustum方法來(lái)創(chuàng)建慷蠕。在老式的 OpenGL 中,通常使用gluPerspectivegluFrustum 方法食呻。在 OpenGL 中流炕,在頂點(diǎn) shader 作用了每一個(gè)頂點(diǎn)后,自動(dòng)進(jìn)行透視除法搁进。這就是頂點(diǎn) shader 中 main 方法輸出的 gl_position 變量浪感,是4維向量,而不是3維向量饼问。

設(shè)置平行光

齊次坐標(biāo)中的一個(gè)屬性影兽,是允許有一個(gè)無(wú)限遠(yuǎn)的點(diǎn)(或無(wú)限長(zhǎng)的向量),在3D坐標(biāo)中這個(gè)是不允許的莱革。當(dāng) W=0 時(shí)峻堰,這點(diǎn)表示無(wú)限遠(yuǎn)的一個(gè)點(diǎn)。如果你嘗試將一個(gè) W=0 的齊次坐標(biāo)轉(zhuǎn)換為一個(gè)普通的 W=1的齊次坐標(biāo)盅视,這會(huì)導(dǎo)致4次除0操作:

試圖將 W=0 的齊次坐標(biāo)轉(zhuǎn)換為普通的 W=1 的齊次坐標(biāo)

這意味著捐名,不能將 W=0 的齊次坐標(biāo)轉(zhuǎn)換到 3D 坐標(biāo)。
那這有什么用呢闹击?用處說(shuō)來(lái)就來(lái)了镶蹋,平行光可以認(rèn)為是一個(gè)無(wú)限遠(yuǎn)處的點(diǎn)光源。當(dāng)一個(gè)點(diǎn)光源在無(wú)限遠(yuǎn)的位置,光線就會(huì)變成平行的贺归,并且所有光線都在同一方向淆两,這就是平行光的基本定義。想想太陽(yáng)吧拂酣。
所以在傳統(tǒng)的3D圖形中秋冰,平行光可以通過(guò)改變點(diǎn)光源位置向量中的 W 分量來(lái)表示,當(dāng) W= 1時(shí)婶熬,是一個(gè)點(diǎn)光源剑勾;當(dāng) W= 0 時(shí),是一個(gè)平行光赵颅。
在實(shí)現(xiàn)光照代碼時(shí)虽另,這更多的是一種傳統(tǒng)的約定,但不是一種有用的方法性含。因?yàn)槠叫泄夂忘c(diǎn)光源的行為不同洲赵,通常分開(kāi)實(shí)現(xiàn)。一個(gè)經(jīng)典的光照 shader 實(shí)現(xiàn)如下:

if (lightPosition.w == 0.0) {    
  //directional light code here
} else {
  //point light code here
}

總結(jié)

齊次坐標(biāo)有一個(gè)額外的維度叫 W 分量商蕴,用來(lái)縮放X, Y, Z三個(gè)分量的值。平移和透視投影的矩陣變換只能在齊次坐標(biāo)中使用芝发,所以在3D計(jì)算機(jī)圖形學(xué)中绪商,當(dāng) W=1時(shí),X, Y, Z 分量被稱為“正確的”辅鲸。任何齊次坐標(biāo)格郁,只要 W 不為0,都可以通過(guò)將每一個(gè)分量除以 W 來(lái)轉(zhuǎn)換到 W=1的向量独悴。當(dāng) W=0 時(shí)例书,這個(gè)坐標(biāo)表示無(wú)窮遠(yuǎn)的一個(gè)點(diǎn)(或者表示無(wú)限長(zhǎng)的一個(gè)向量),通常用于表示平行光的方向刻炒。

原文:Explaining Homogeneous Coordinates & Projective Geometry

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末决采,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子坟奥,更是在濱河造成了極大的恐慌树瞭,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件爱谁,死亡現(xiàn)場(chǎng)離奇詭異晒喷,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)访敌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)凉敲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事爷抓∮晷В” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵废赞,是天一觀的道長(zhǎng)徽龟。 經(jīng)常有香客問(wèn)我,道長(zhǎng)唉地,這世上最難降的妖魔是什么据悔? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮耘沼,結(jié)果婚禮上极颓,老公的妹妹穿的比我還像新娘。我一直安慰自己群嗤,他們只是感情好菠隆,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著狂秘,像睡著了一般骇径。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上者春,一...
    開(kāi)封第一講書(shū)人閱讀 49,144評(píng)論 1 285
  • 那天破衔,我揣著相機(jī)與錄音,去河邊找鬼钱烟。 笑死晰筛,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的拴袭。 我是一名探鬼主播读第,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼拥刻!你這毒婦竟也來(lái)了怜瞒?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤泰佳,失蹤者是張志新(化名)和其女友劉穎盼砍,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體逝她,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡浇坐,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了黔宛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片近刘。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出觉渴,到底是詐尸還是另有隱情介劫,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布案淋,位于F島的核電站座韵,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏踢京。R本人自食惡果不足惜誉碴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望瓣距。 院中可真熱鬧黔帕,春花似錦、人聲如沸蹈丸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)逻杖。三九已至奋岁,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間弧腥,已是汗流浹背厦取。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留管搪,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓铡买,卻偏偏與公主長(zhǎng)得像更鲁,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子奇钞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

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