深入研究透視投影變換

2021-09-01 07:14:42 字數 2497 閱讀 1694

深入研究透視投影變換

3d世界變換主要有世界變換、觀察變化、投影變換。世界變換做的事情是把座標從模型空間變換到世界空間,而觀察變換是把座標從世界空間變換到觀察空間。3d世界裡,所有的物體(包括相機等)都可以認為是3d模型,他們開始建立的時候都是處於自身座標系內,渲染的時候,我們需要把這些模型從模型空間最終變換到統一的觀察空間(相機自身空間)以方便進行裁剪等操作,最後,再經過透視投影變換將座標變換到統一的立方體空間內。

在這三種變換中,投影變換最麻煩,越是麻煩的事情,越是需要整理一下思路,下面是我在做「將螢幕座標轉換為三維射線」演算法研究中的一些想法,記錄下來以供將來察看.

投影變換就做一件事:將錐形的觀察空間轉化為單位立方體空間。

上圖是觀察空間,其中近裁剪面可以認為是計算機內的乙個3d圖形顯示視窗或者螢幕,經過觀察變化後,只有處於此錐形空間內的物體才會最終顯示在使用者面前。

上圖是觀察空間的yz圖,我們據此推出座標之間的關係:

y = ± z * tan(fov/2),x = y*aspect

上圖是投影空間的可見範圍,這個空間處於你所見到的螢幕上。實際上將螢幕表面視作投影空間的xoy平面,再加一條垂直螢幕向里(或向外)的z軸(這取決於你的座標系是左手系還是右手系),這樣就構成了我們想要的座標系。好了,現在我們可以用視口(view port)的大小來描述這個可視範圍了。比如說全螢幕640*480的解析度,原點在螢幕中心,那我們得到的可視區域為乙個長方體,它如圖(a)所示。

從圖(a)變換到圖(b)需要經過視口變換,目的是將螢幕座標(0< span>)變換到[-1,+1]的範圍內。下面是將螢幕座標變換到視口座標的轉換過程

接下來,我們處理視口空間到觀察空間的轉換。

由於在觀察空間內,y = ± z * tan(fov/2),x = y*aspect

而在投影空間內,x』和y』都屬於[-1,+1],因此我們推出從觀察空間到投影空間的變換公式,如下:

y』 = y * cot(fov/2) / z, x』 = x * cot(fov/2) /(z* aspect)

我們可以看到,從(x,y)變換到(x』,y』)是一次非線性變換,為了用矩陣來表達這個轉換過程,我們就得用w這個分量了,為什麼這麼有用呢?我們可以想到,在世界變換和觀察變換這兩個過程內,我們對座標的操作都是一些平移、旋轉、縮放操作,仔細觀察這些變換矩陣,我們可以發現這些矩陣的第四列元素均是(0 0 0 1),因此向量與矩陣相乘後,w分量並不會改變。換句話說,只要不是故意,乙個w分量等於1的向量,再來到投影變換之前他的w分量仍舊等於1。好的,接下來我們讓w』= w*z, 新的w』就記錄下了view空間中的z值;同時在x,y分量上我們退而求其次,只要做到y』 = y * cot(fov/2), x』 = x * cot(fov/2) /aspect。那麼,在做完線性變換之後,我們再用向量的y除以w,就得到了我們想要的最終的y值。

現在只剩下z分量了。我們所渴望的變換應將z = znear 變換到z = 0,將z = zfar變換到z = 1。這個很簡單,但是等等,x, y最後還要除以w,你z怎能例外。既然也要除,那麼z = zfar 就不能對映到z = 1了。唔,先對映到z = zfar試試。於是,有z』 = zfar*(z-znear)/(zfar – znear)。接下來,看看z』/z的性質。令f(z) = z』/z = zfar*(z-znear)/(z*(zfar – znear))。

則f』(z) = zfar * znear / ( z^2 * (zfar –znear )), 顯而易見f』(z) > 0。所以除了z = 0是乙個奇點,函式f(z)是乙個單調增的函式。因此,當znear≤z≤zfar時,f(znear)≤f(z)≤f(zfar),

即0≤f(z)≤1。

至此,我們可以給出投影變換的表示式了:  

x』 = x*cot(fov/2)/aspect  

y』 = y*cot(fov/2)  

z』 = z*zfar / ( zfar – znear ) – zfar*znear / ( zfar – znear ) 

w』 = z

以矩陣表示,則得到變換矩陣如下,  

cot(fov/2)/aspect 0 0 0  

0 cot(fov/2) 0 0  

0 0 zfar/(zfar-znear) 1  

0 0 -zfar*znear/(zfar-znear) 0

做完線性變換之後,再進行所謂的「歸一化」,即用w分量去除結果向量。

為了驗證這一研究結果,我們可以察看dx9文件,發現投影矩陣就是我們在上面推出的矩陣,因此,我們可以得出結論,經過d3d提供的投影函式,我們可以得到投影矩陣m,為了將觀察空間內的座標變換到投影空間,我們首先要將觀察空間內的向量稱上矩陣m以執行線性變換,然後再將得到的向量除以w分量,就可以得到最終的投影空間內的向量了。

為了簡化上述步驟,direct manager提供了乙個函式transformcoordinate函式,該函式內部直接將w分量「歸一化」為1了。因此,我們只需將觀察空間內的向量乘上此投影矩陣就可以得到投影空間內的向量了。

同理,如果我們想從二維的螢幕座標轉化到模型空間內的座標,就需要執行上述過程的逆過程:視口變換-->投影逆變換-->觀察逆變換-->世界逆變換。

讀Twinsen的深入探索透視投影變換

2017.10.16更新,分割線下面是以前的文字,有表達的意思,卻言不達意,實屬羞恥,看官只需看前面文字即可。twinsen大神的 深入探索透視投影變換 有幾個點說得不夠清晰,我這裡提一下 1.p 代表的是 面的投影點,p 代表的是p 對映到單位立方體後的投影點 2.原文 事實上是透視投影變換由兩步...

二維透視投影變換

如下圖,位於xy平面的單位正方形投影到任意平面p上後,變成了不規則的四邊形abcd,我們能根據正方形的四個頂點投影前後的座標,計算出平面xy上任意點 x,y 投影到平面p 上之後的座標 x y 嗎?我們注意到正方形的四個邊投影到平面p之後,分別變為線段ab,bc,cd,da,也就是說投影前位於一條直...

投影變換 透視投影和正交投影

2.3 投影變換 3.2.3.1 基本概念 在計算機圖形軟體中所採用笛卡爾 cartesian 直角三維座標系統,按照 z軸方向的不同有兩種形式 1 右手系統 當用右手握住 z軸時,大姆指指向 z軸的正方向 圖 3.20 a 其餘四個手指從x軸到 y軸形成乙個弧。2 左手系統 當用左手握住 z軸時,...