《Real Time Rendering》第四章 圖形變換


圖形變換是一個將例如點、向量或者顏色等實體進行某種轉換的操作。對於計算機圖形學的先驅者,掌握圖形變換是極為重要的。有了他們,你就可以對象、光源以及攝像機進行定位,變形以及動畫添加。你也可以確認所有的計算都是在同一個坐標系統下面進行的,而物體以不同的方式投影到平面上。在圖形變換只有少數操作運行,但它們足以證明圖形變換在實時圖形學中的重要性,甚至可以說是任何一種計算機圖形學。

線性變換是一種保留了向量加法和標量乘法的變換。具體如下:

f(x) + f(y) = f(x+y), kf(x) = f(kx)                                   (4.1)

例如,f(x)=5x就是變換,即將向量中的每個元素都乘以5。這種變換是線性的,因為兩個向量先乘以5再相加的出的結果與它們先相加后乘以5的結果是一樣的。標量乘法條件是滿足的。這個函數叫做縮放變換,因為它改變了對象的縮放比例(尺寸)。使向量繞原點轉動的旋轉變換是另一種線性變換。縮放和旋轉變換,以及所有用於三元向量的線性變換,都可以用一個3×3的矩陣表示。

然而,這個矩陣的大小還不夠。用於三元向量x的函數,例如f(x)=x+(7,3,2)不是線性的。分別在兩個向量上運行這個函數時,會將(7,3,2)中的每個元素都加兩次而形成結果。將一個固定數值的向量加到另一個向量上是執行了平移,即是,它以同樣的大小移動所有位置。這是一種十分有用的變換類型,而我們希望將各種變換組合到一起,例如,將對象縮小至一半,移動它到不同的位置。目前為止保持函數的簡單形式,使得很難將它們組合起來。

線性變換和平移的結合可以通過仿射變換實現,典型的是將其存儲在一個4×4的矩陣中。仿射變換執行線性變換,接着進行平移。為代表四元向量,我們使用以同樣方法(粗體小寫)指示點和方向的齊次標記。v = (vx vy vz 0)T代表一個方向向量,而v = (vx vy vz 1)T代表一個點。在這一章,我們會大量使用到附錄A中解釋的術語。你現在或許需要看看附錄,特別是905頁的關於齊次標記的A.4章節。

所有的平移,旋轉,縮放,反射,以及剪切矩陣都是仿射的。仿射矩陣的主要特點是它保持了直線間的平行關系,但不一定保持其長度和角度。一個仿射變換也可以多個個體仿射變換的任意次序的連接。

這一章節將從最基本的,最基礎的仿射變換開始。這確實是很基本的,並且這章節可以看着簡單轉換的“參考手冊”。然后更多的是關於專用矩陣的描述,接着的是一個強大的圖形變換工具——四元數的描述。然后是頂點混合和變形,這兩者都是簡單但功能強大的網格的動畫表示方式。最后,投影矩陣被描述。大部分的圖形變換,他們的符號,函數和屬性將在表格4.1中總結。

圖形變換是一個操縱幾何圖形的基本工具。所有的圖形應用程序編程接口(APIs)包含了矩陣操作,這些操作實現了很多這章所討論的圖形變換。但是去了解真正的矩陣,以及它們在函數調用背后的互動是值得的。知道在函數調用后矩陣做了什么只是一個開始,但理解矩陣本身的屬性會讓你更為深入。例如,當你正處理正交的矩陣時,這些理解能幫助你認識到它的逆矩陣也就是它的轉置矩陣(見904頁),從而得出更快的矩陣求逆。這類知識可以優化代碼,加速執行。

符號

名稱

特性

T(t)

平移矩陣

移動一個點。

仿射。

Rx(ρ)

旋轉矩陣

繞x軸旋轉ρ的角度。相似的標記用於y軸和z軸。

正交且仿射。

R

旋轉矩陣

所有的旋轉矩陣。

正交且仿射。

S(s)

縮放矩陣

根據s,沿x、y、z軸進行縮放。

仿射。

Hij(s)

剪切矩陣

相對j對i進行參數為s的剪切變形,i, j∈{x, y, z}。

仿射。

E(h, p, r)

歐拉變換

歐拉角(head/yaw,pitch,roll)給出的朝向矩陣。

仿射。

Po(s)

正交投影

向某個平面或體積進行平行投影。

仿射。

Pp(s)

透視投影

向一個平面或體積進行透視投影。

slerp()

插值變換

根據四元數和以及參數t,創建一個插值的四元數

表格4.1 這一章中討論的大部分圖形變換的總結

4.1 基本圖形變換

這一節描述了最基本的圖形變換,例如平移,旋轉,縮放,剪切,圖形變換的連結,剛體轉換,法線變換(這並不常見),和矩陣求逆。對於已有相應經驗的讀者,這可以用作簡單圖形變換的參考手冊;而對於新手,它可以用作該主題的入門。這些材料是這章剩余部分以及本書中其它各章的必須的背景知識。我們從最簡單的變換——平移變換開始。

4.1.1 平移

由一個位置到其他位置的變換是由平移矩陣,T所代表。這個矩陣通過一個向量t=(tx,ty,tz)變換一個實體。下面的方程4.2給出T:

wps_clip_image-11243                                 (4.2)

圖4.1展示了平移變換產生的效果。容易看到的是一個點P=(px, py, pz, 1)與T(t)相乘產生新的點P’=(px+tx, py+ty, pz+tz, 1),這就是平移。注意到向量v=(vx, vy, vz, 0)左乘T后沒有變化,因為一個方向向量不能被平移。相反的,其余的仿射變換都能影響點和向量。平移矩陣的逆矩陣是T-1(t)=T(-t),換句話說,向量t是取反的。

wps_clip_image-5622

圖4.1 左邊的一個正方形被平移矩陣T(5,2,0)所轉換,據此,正方形向右移動了5個單元而向上移動了2個單元。

4.1.2 旋轉

一個旋轉變換繞給定的過原點的軸將一個向量(位置或方向)旋轉給定的角度。就像平移變換那樣,它是剛體變換,也就是它保存被變換的點之間的距離,並且保持旋向性(也就是說他從不會使圖形左右交換)。這兩種圖形變換在計算機圖形學中的物體的定位和定向是十分有用的。一個方向矩陣是一個與攝像機視圖或者一個定義其在空間中的朝向的對象相關的旋轉矩陣,也就是說他的方向是向上和向前。常用的旋轉矩陣是Rx(φ),Ry(φ)和Rz(φ),它們使實體繞相應的x,y和z軸轉動φ個弧度。方程4.3~4.5給出了相應的矩陣:

wps_clip_image-3835                                (4.3)

wps_clip_image-27820                                  (4.4)

wps_clip_image-28365                                  (4.5)

對於每個3×3的旋轉矩陣,R,繞任何軸旋轉φ弧度,它的跡(定義見898頁)是獨立於軸的常量,計算如下:

tr(R) = 1 + 2cosφ                                             (4.6)

可以在62頁的圖4.4看到旋轉矩陣的效果。Ri(φ)表征一個旋轉矩陣,除了它繞i軸轉動φ個弧度外,它還保持i軸上所有的點不變。注意到R也用於指示繞任意軸的旋轉矩陣。上面給出的軸旋轉矩陣可用於一系列的三個圖形變換去執行繞任意軸的旋轉。這個過程將在4.2.1節中討論。4.2.4節中直接涵蓋了執行一個繞任意軸的旋轉。

所有的旋轉矩陣行列式為1並且是正交的,十分容易通過904頁的附錄A給出的正交矩陣定義去驗證。對於任意數量的這種變換的連接,這個性質也是保持的。這是另一個獲得逆矩陣的方法:Ri-1(φ) = Ri(-φ),也就是,繞同一軸的相反方向轉動。因為旋轉矩陣是正交,其行列式總是為1.

例子:繞一個點旋轉。假設我們想讓一個對象以z軸為軸,以某個點P為旋轉中心,旋轉φ弧度。這是什么圖形變換?這個情景在圖4.2中描繪。因為一個繞一點的旋轉的特點是點本身事實上不能被旋轉所影響,於是圖形變換首先平移對象,通過T(-p)使得P與原點重合。其后接着的是真正的旋轉:Rz(φ)。最后,對象使用T(p)被平移回原來的位置。產生的變換,X,如下

X=T(p)Rz(φ)T(-p)                                         (4.7)

wps_clip_image-30333

圖4.2 繞指定點P旋轉的例子。

4.1.3 縮放

一個縮放矩陣,S(s)=S(sx, sy, sz),根據對應x,y和z軸的因子sx,sy,sz縮放一個實體。這意味着一個縮放矩陣可以用於物體的放大縮小。si(i∈{x, y, z})越大,縮放的實體在相應的方向就越大。將S的任何分量設置為1通常避免該方向發生縮放變化。方程4.8展示了S:

wps_clip_image-22050                                        (4.8)

62頁的圖4.4展示了縮放矩陣的效果。如果sx=sy=sz則將縮放操作叫做一致的,否則就是不一致的。有時會用各向同性和各向異性代替一致的和不一致的。其逆矩陣為S-1(s)=S(1/sx, 1/sy, 1/sz)。

另一個使用齊次坐標創建一個一致的縮放矩陣的合法方法是操縱矩陣中位於(3,3)位置的元素,也就是右下角的元素。這個數字影響齊次坐標的w分量,因此所有的坐標都通過矩陣進行縮放變換。例如,一致地以因子5進行縮放,(0,0),(1,1)(2,2)位置上的元素可以設置為5,或者(3,3)位置上的元素設置為1/5。執行這個操作的兩個不同矩陣如下:

wps_clip_image-12355,    wps_clip_image-24355                           (4.9)

與將S用於一致縮放相反,S’的使用必須遵守均勻化,縮放要一致。這可能是低效的,因為它在均勻化過程中涉及了除法;如果右下角((3,3)位置)的元素為1,則不需要相除。當然,如果系統總是執行除法而不先測試除數為1,那么這里就沒有額外的消耗。

一或三個S分量為一負值給出了反射矩陣,也叫做鏡像矩陣。如果只有兩個縮放因子是-1,那么我們會旋轉π個弧度。當發現反射矩陣時,通常需要特殊處理。例如,一個頂點順序是逆時針的三角形經過反射變換后會得到順時針順序。這個順序的改變會導致不正確的光照和背部消隱產生。為檢測一個給定矩陣是屬於那種情況,計算左上3×3的元素組成的矩陣的行列式。如果數值是負的,矩陣就是反射的。

例子:某個方向上的縮放。縮放矩陣S僅沿着x,y和z軸進行縮放。如果需要在其他方向上進行縮放,那么就需要復合變換了。假設需要沿着標准正交的,右手定則的向量fx,fy和fz進行縮放。首先,如下構建矩陣F:

wps_clip_image-24941                                   (4.10)

其思路是使這三個軸給出的坐標系與標准的軸重合,接着使用標准的縮放矩陣,然后再轉換回來。第一步通過與F的轉置矩陣,也就是逆矩陣,相乘而得出。方程4.11展示了這個變換:

X=FS(s)FT                                                              (4.11)

4.1.4 剪切變換

另一類圖形變換是一組剪切矩陣。它們可以做,例如被用於游戲中去扭曲場景中的實體以營造迷幻的效果或是通過抖動創造模糊反射(見9.3.1節)。這有6種基本的剪切矩陣,它們被標記為Hxy(s),Hxz(s),Hyx(s),Hyz(s),Hzx(s)和Hzy(s)。第一個下標用於標記那個坐標被剪切矩陣改變,而第二個下標指出那個坐標執行這個剪切。方程4.12展示了剪切矩陣Hxz(s)。觀察到下標可以用於確定參數s在下面矩陣的位置;x(其數字索引是0)標記為第0行,而z(其數字索引為2)標記為第2列,所以s定位於那兒:

wps_clip_image-6591                                 (4.12)

這個矩陣與一個點P相乘產生一個點:(px+spz py pz)T。圖4.3生動地將其展示在單元正方形上。Hij(s)的逆矩陣(相對第j號坐標,剪切第i號坐標,且i≠j)通過反方向的剪切變換生成,即H-1ij(s) = Hij(-s)。

wps_clip_image-12135

圖4.3 使用Hxz(s)剪切單位正方形的效果。y和z的值都沒有受到圖形變換的影響,而x值則是x的原數值與s與z的乘積的和,使得正方形傾斜。

一些計算機圖形學的文章使用稍不同種的剪切矩陣:

wps_clip_image-32266                                 (4.13)

但在這里,所有的下標都用於標記被第三個坐標剪切的坐標。這兩種不同種類的描述之間的關聯是H’ij(s,t)=Hik(s)Hjk(t), k用作第三個坐標的索引。使用何種矩陣是個人的喜好和API是否提供支持。

最后,應該注意到的是任何剪切矩陣的行列式|H|=1,這是一個保存體積不變的圖形變換。

4.1.5 圖形變換的串接

因為矩陣乘法的不可交換性,矩陣出現的順序變得十分要緊。圖形變換的串接因此被認為是依賴於順序的。

舉個順序依賴的例子,考慮兩個矩陣,S和R。S(2,0.5,1)對x進行2倍,對y進行0.5倍的縮放。Rz(π/6)以逆時針繞z軸(其指向從書頁面向外)轉π/6。這些矩陣可以以兩種方式相乘,而產生完全相反的結果。圖4.4展示了兩個結果。

wps_clip_image-16636

圖4.4 這展示了矩陣相乘時的順序相關。在上面一行中,旋轉矩陣Rz(π/6)被應用,緊接着的是縮放矩陣S(s),其中s=(2, 0.5, 1)。其復合矩陣為S(s)Rz(π/6)。在下面一行中,矩陣以相反的順序被應用,產生為Rz(π/6)S(s)。兩者的結果是明顯地不同。對於任意的矩陣M和N,總體上是MN≠NM的。

將一系列矩陣串接合成一個單一矩陣的一個顯而易見的原因是效率。例如,想象一下你需要對一個有數千個頂點的對象進行縮放,旋轉,以及最后的平移。現在,所有的頂點不是和三個矩陣的每個都相乘,而是三個矩陣串接結合成一個單獨的矩陣。這個單獨的矩陣被應用在頂點上。這個復合的矩陣C=TRS。注意到這里的順序:縮放矩陣S將會首先應用在頂點上,因此出現在復合矩陣的右邊。這順序為TRSp=(T(R(Sp)))。

值得注意的是矩陣的串接是順序相關的,但矩陣可以按需要進行分組。例如,對於TRSp你希望一次計算出剛體運動的圖形變換TR。將這兩個矩陣分為一組(TR)(Sp),然后用中間結果替換是合法的。因此,矩陣是相關的。

4.1.6 剛體圖形變換

當一個人拿一個固體的物體,例如從桌上拿一支鋼筆,並且將它移動到另一個位置,例如她襯衫的口袋里,僅僅是物體的朝向和位置發生變換,而物體的形狀總體上沒有受到影響。這種由平移和旋轉串接而組成的圖形變換,被稱為剛體圖形變換,其特點為保持物體的長度,角度和旋向性。

任何剛體矩陣X可以被寫成平移矩陣T(t)和旋轉矩陣R的串接。因此X形如方程4.14中的矩陣:

wps_clip_image-4736                                 (4.14)

X求逆矩陣的計算為X-1=(T(t)R)-1=R-1T(t)-1=RTT(-t),因此,為了計算逆矩陣,左上3×3矩陣R被轉置,而T的平移數值改變了符號。這兩個新的矩陣以相反的順序相乘在一起得到逆矩陣。計算X逆矩陣的另一個方法是將R(R為3×3的矩陣)和X認為是如下的標記:

wps_clip_image-6682wps_clip_image-27982                            (4.15)

這里,0是一個以0填充的3×1的列向量。產生逆矩陣的一些簡單的計算展示在方程4.16的表達式中:

wps_clip_image-23134                                (4.16)

4.1.7 法向圖形變換

一個單獨的矩陣可以用於點,線,多邊形和其他幾何體的一致變換。同樣的矩陣可以變換沿着這些線或多邊形表面的切線向量。但是這些矩陣不能用於變換一個重要的圖形屬性,表面法線(以及頂點光照法線)。圖4.5展示了如果同樣的矩陣被使用將會發生什么情況。

wps_clip_image-12570

圖4.5 在左邊的是原來的幾何體,從側面展示了一個多邊形和它的法線。中間的圖展示了經過沿x軸進行0.5倍的縮小,而且法線使用同樣的矩陣進行變化后圖片發生了什么變化。右邊的圖展示了法線的正確變換。

不是乘以矩陣本身,合適的方法是使用矩陣的伴隨矩陣的轉置。伴隨矩陣的計算在A.3.1節中描述。伴隨矩陣總是被認為是存在的。法線在變換以后不保證其為單位長度,因此必須對其標准化。

對於法線變換的傳統方法是計算逆矩陣的轉置。這個方法通常是可行的。完全求逆(full inverse)是不必要的,但偶爾不能創建。逆矩陣是鄰接矩陣除以原矩陣的行列式。如果這個行列式為0,矩陣是奇異的,那么他的逆矩陣就不存在。

即使是計算一個4×4矩陣的鄰接矩陣,其運算量也是很大的,而且通常是不需要的。因為法線是一個向量,平移是不會影響它的。此外,多數模型的變換是仿射的。它們不會改變傳入的齊次坐標的w分量,也就是說它們不會進行投影。在這些(通常的)環境下,法線變換的計算僅需要計算左上3×3分量的鄰接矩陣。

通常甚至這個鄰接矩陣也不需要計算。我們知道圖形變換矩陣由整個平移,旋轉,和整體縮放操作(沒有拉伸或壓縮)串接而成的。平移不影響法線。整體縮放因子簡單地改變法線的長度。剩下的是一系列旋轉,它們總是產生某種純粹的旋轉,僅此而已。一個旋轉矩陣的特性是它的轉置矩陣就是它的逆矩陣。逆矩陣的轉置可以用於變換法線,並且兩次轉置(或者兩次求逆)可以互相消去。將這些放在一起,其結果是在這樣的環境下,原來的矩陣本身可以直接用於變換法線。

最后,完整的重標准化不總是需要的。如果只是平移和旋轉串接在一起,當通過矩陣變換時,法線長度不會變化。如果整體縮放也被串接,那么整體縮放因子(出自4.2.3節)可以直接用於輸出法線標准化。例如,如果我們知道一系列的縮放被使用使得對象變為5.2倍大,那么法線變換直接通過這個矩陣,其通過除以5.2實現標准化。或者,要創建一個產生標准化結果的法線變換矩陣的方法是,原來的矩陣左上3×3除以這個縮放因子。

注意到法線變換不是一個問題,在系統中,變換后表面法線源自三角形(例如,三角形的邊的叉積)。切線向量與法線在本質上是不同的,而且總是直接被原矩陣所變換。

4.1.8 矩陣求逆

很多的地方需要求逆矩陣,例如,在兩個坐標系統中來回變換。基於可得到的圖形變換信息,可以使用以下三種計算逆矩陣的方法中的一種。

·如果矩陣是一個單獨的圖形變換或者一些列帶有給定參數的簡單變換,那么矩陣可以通過“參數取反”和矩陣的順序,容易地計算得出。例如,如果M=T(t)R(φ),那么M-1=R(-φ)T(-t)。

·如果已知矩陣是正交的,那么M-1=MT,也就是說轉置矩陣就是逆矩陣。任何順序的旋轉都是旋轉,並且因此是正交的。

·如果沒有已知任何特性,那么鄰接矩陣方法(902頁的方程A.38),克拉默法則,LU分解,或者高斯消元可以被用於計算逆矩陣(見A.3.1節)。克拉默法則和鄰接矩陣總體上是更好的,因為他們有較少的分支操作;在現代架構中避免“if”測試是好的。見4.1.7節中如何使用鄰接矩陣求逆去變換法線。

在優化時,可以將計算逆矩陣的目的也考慮上。例如,如果逆矩陣將被用於變換向量時,通常僅矩陣左上3×3部分需要被求逆(見前面章節)。

4.2 特殊矩陣以及其操作

在這一節,一些與實時計算機圖形學息息相關的矩陣的變換和操作將被介紹和推導。首先我們展示歐拉變換(以及它的參數的提取),一個描述朝向的直觀方法。然后我們涉及從一個單獨矩陣返回一系列基礎的圖形變換。最后,一個讓實體繞任意軸旋轉的方法被推導出來。

4.2.1 歐拉變換

這個圖形變換是一個直觀的方法,去構建一個矩陣,以確定你自己(也就是說攝像機)或者其他實體在某個方向的朝向。它的名字來自偉大的瑞士數學家萊昂哈特·歐拉(1707-1783)。

wps_clip_image-7502

圖4.6 以歐拉變換的術語描述,你轉動你的head, pitch和roll。默認的視圖方向被展示,朝z軸負向看而且head朝向沿着y軸。

某種默認的視覺方向必須首先被建立。通常它會沿z軸負向且head朝向沿y軸,就像圖4.6所示的那樣。歐拉變換是三個的矩陣的相乘,即圖中所示的旋轉。更確切地說,這個以E標記的轉換矩陣,以方程4.17給出:

E(h, p, r)=Rz(r)Rx(p)Ry(h)                                    (4.17)

因為E是一個旋轉矩陣的串接。它無疑也是正交的。因此它的逆矩陣可以表達為E-1=ET=(RzRxRy)T=RyTRxTRzT,盡管當然是更容易使用的E的轉置矩陣直接。

歐拉角h,p和r代表順序和head,pitch和roll應該繞他們對應的軸轉過多少度。這變換是直觀的並且因此易於與外行人討論。例如,改變head角度使得觀察者搖晃他的頭說不,改變pitch使得他點頭,而roll使他的頭側傾。注意到的是這個圖形變換不僅可以給攝像機定向,也可以用於其他對象或實體。這些變換可以用於世界空間的全局坐標軸或者相對一個局部框架的參考。

當你使用歐拉變換,一種叫做萬向鎖的情況可能出現。發生這種情況是,旋轉使得物體失去一個自由度。例如,變換的順序是x、y、z。考慮一個繞y軸轉π/2的轉動,第二個旋轉運行。實施這樣的旋轉后局部坐標的z軸將會與原來坐標的x軸重合,如此的話最后繞z的旋轉成了冗余的。

另一個看到失去一個自由度的方法是設置p=π/2並檢查歐拉矩陣E(h, p, r)發生了什么:

wps_clip_image-26853      (4.18)

因為矩陣是依賴於一個角(r+h),我們斷定失去了一個自由度。

歐拉角一般按x、y、z的順序出現在模型系統中,然而繞局部坐標的旋轉也可以按照其他順序的。例如,用於動畫的z、x、y和用於動畫和物理的y、x、z。所有都是合法的指定三個分離旋轉的方式。最后一個順序,y、x、z,對於某些應用場景是表現優秀的,因為只有當繞x軸轉過π弧度(轉一半)才會引發萬向鎖。這就是說,“毛球定理”萬向鎖是不可避免的,沒有完美的順序可以避免它。

雖然對於小角度的改變和觀察者定位十分有用,歐拉角有其他很嚴重的限制。將兩個歐拉角組合起來是很困難的。例如,一個歐拉角與另一個之間的插值不是簡單地對每個角進行插值。事實上,兩個不同的歐拉角可以得出相同的朝向,所以任何插值都不應該旋轉對象。這些是使用另外的一些朝向表達,例如后面討論的四元數,的原因。

4.2.2 從歐拉變換中提取參數

在某些情況,能夠從正交矩陣中提取歐拉參數h,p和r是很有用的。這個提取步驟如方程4.19所示:

wps_clip_image-28984                       (4.19)

串接這方程4.19產生的三個旋轉矩陣

wps_clip_image-1003         (4.20)

從這可以明顯地看到參數pitch由sinp=f21給出。同樣的,f01除以f11,以及相似的f20除以f22,推導出了接下來用於參數head和roll的提取公式:

wps_clip_image-16891                                   (4.21)

因此,歐拉參數h(head),p(pitch),r(roll)使用函數atan2(y, x)(見第一章中的第7頁)從矩陣F中提取如公式4.22所示:

wps_clip_image-31164 (4.22)

但是,這里有一個特殊例子我們需要處理。當cosp=0時它發生,因為這時f01=f11=0,而因此函數atan2不能使用。Cosp=0意味着sinp=±1,所以F可以簡化為

wps_clip_image-16215 (4.23)

剩余的參數可以通過任意設置h=0,那么sinr/cosr=tanr=f10/f00,通過r=atan2(f10, f00)得到。

注意到arcsin(見B.1節)的定義域為[-π/2, π/2],這意味着如果F如果由這個范圍以外的值p創建,那么就不能提取原來的參數。h,p和r不是唯一的,多於一組的歐拉角參數可以產生同樣的變換。更多歐拉角的轉換可以在Shoemake的1994的論文中看到。以上描述的簡單的方法會產生數值不穩定的問題,這在損失一定速度后可以避免。

例子:圖形變換的限制。想象你正拿着一個靠在螺栓上的扳手並繞x軸旋轉扳手以上緊螺栓。現在假設你的輸入設備(鼠標,數據手套,軌跡球等)給出扳手運動的正交變換。你遇到的問題是你並不願意將變換應用在這個一般應該只繞x軸旋轉的扳手上。因此為了將輸入的變換P,限制在繞x軸的旋轉,使用本節介紹的方法提取歐拉角h,p和r並且創建新的矩陣Rx(p)。這是一個很好用的能使扳手繞x軸旋轉的變換(如果P包含了這樣的運動)。

4.2.3 矩陣分解

到現時為止,所有的工作都基於假設我們知道所用的變換矩陣的變化的源頭和歷史。這並不是常見的情況:例如,除了與變換對象相關的已串接矩陣外沒有其他東西。從串接矩陣中返回多個矩陣的任務叫做矩陣分解。

需要返回一系列變換的原因有很多,包括:

·為對象提取縮放因子。

·查找粒子系統所需的圖形變換。例如,VRML使用變換節點(見4.1.5節)並且不允許使用任意的4×4矩陣。

·檢測模型的變換是否只含有剛體圖形變換。

·當僅可以獲得對象的矩陣時,可以在關鍵幀之間進行動畫插值。

·將剪切變換從旋轉矩陣中移除。

我們已經展示了兩種分解,這些包括在一個剛體變換中划分平移和旋轉矩陣(見4.1.6節),以及在一個正交矩陣中划分出歐拉角(見4.2.2節)。

像我們看到的,返回整個平移矩陣並不是重要的,因為我們只需要這個4×4矩陣的最后一行。我們也可以通過檢查矩陣的行列式是否為負從而確定反射是否發生。為了區分旋轉,縮放和剪切需要更多工作。

幸運的是在網上可以獲取到相當多的關於這方面的論文,以及代碼。Thomas和Goldman都提出了稍微不同的對應各種類型變換的方法。Shoemake對用於仿射矩陣的技術進行改進,他的算法獨立於參照物的框架並試圖分解矩陣以得到剛體變換。

4.2.1 繞任意軸的旋轉

某些時候如果能夠讓一個實體繞任意軸轉動一定角度是十分方便的。假設旋轉軸r是標准化的而且變換被創建為繞r旋轉α弧度。

為此,首先找到任意兩個單位長度的,與r都兩兩相互正交,也就是標准正交的軸。由這些形成一個空間的基。其方法就是將空間的基從標准空間的基轉變為這個新的基,然后繞x軸(與r軸相對應)旋轉α個弧度,並且最后變換回標准空間基。這個過程在圖4.7展示。

wps_clip_image-8158

圖4.7 繞任意軸r的選擇是通過找到由r,s和t組成的標准正交的基完成的。接下來將這個基與標准基對齊,使得r與x軸對齊。繞x軸的選擇在此執行,然后變換回去。

第一步是計算基的標准正交的軸。第一個軸是r,也就是旋轉所繞的那一個。我們現在集中到尋找第二個軸s,而第三個軸t將會是第一個軸和第二個軸的叉乘,t=r×s。一個數值穩定的實現方法是找到r的最小分量(絕對值)並將它設置為0。交換另外兩個分量,然后將這些數字的第一個取負。數學上可以表示為:

wps_clip_image-17008                        (4.24)

這保證了wps_clip_image-17847是正交(垂直)於r,而(r,s,t)是一個標准正交的基。我們可以如下將這三個向量作為矩陣的行:

wps_clip_image-5282                                              (4.25)

這個矩陣將r變換到x軸(ex),s變換到y軸和t變換到z軸。所以繞標准化向量r旋轉α個弧度最終的矩陣為

X=MTRx(α)M                                           (4.26)

簡而言之,這意味着我們先變換已使得r成為x軸(使用M),接着我們繞x軸旋轉α個弧度(使用Rx(α)),接着我們使用M的逆矩陣變換回來,在這個例子中是MT,因為M是正交的。

Goldman展示了另一個繞任意軸r旋轉φ個弧度的方法。我們在這簡單展示他的變換:

wps_clip_image-4240 (4.27)

在4.3.2節,我們展示了解決這種問題的另一種方法,使用四元數。這也是這章中處理相關問題,例如從一個向量旋轉到另一個向量的更高效的算法。

4.3 四元數

盡管四元數可以追溯到1843年Sir William Rowan Hamilton關於復數的擴展,它直到1985年才被Shoemake引入到計算機圖形學科中。四元數是一個功能強大的工具,在構造圖形變換有着引人注目的特性,在某些方面,它超越了歐拉角與矩陣,尤其是對於旋轉和定向。給出坐標軸和角度的代表,變換或計算一個四元數是很直觀的。然而歐拉角在任意一個角度的變換都是困難的。四元數可以用於穩定不變的朝向插值,歐拉角在這方面變現不好。

一個復數包含了實數和虛數。兩者都由實數字代表,第二個實數乘以wps_clip_image-18919。相似地四元數有四個部分。前三個數值與旋轉的軸緊密相關,旋轉的角度影響所有四部分(關於這些的更多在4.3.2節)。每個四元數由4個與不同部分關聯的實數代表。因為四元數有四個部分,我們使用向量去代表它,但為了區分它們,我們給它們戴個帽子:wps_clip_image-8435。我們由一些四元數的數學背景開始,這些將用於四元數的構建和有用的變換。

4.3.1數學背景

我們從四元素的定義開始。

定義  四元數q可被下列方法定義,這些方法都是等效的

wps_clip_image-13133 (4.28)

變量qw被稱為四元數wps_clip_image-5041的實數部分,虛數部分是qv,而i,j和k叫做虛單元

對於虛部,,我們使用正常的向量運算,例如加減數乘,點乘,叉乘及更多其它。根據四元數的定義,兩個四元數wps_clip_image-21083wps_clip_image-17486相乘推導如下。注意到虛單元的乘法是不滿足交換律的。

乘法:

wps_clip_image-15440 (4.28)

如方程所示,我們對兩個四元數的相乘使用了叉乘和點乘。由四無數的定義可得出其加法,共軛,標准化和單位四元數如下:

加法:wps_clip_image-9132

共軛:wps_clip_image-5278

規范化:wps_clip_image-19753                                     (4.30)

單元:wps_clip_image-16408

wps_clip_image-5514被簡化(結果展示如上),其虛部被消除而只有實數部分保留。標准化有時可標記為wps_clip_image-16038。上述的結果是乘法逆元,標房為wps_clip_image-27244,這可被推導。方程式wps_clip_image-18300必須成立(因為這是乘法逆元共有的)。我們取模的定義推導出公式

wps_clip_image-19987 (4.31)

這給出乘法逆元如下:

逆元:wps_clip_image-25639 (4.32)

逆元的公式使用了標量乘法,這個運算源自公式4.29的乘法:wps_clip_image-23243,而wps_clip_image-26866,這意味着標量乘法是可交換的:wps_clip_image-21047

以下一系列的定理可以容易從定義中獲是:

共軛定理: wps_clip_image-23912 (4.33)

取模定理: wps_clip_image-8264 (4.34)

乘法法則:

線性: wps_clip_image-15875 (4.35)

結合性: wps_clip_image-13997 (4.36)

一個單位四元數,wps_clip_image-2127,其wps_clip_image-3321。由此wps_clip_image-19708可寫為

wps_clip_image-13018 (4.36)

對於一些三維向量uq,例如||uq||=1,因為

wps_clip_image-8125 (4.37)

這些且僅當uq.uq=1=||uq||2才成立。像在下一節所見,單位四元數是十分適合構建高效旋轉和朝向。但在此之前,一些對於單位四元數的額外運算將被引入。

對於復數,一個二維的單位向量可寫為wps_clip_image-3340。四元數的對等為

wps_clip_image-15079                                     (4.38)

對於單位四元數的對數及冪運算如方程4.38:

對數: wps_clip_image-23284

冪:                wps_clip_image-7458                               (4.39)

wps_clip_image-21000

圖4.8 由單位四元數wps_clip_image-22969代表的旋轉變換的圖例。變換繞uq軸旋轉2φ個弧度。

4.3.2 四元數圖形變換

我們現在研究四元數的一個子類,即其長度為單位長,稱為單位四元數。單位四元數的重要之處在於它們可代表任意三維旋轉,並且其表示是極為簡潔和簡單。

  現在我們描述什么使單位四元素對於旋轉和朝向如引有用。首先,將點或向量的四個坐標(Px Py Pz Pw)T放入四元數wps_clip_image-17767的分量,並假定我們有一個單位四元數wps_clip_image-22600。那么

wps_clip_image-17237 (4.40)

旋轉wps_clip_image-26317(並由此點P)繞軸uq轉2φ弧度。注意到因為wps_clip_image-8056是一個單位四元數,wps_clip_image-22899。這個旋轉在圖4.8上展示出來,它顯然可被用於繞任意軸旋轉。

任何wps_clip_image-22527的非零實數乘法也代表相同的變換,這意味着wps_clip_image-3473和-wps_clip_image-29992代表相同的旋轉。這就是對uq取負軸,和實數部分,qw,創建一個像原來的四元數那樣旋轉和四元數。這也意味着由矩陣中提取四元數可以返回wps_clip_image-4524和-wps_clip_image-15799

給出兩個單位四元數,wps_clip_image-640wps_clip_image-12379,串聯連結是先后將wps_clip_image-27994wps_clip_image-28955應用到一個四元數,wps_clip_image-19024(可認為是點P),由公式4.41給出:

wps_clip_image-4921 (4.41)

這里,wps_clip_image-29970是單位四元數,代表單位四元數wps_clip_image-11063wps_clip_image-364的串聯。

矩陣轉換

因為某些系統將矩陣乘法用硬件實現,而且事實上矩陣乘法相較公式4.40有更高的效率,我們需要一個矩陣與四元數的相互轉換的方法。四元數,wps_clip_image-12757,可以被轉換成矩陣Mq,像公式4.42所表達的:

wps_clip_image-28848 (4.42)

這里,標量wps_clip_image-18507。對於單位四元數,這可簡化為

wps_clip_image-14244 (4.43)

一旦四元數被構建,就不再需要計算三解函數了,因此在實踐中,這轉換過程是高效的。

相反的轉換,從正交矩陣,Mq,轉換到一個單位四元數,wps_clip_image-12044,泛及更多方面。這過程的關健是下面由方程4.43中的矩陣的不同之處:

wps_clip_image-16551                                     (4.44)

這組公式暗示如果qw是已知,向量vq可似被算出,而因些wps_clip_image-3022可被導出,Mq的跡(見898頁)可以被計算為

wps_clip_image-13347 (4.45)

這個結果對單位四元數產生以下的變換:

wps_clip_image-16561 (4.46)

為了在數值上能穩定,應避免除以一個小值數。因此,首先設wps_clip_image-24981由此可得

wps_clip_image-26036 (4.47)

這意味着最大的m00,m11,m22以及u決定了qx,qy,qz和qw那個最大,如果qw是最大,那么公式4.46被用於導出四元數。否則,我們注意到下面:

wps_clip_image-13730                               (4.48)

在方程4.44用於計算wps_clip_image-16103剩余的部分之后,以上之一的合適方程用於計算qx,qy和qz之間的最大值。幸運的是在這一章最后的進一步閱讀和資源中有這方面的代碼。

球面線性插值

球面線性插值是一個這樣的運算,給出兩個單位四元數,wps_clip_image-19995wps_clip_image-7405 ,以及參數t∈[0,1],計算之間的插值四元數。這對動畫對象很有用。它在攝像機朝向的插值用處不大,因為攝像機的“上”向量會在插值中變傾斜,這通常是不好的效果。

這操作的代數形式表示為復合四元數,wps_clip_image-732,如下:

wps_clip_image-17101 (4.49)

但是,對於軟件實現,以下的形式,球形線性插值點,是更為合適:

wps_clip_image-13035 (4.50)

為了計算φ這一方程所需的值,以下可用:wps_clip_image-814,對於t∈[0,1],球面插值函數計算一系列(唯一的)插值四元數一起組成了四維單位球上由wps_clip_image-24386(t=0)到wps_clip_image-6241(t=1)的最短弧。圓弧落在wps_clip_image-10530wps_clip_image-5619以及原點所給出的平面與四維單位球體相交所形成的圓形上。這如圖4.9所示。計算的旋轉四元數繞固定軸似恆定速度旋轉。這樣的以常速運行,因此加速為零的曲線,叫做測地曲線。

wps_clip_image-14319

圖4.9 單位四元數用於表示單位圓上的點。Slerp函數用於四元數間的插值,並且插值路徑是球上的弧,注意到由wps_clip_image-1950wps_clip_image-27353的插值與由wps_clip_image-12485wps_clip_image-7390再到wps_clip_image-14568的插值不是同一樣,即使他們最后都到達同一朝向。

Slerp函數十分適合在兩個朝向間的插值並且它表現得很好(固定軸,常速)。在使用一些歐拉角進行插值時並非如此。在實踐中,直接計算slerp是一個昂貴的運算,涉及了三角函數的調用。Li提供了更快的遞增方式去計算Slerps並用不犧牲精度。

當多於兩個朝向,記為wps_clip_image-13814,可得,而我們希望從wps_clip_image-13496wps_clip_image-23131再到wps_clip_image-14506,直到wps_clip_image-20808進行插值,Slerp可直接使用。現在當我們接近wps_clip_image-18745,我們會以wps_clip_image-18103wps_clip_image-24126為Slerp插值的參數。之后越過wps_clip_image-26580,我們會使用wps_clip_image-6662wps_clip_image-6208作為Slerp的參數。這會使朝向插值出現突然間的急速變化,這可見於圖4.9。與之相似的是點被線性插值,見578頁圖13.2的右上部分。一些讀者可能想在讀完13章關於樣條曲線后重讀接下來的段落。

一個更好的插值方法是使用某種樣條曲線。我們在wps_clip_image-6669wps_clip_image-11881之間引入四元數wps_clip_image-13950wps_clip_image-22384。球面立方插可被定義一系列四元數,wps_clip_image-28407wps_clip_image-1915wps_clip_image-30235wps_clip_image-16741中。出乎意料地,三個額外的四元數可如下被計算:

wps_clip_image-6901 (4.51)

wps_clip_image-6446wps_clip_image-1597會用於四元數的球面插值,使用三次樣條平滑,如方程4.52:

wps_clip_image-11921 (4.52)

由上可見,squad函數通過重復球面插值使用slerp構建(見13.1.1節中關於點的重復線性插值的信息)。插值會經過初始朝向wps_clip_image-13052,i∈[0,...,1],缺不穿過wps_clip_image-2480——這是用於指示初始朝向的切線朝向。

從一個向量旋轉到另一個

通常的操作是從一個方向s通過最短路徑轉到t。四元數數學極大地簡化了這一步驟,並且展示了四元數與這一表示方式的緊密關系。首先,規范化s和t ,然后計算單位旋轉軸,稱為u,通過wps_clip_image-1321計算,下一步,wps_clip_image-20915並有wps_clip_image-13861,這2φ是s和t之間的夾角。四元數表示由s旋轉到t是wps_clip_image-21964,實際上使用半角關系(見19頁)以及三角函數恆等式(公式B.9)可將wps_clip_image-20049簡化為

wps_clip_image-25350 (4.53)

以這種方式直接生成四元數(相較於規范化s與t 的叉乘)避免了當s與指向幾乎相同的t叉乘時數值上的不穩定。穩定性問題同樣出現在s和t指向相反方向,因為出現了除以零。當檢測到這樣的特殊例子,任何垂直於s的轉動軸可用於旋轉至t。

有時我們需要矩陣表示從s到t 的旋轉。在代數和三角函數簡化公式4.43后,旋轉矩陣變為

wps_clip_image-23564 (4.54)

在這個方程,我們使用以下的中間計算:

wps_clip_image-30140 (4.55)

就像可見的,所有平方根和三角函數由於化簡而消失,因此這是一個高效的構建矩陣的方法

需特別注意到,當s與t 是平行或都幾乎平行,因此||s×t||≈0。如果φ≈0那么我們可似返回單元矩陣。然而,如果2φ≈π,那么我們可似繞任何軸旋轉π個弧度。這個軸可以由s和其它任意不平行於s的向量的叉積而得(見4.24節)。Moller和Hughes使用戶主矩陣以不同的方式處理這種特殊的情況。

例子:為攝像機設置位置和朝向。假設默認的虛攝像機(或視點)的位置是(0 0 0)T並且默認的視覺方向v是沿z軸負向,也就是說是v=(0 0 -1)T。現在,目標是創建一個變換將攝像機移到新的位置p,看向新的方向w。由攝像機的定向開始,這可以由從默認視圖方向轉到目標視圖方向實現。R(v,w)負責這些。定位是簡單地由平移到p實現,這產生了結果變換X=T(p)R(v,w)。在實踐中,在第一次旋轉之后其它的向量與向量間的旋轉很可能會將視圖向上方向旋轉到所需要的方向。

4.4頂點混合

設想一個數字人物的手臂動畫化被分為兩部分,前臂和上臂,像圖4.10左邊那樣顯示。這個模型的動畫可使用剛體變換(見4.1.6節)。但兩部分間的連接點卻不像真正的手肘。這是因為使用的是兩個分離的對像,而且因此連接點由兩個分離的對像的重合部分組成。顯然,使用一個獨立的對象更好。然而,靜態模型部分並不能使連接點靈活。

wps_clip_image-23510

圖4.10 一個手臂由前臂和上臂組成,其動畫化使用左邊的兩個分離對象的剛體變換。手肘並未表現真實。對於右邊,頂點混合用於一個單獨的對象。最右邊旁邊的手臂展示了當一個簡單的皮膚直接連接兩部分覆蓋手肘將會發生什么。最右邊手臂展示了當頂點混合被使用將會發生什么,並且一些頂點被以不同的權重進行混合:(2/3, 1/3)意味着頂點的變換的權重是上臂2/3,前臂1/3。這圖也在最右邊展示了頂點混合的不足,這里,在手肘內部的折疊是可見的,更好的結果可以由更多骨骼,以及更細的權值設定而獲得。

頂點混合是這個問題的一個解決方案。這技術有許多其它名稱,例如蒙皮,包絡和骨骼子空間變形。雖然這所展示的算法的精確起源不為人所清楚,但定義骨骼並使皮膚對變化作出反應是計算機動畫的舊概念。在它最簡單的形式,前臂及上臂像此前那樣,但在連接點,兩個部件通過彈性的“表皮”連接。因此,這個彈性部分將會有一組頂點由前臂矩陣變換,而另一組由上臂矩陣變換。這個結果為三角形,其頂點可能被不同的矩陣變換,與每個三角形都使用單獨的矩陣形成鮮明的對比。見圖4.10。這種基本的技術叫做拼接。

在這步繼續深入,一個單獨的頂點可以被多個不同矩陣變換,並包含了結果位置的加權混合。這由擁有骨骼的動畫對象實現,其每個骨骼的變換會通過用戶自定義的權重影響每一各頂點。因為整個手臂可能都是“有彈性的”,也就是,所有的頂點可以被一個以上的矩陣影響,整個網格通常稱為皮膚(包裹着骨骼)。見圖4.11。很多商業建模系統擁有這同種骨骼建模的功能。雖然有這樣一個名稱,但骨骼並非一定需要是剛硬的。例如,Mohr和Gleicher提出了關於增加額外的連接點以啟用例如肌肉膨脹的效果的想法。James和Twigg討論了動畫蒙皮使用可以壓縮和拉伸的骨骼。

wps_clip_image-3000

圖4.11 一個真實的頂點混合例子。左上圖片在一個延伸的位置上展示手臂的兩個骨骼。右上圖展示了網格,並且以顏色標記了每根骨骼所擁有的頂點。下面的圖:着色后的手臂網格,與前圖位置稍異。

這在數學上被表示為公式4.56,其p是頂點原本位置,而u(t)是變換后頂點,其位置由時間參數t確定。n塊骨骼影響着p的位置(即其世界坐標)。矩陣Mi從原來的骨骼坐標系統變換到世界坐標系。典型的是骨骼有它在其坐標系統原點的控制節點。例如,前臂骨骼會以手肘節點為原點,以動畫旋轉矩陣繞着該節點移動手臂的這部分。Bi(t)矩陣是第i塊骨骼隨時間變化使對象動畫化的世界變換,並且通常是一些列矩陣的串聯,例如層次化中之前的骨骼變換以及局部動畫矩陣。Woodland深入討論了一個維護和更新Bi(t)矩陣動畫功能的方法。最后,wi是骨骼i對定點p的權重。定點混合公式是

wps_clip_image-8821 (4.56)

每塊骨骼都就自有的框架參考點變換頂點,而最終的位置是由一些列計算出來的點插值得出的。在蒙皮的一些討論中,矩陣Mi不是顯式展示的,而是被當做Bi(t)的一部分。我們在這展示它是因為它是有用的矩陣,幾乎總是矩陣串接過程的一部分。

在實踐中,每幀動畫的每塊骨骼的矩陣Bi(t)和Mi-1串接一起,而且每個結果矩陣都是用於變換頂點的。頂點p被不同骨骼串接后的矩陣變換,並且使用權重wi混合到一起——因此名為頂點混合。權重為非負數值以及其和為1,因此頂點根據一些位置變換並在其中插值的情況將會發生。同樣地,變換后的點u會位於一些列點Bi(t)Mi-1p(固定時刻t下由0到n-1的所有的i)。法向量通常也可以由公式4.56變換。根據變換的使用(例如如果一塊骨骼被延伸或者壓縮一個相當大的數值),Bi(t)Mi-1的逆矩陣可以由轉置矩陣代替,就像4.1.7節中討論的那樣。

頂點混合十分適合用於GPU。網格中的一系列頂點可以至於靜態緩存中,一次性提交給GPU然后重復使用。在每一幀中只有骨骼矩陣發生變化,頂點着色器計算他們在已存儲的網格上產生的作用。在這個方法中,數據處理和與CPU交互的數據量是最少的,允許GPU高效地渲染網格。如果模型的整套骨骼可以一起使用的話是最容易的;否則模型就必須分割並且一些骨骼將會重復。

使用頂點着色器時,可以指定[0,1]以外,或者總和不為1的一組權重。但是,這樣使得場景只能使用其他的混合算法,例如目標變形(見4.5節)正被使用。

原始的頂點混合的一個缺點是會發生不需要的折疊、扭曲和自相交。見圖4.12。一個最佳的解決方法是使用Kavan以及其他人所展示的對偶四元數。這個處理蒙皮的技術幫助保留原變換的剛性,故避免了肢體發生“糖果包裹紙”般的扭曲。計算量小於線性蒙皮混合的1.5倍,並且結果優秀,導致該技術的快速普及。感興趣的讀者可以參考該論文,它也包括了一關於之前關於線性混合改進的簡述。

wps_clip_image-17471

圖4.12 左邊的圖展示了使用線性混合時在連接點發生的問題。在右邊,使用對偶四元數的混合改進了其外觀。

4.5 變形

在展示動畫時,從一個三維模型變形到另一個是十分有用的。一個模型的圖像在時刻t0顯示而我們希望它在時刻t1變換到另一個模型。對於t0到t1之間的所有時間,由某種差值得出一個連續的“混合”模型。圖4.13展示了一個變形的例子。

wps_clip_image-24907

wps_clip_image-9629

wps_clip_image-24118

圖4.13 頂點變形。兩個位置和法線定義了每個頂點。每一幀中,中間位置和法線被頂點着色器線性差值得出。

變形由兩個主要的問題構成,分別是頂點對應問題和插值問題。給出兩個任意的模型,它們有着不同拓撲結構、不同頂點和不同的網格連接,首先通常需要從設置這些頂點的對應關系開始。這是一個困難的問題,而且這方面已有很多的研究。感興趣的讀者可以參考Alexa的綜述[16]。

然而,如果兩個模型間頂點的一對一對應,那么插值可以在逐頂點的基礎上實現。這就是,對於第一個模型的每個頂點,在第二個模型中必須存在唯一一個對應的頂點,反之亦然。這使得插值成了簡單的任務。例如,線性插值可以直接應用到頂點中(見13.1節中其他插值的方法)。為了計算時間在[t0,t1]之間的變形頂點,我們首先計算s=(t-t0)/(t1-t0),而線性頂點混合為

m=(1-s)p0+sp1                                                                                (4.57)

其中p0和p1 對應同一頂點在不同時刻t0和t1 。

一個有趣的變形的變體被稱作為目標變形或者形狀混合[671],它使得用戶能夠更為直觀地控制。其基本的理念可由圖4.14解析。

wps_clip_image-23532

圖4.14 給出兩個嘴巴的姿勢,一組不同的向量被計算出來去控制內插插值,或甚至外推插值。在目標變形,不同頂點的向量被用於向中性的面部“增加”動作。隨不同的向量的位置權重,我們得出了一個微笑的嘴巴,而負值的權重可以給出相反的效果。

我們從一個中性的模型開始,在這個例子中是一張臉。我們標記這個模型為N。此外,我們也有一組不同的面部表情。在例子中僅有一個微笑的表情。通常,我們可以允許標記為Pi,i∈[1,...,k]的不同表情的k≥1。作為前處理,“表情的差異”被計算為:Di=Pi-N,也就是每個表情模型中減去中性表情。

在這一點,我們有中性模型,N,以及一組姿勢差異,Di。一個變形后的模型M可以使用一下公式得到:

wps_clip_image-956 (4.58)

這是中性模型,而緊接着我們按需要使用權重wi增加不同的姿勢。對於圖4.14,設置w1=1給出了圖中間的精確的笑臉。使用 w1=0.5給出半笑的表情,等等。也可以使用負向或者大於1的權重。

對於這個簡單的面部模型,我們可以以增加另外的擁有憂傷眉毛的臉。因為位移是可附加的,這個眉毛的位置可以結合微笑嘴巴的姿勢使用。目標變形是一個強大的技術為動畫制作人提供更多的控制,因為模型的不同突出部可以獨立與其他部分而被操控。Lweis等人[770]介紹了骨骼(姿勢)空間變形,它結合了頂點混合和目標變形。硬件支持的DirectX 10可以使用流輸出和其他改進的功能實現在單個模型上使用多個目標並且僅在GPU中計算效果[793]。

圖4.15展示了一個使用蒙皮和變形的真實例子。

wps_clip_image-8997

圖4.15 瑞秋角色面部表情和動作由蒙皮和頂點變形控制,它在使用圖形硬件支持下可以加速

4.6 投影

在渲染一個場景之前,所有在場景中相關的對象必須投影在某個平面上或者投影到某個簡單形體中。此后再執行裁剪和渲染(見2.3節)。

這章中迄今為止所見的變換都留下第四個分量,w,不作改變。也就是說點和向量在變換后仍保留着他們的類型。同樣的是4×4矩陣的最底一行總是(0 0 0 1)。透視投影矩陣對這些屬性而言是個例外:底行包含向量和點的操縱數字,而且通常需要齊次化過程(也就是w通常不是1,因此需要除以w去獲得非齊次點)。這節中先前處理的正交投影,是一種簡單的被普遍應用的投影。它不會影響w分量。

在這一節中,假設視角是朝z軸的負向看,y軸朝上而x軸朝右。這是右手坐標系。一些文章和軟件,例如DirectX,使用的是左手坐標系,其視角是朝z軸正。兩者都是同樣正確的,並且能達到同樣的效果。

4.6.1 正交投影

一個正交投影的特征是在投影后平行線依然是平行線。下面所示的矩陣Po是一個簡單的正交投影矩陣,它留下點的x和y分量不變,而設置z分量為0,也就是它正交地投影到z=0的平面上:

wps_clip_image-21329 (4.59)

這個投影的效果展示在圖4.16。明顯的,Po是不可逆,因為它的行列式|Po|=0。簡而言之,變換從三維降到二維,而且沒有辦法重新獲得所丟棄的那一維。使用這種正交投影成像存在一個問題,那就是它將z分量正值和負值的點都投影到一個投影平面上。它能將z值(或者x,y值)限制在某一個區間,形成所說的從n(近平面)到f(遠平面)。這是下一個變換的目的。

wps_clip_image-24262

圖4.16 公式4.59生成的簡單正交投影的三個不同的視角。這投影可以認為視角是沿着z軸負向,這意味着投影簡單地略過坐標z(或者設置為0),但保留x和y坐標。注意到z=0的兩邊都被投影到投影面上。

一個更為普遍的執行正交投影的矩陣以一個六個數組合的方式表述,(l,r,b,t,n,f),標記為左、右、下、上、近、遠平面。這個矩陣本質上是軸對齊(AABB;定義見16.2節)地縮放和平移,由這些平面形成一個軸對齊的以原點為中心的立方體。AABB的最小轉角是(l,b,n)而最大轉角是(r,t,f)。認識到n>f很重要,因為我們是在空間是沿着z軸負向去看。我們的常識是近的數值應該小於遠的。同樣是朝z軸負向看的OpenGL,在調用glOrtho生成正交投影矩陣時以小於遠值的近值作為輸入參數,而后在內部將兩個參數取負。另一種方法是認為OpenGL的近值和遠值是沿視角方向(負向z軸)的(正的)距離,而非z視點坐標值。

OpenGL的軸對齊立方體有最小轉角(-1,-1,-1)以及最大轉角(1,1,1);DirectX的范圍則是(-1,-1,0)到(1,1,1)。這個立方體叫做正規化可視空間而這個空間的坐標叫做規范化設備坐標。圖4.17展示了變換的過程。轉換到正規化可視空間的原因是在這個狀態下裁剪更為高效。

wps_clip_image-21230

圖4.17 在正規化視圖空間中變換軸對齊。在左邊的盒子是第一個變換,使得它的中心位於原點。之后它像右邊所示的,縮小至正規化視圖空間。

在變換到正規化視圖空間后,將被渲染的幾何體的頂點會被這個立方體裁剪。不在立方體外的幾何體最終通過將剩余的單位正方形映射到屏幕而被渲染。OpenGL中這個正交投影如下:

wps_clip_image-13196      (4.60)

正如公式所示,Po可被寫成變換的串接,T(t),接着是縮放矩陣,S(s),其中s=(2/(r-l), 2/(t-b), 2/(f-n)),而t=(-(r+l)/2, -(t+b)/2, -(f+n)/2)。這個矩陣是可逆的,也就是說Po-1=T(t)S((r-l)/2, (t-b)/2, (f-n)/2)。

在計算機圖形學中,投影后通常使用左手坐標系——也就是說,對於視口,x軸指向右,y軸指向上,而z軸指向里。因為我們定義軸對齊包圍盒(AABB)的方式是遠值小於近值,所以正交投影變換通常包含一個鏡像變換。要明白這個,所謂軸對齊包圍盒大小保持不變是規范化視圖空間的目標。於是,軸對齊包圍盒的坐標是(-1, -1, -1)對應(l, b, n)而(1, 1, -1)對應(r, t, f)。公式4.60推導出:

wps_clip_image-6240,                                          (4.61)

這是一個鏡像矩陣。這個鏡像將右手坐標系(朝z軸負向看)轉換為左手的規范化的設備坐標系。

DirectX將z深度映射到范圍[0, 1]而OpenGL則是[-1, 1]。這可以在應用正交投影矩陣后通過應用簡單的縮放和平移矩陣而實現,這就是,

wps_clip_image-23568,                                          (4.62)

因此,DirectX使用的正交投影矩陣為

wps_clip_image-19825,                               (4.61)

這通常以轉置的形式出現,因為DirectX使用行主元去輸出矩陣。

4.6.2 透視投影

一個相較正交投影更為有趣的投影是透視投影,它被應用於大多數的計算機圖形程序。此時,投影后平行線一般不再平行,他們會在極遠處匯聚成一個點。透視投影更為接近我們對真實世界感知,簡而言之,遠處的物體通常更小。

首先,我們展示一個啟發性的透視投影矩陣的推導,這個投影投影到z = -d的平面,d > 0。我們從世界空間開始推導,簡化關於世界到視圖轉換的理解。這個推導之后就是更為常用的矩陣使用,例如OpenGL。

wps_clip_image-18231

圖4.18 用於導出透視投影矩陣的圖標。點p被投影到z = -d平面(d > 0),產出投影點q。投影由位處原點的透視攝像機產生。推導時使用的x分量的相似三角形如右圖所示。

假設攝像機(視點)被放置在原點,而我們希望投影一個點,p,到z = -d的平面(d > 0)而產生一個新的點q(qx, qy, -d)。這個場景如圖4.18所描述。從這幅圖所示的相似三角形,以下關於q的x分量的推導可得:

wps_clip_image-23172 (4.64)

q的另一個分量的表達式為qy=-dpy/pz(推導與qx相似),並且qz=-d。聯合上面的公式,我們得出投影透視矩陣,Pp,如下:

wps_clip_image-2539 (4.65)

這個矩陣是否產生正確的透視投影可簡單地通過公式4.66驗證:

wps_clip_image-15937 (4.66)

最后一步是整個向量都除以w分量(例子中的-pz/d),使得w分量保持為1。Z值的結果總是為-d,因為我們投影到一個平面。

直覺上容易理解為何齊次坐標允許投影。一幾何的解釋是齊次化的過程是將點(px,py,pz)投影到w=1的平面。

對於正交變換,也是一個透視變換,不是實際投影到一個平面上(這是不可逆的),而是將視圖平截頭體變換到前面所說的標准視圖空間。這里的視圖平截頭體設定為始於z = n而終於z = f,其中0 > n > f。在z=n的正方形有小角(l, b, n)而最大角在(r, t, n)。這展示在圖4.19中。

wps_clip_image-7762

圖4.19 矩陣Pp將視圖平截頭體變換到單元立方體(也就是所謂的規范化可視空間)

參數(l, r, b, t, n, f)決定了攝像機的視圖平截頭體。視體的水平視野由平截頭體的左右平面(由l和r確定)間的夾角決定。水平視野越大,攝像機看到的就越多。非對稱平截頭體通過r≠-l或t≠-b創建。非對稱平截頭體用於諸如立體感的觀察(見18.1.4節)和CAVEs[210]。

視體的視野是一個給出場景真實感覺的重要因素。相比計算機屏幕,視點本身有一個物理實體上的視野,其關系為:

Φ=2arctan(w/(2d))                                    (4.67)

其中φ是視野,w是對象垂直於視線的寬度,而d是對象的距離。例如,一個21英寸監視器是大約16英寸寬,而最小的推薦觀看距離(產生35度的實體視野)是25英寸。當距離為12英寸,視野是67度;18英寸,則為48度;30英寸,則為30度。這個簡單的公式可以用於將攝像機鏡頭轉換到視野,例如,一個標准的50mm鏡頭對於35mm攝像機(擁有36mm外框尺寸)給出Φ=2arctan(36/(2*50))=39.6度。

使用一個相比實體更窄的視野設置會降低透視的效果,就像觀察者在場景中被放大。設置一個更寬的視野會使得對象表現得出現扭曲(像使用廣角鏡),尤其是在靠近屏幕的邊緣會增大旁邊對象的比例。但是,更寬的視野使得觀察者感覺場景更為廣大和震撼,並有提供用戶更多周遭信息的好處。

將平截頭體變換到單元立方體的透視變換矩陣由公式4.68給出:

wps_clip_image-30932 (4.68)

在對點應用變換后,我們得到另一個點q=(qx,qy,qz,qw)T。這個點的W分量,qw,既非零也不等於1。為了得到投影的點,p,我們需要除以qw:p=(qx/qw,qy/qw,qz/qw,1)T。矩陣Pp總是實現z=f對應+1而z=n對應-1。透視投影被執行,裁剪和齊次化(除以w)會被執行以得到規范化的設備坐標。

為了得到OpenGL的透視變換,因為與正交投影相同的原因首先乘以s(1,1,-1)。這可以簡單地通過對公式4.68的第三列數值取負實現。在這鏡像變換被應用后,其遠值和近值會變成正值,其中0< n’< f’,就像它傳統展示給用戶那樣。然而,它依然代表沿着世界坐標系的z軸負向,這個視圖的方向。為了提供參照,這是OpenGL的公式:17

wps_clip_image-25438 (4.69)

一些APIs(例如DirectX)將近平面對應為z = 0(而非z = -1)而遠平面z = 1。還有,DirectX使用左手坐標系定義它的投影矩陣。這意味着DirectX沿z軸正向看,並且近值和遠值都為正數。以下是DirectX的公式:

wps_clip_image-14077                              (4.70)

DirectX在它的文檔中使用行主元的形式,所以這個矩陣通常以轉置的形式出現。

使用透視變換的一個效果是深度計算值並非與輸入的pz值成線性變化。例如,如果n’= 10和f’= 110(使用OpenGL的術語),當pz是60個單位沿z軸負向(也就是中間點)規范化設備坐標深度值為0.833,而非0。圖4.20展示了不同的近平面到原點距離的影響。近遠平面的放置影響着Z緩存的精度。這個影響將在18.1.2節中深入討論。

wps_clip_image-15902

圖4.20 不同近平面與原點距離的影響。距離n’- f’恆定保持為100。當近平面靠近原點,遠平面附近的點使用一個較小的規范化設備坐標深度空間。這個影響使得當點距離近平面遠時z緩存降低精度

進一步閱讀和資源

一本以較不痛苦的方式建立一個人對矩陣的直覺的書是Farin和Hansford的《The Geometry Toolbox》[333]。另一本有用的著作是Lengyel的《Mathematics for 3D Game Programming and Computer Graphics》[761]。對於不同的視角,很多計算機圖形學文章,例如Hearn和Baker[516],Shirley[1172],Watt和Watt[1330],和Foley等人的兩本書[348,349],都包括了矩陣的基本知識。《Graphics Gems》系列[36,405,522,667,982]展示各種變換相關的算法並在線提供相應的代碼。Golub和Van Loan的《Matrix Computations》[419]是綜合研究矩陣技術的一個起點。見http://www.realtimerendering.com中用於不同變換的代碼,包括四元數。更多的關於骨骼子空間的變形、頂點混合和形體插值可以閱讀Lewis等人的SIGGRAPH論文[770]。

Hart等人[507]和Hanson[498]提供了一個可視化的四元數。Pletinckx[1019]和Schlag[1126]展示在一系列的四元數見進行平滑插值的不同方法。Vlachos和Isidoro[1305]堆到了用於四元數C2插值的公式。與四元數插值問題相關的是沿曲線計算一個一致的坐標系統。這為Dougan[276]嘗試。

Alexa[16]和Lazarus和Verroust[743]展示了關於不同變形技術的綜述。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM