《Fundamentals of Computer Grahpics》虎书第三版翻译——第一章 介绍
1.1 圖形領(lǐng)域
在任何領(lǐng)域進行強分類是危險的,但大多數(shù)從事圖形學行業(yè)的人都會贊同以下這些計算機圖形學的主要領(lǐng)域:
建模:使用數(shù)學規(guī)格進行建模,這些數(shù)據(jù)是能存儲在計算機上的形狀和外觀屬性。例如,一個咖啡杯可以被描述作為一組以一些插值規(guī)則連接的有序的三維空間上的點,以及反射模型,該模型描述了光與杯子是如何相互作用的
渲染:出自美術(shù)的一個專業(yè)術(shù)語,用于生成從3D計算機模型渲染后的圖像
動畫:通過一系列圖像創(chuàng)造幻覺運動的一門技術(shù)。動畫使用模型和渲染但添加了隨時間運動的關(guān)鍵問題,在基本的建模和渲染中這類問題并不常見。
還有許多其他領(lǐng)域涉及到計算機圖形學,但他們是否是計算機核心領(lǐng)域因人而異。這些內(nèi)容在本書內(nèi)容會至少會提及一點。內(nèi)容包括:
用戶交互:它處理用戶和輸入設(shè)備的接口,例如鼠標和鍵盤,應用程序,將圖像反饋給用戶,以及其他感官的反饋。從歷史上看,這一領(lǐng)域與圖形IC有很大的關(guān)聯(lián),因為圖形學研究人員是最早接觸這些無處不在的輸入/輸出設(shè)備的。
虛擬現(xiàn)實:嘗試讓用戶沉浸在3D世界。這通常需要立體圖形以及對頭部運動的反應。為了更加逼真的虛擬現(xiàn)實,聲音和力反饋也應該提供。因為這一領(lǐng)域需要先進的3D圖形和先進的顯示技術(shù),所以它通常與圖形密切相關(guān)。
可視化:通過可視化讓用戶理解復雜的信息。通常這些圖像與圖形學問題息息相關(guān)。
圖像處理:處理2D圖像的操作。被用于圖像和視覺兩個領(lǐng)域。
3D掃描:使用測距技術(shù)創(chuàng)建測量的三維模型。這些模型對于創(chuàng)造復雜的視覺圖像很有用,而且處理這些模型需要用到常用的圖形學算法
計算攝影:利用計算機圖形學、計算機技術(shù)視覺和圖像處理方法,以實現(xiàn)新的攝影方式,從根本上捕獲對象、場景和環(huán)境。
1.2 主要應用
幾乎所有的領(lǐng)域都可以用到計算機圖形學,但是計算機圖形學技術(shù)的主要使用者包括以下行業(yè):
電子游戲:對復雜的3D模型和渲染算法的使用日益增長
卡通:通常由3D模型直接渲染而來。許多傳統(tǒng)的2D卡通動畫的使用3D模型渲染出來的背景,這樣可以不斷移動的視點,且不需要花費大量藝術(shù)家的時間。
視覺效果:使用了幾乎所有類型的計算機圖形學技術(shù)。幾乎每部現(xiàn)代電影都使用數(shù)字合成來讓前景和背景疊加。許多電影還使用 3D 建模和動畫來創(chuàng)建合成環(huán)境、物體,甚至 大多數(shù)觀眾永遠不會懷疑的角色不是真實的。
動畫電影:使用了許多與視覺效果相同的技術(shù)效果,但不需要讓圖像看上去很真實。
CAD/CAM :代表計算機輔助設(shè)計和計算機輔助制造。 這些領(lǐng)域使用計算機技術(shù)在電腦上設(shè)計零件和產(chǎn)品,然后使用這些仿真軟件來輔助制造。 比如很多機械零件都是在 3D計算機建模包中設(shè)計的,然后在計算機控制的銑削設(shè)備上自動生產(chǎn)。
模擬:可以被認為是精密的視頻游戲。 例如,一個飛行模擬器使用復雜的 3D 圖形來模擬開飛機。 這種模擬對于那些安全性十分重視的領(lǐng)域在前期培訓上很有幫助,例如駕駛。以及對培養(yǎng)有經(jīng)驗的用戶的場景培訓非常有用,比如創(chuàng)造成本高昂或危險的特殊消防場景。
醫(yī)學成像:通過掃描患者的數(shù)據(jù)來創(chuàng)建有意義的圖像。例如,計算機斷層掃描(CT)數(shù)據(jù)集是由密度值的大型3D矩陣組成的。計算機圖形學用于創(chuàng)建渲染后的圖像,幫助醫(yī)生提取出最重要的信息。
信息可視化:不需要形象化描述就能創(chuàng)建數(shù)據(jù)的圖像。例如,不需要形象化描述就能通過這些巧妙的繪圖技術(shù)來描述十種不同股票的價格的變化趨勢,這樣可以幫助人們很容易找出這些數(shù)據(jù)的規(guī)律。
1.3 圖形API
使用圖形庫的關(guān)鍵是使用圖形學API。應用程序接口 (API) 是執(zhí)行一組相關(guān)操作的標準函數(shù)集合,而圖形API是將圖像和3D表面繪制到屏幕上的基本操作的一組函數(shù)。
每個圖形程序都必須能夠使用兩個相關(guān)的API:用于視覺輸出的圖形API和用于用戶輸入界面API。當前,圖形和用戶界面API有兩種主要的典型。第一種是集成方法,以Java為例,它的圖形和用戶界面工具包是集成的且可移植的程序包,這些程序包已完全標準化并成為語言的一部分。第二種以Direct3D和OpenGL為代表的,其中繪圖命令是與語言綁定的軟件庫(比如C++)的一部分,并且用戶界面軟件是一個獨立的實體,可能因系統(tǒng)而異。在后一種方法中盡管對于簡單的程序,也許可以使用可移植庫層來封裝系統(tǒng)特定的用戶界面代碼,但是編寫可移植代碼很麻煩。
無論你選擇哪種API,基本的圖形調(diào)用都基本相同,本書的概念也都適用。
1.4 圖形管線
如今,每臺臺式電腦都有一個強大的3d圖形管道。他是一個特殊的軟/硬件子系統(tǒng),可以有效的繪制基本的3D物體的透視圖。通常這些系統(tǒng)可以優(yōu)化那些具有共享頂點的三維三角形。管線的基本操作是將3D頂點位置映射到2D屏幕位置并對三角形進行渲染,使他們看上去很逼真,并以適當?shù)那昂箜樞蝻@示。
盡管以有效地以從后往前的順序繪制三角形在當時是最重要的研究問題,但是現(xiàn)在總能使用Z緩沖區(qū)解決,它使用了一個特殊的內(nèi)存緩沖區(qū)來以蠻力解決這個問題。
事實證明在圖形管線所使用的幾何操作幾乎能在由三個傳統(tǒng)的幾何坐標和輔助透視用的第四個齊次坐標組成的思維空間坐標完成。這些4D坐標是使用4×4矩陣和4維向量處理的。因此,圖形流水線包含了許多機器,以便有效地處理和組成各種各樣的矩陣和向量。四維坐標系是計算機科學中使用的最微妙和美麗的結(jié)構(gòu)之一,這無疑是學習計算機圖形學時需要翻過的最大的障礙。每本圖形學書的第一部分的絕大部分都在與這些坐標打交道。
圖像生成的速度很大程度取決于繪制三角形的數(shù)量。由于交互性在很多應用程序比視覺質(zhì)量更重要,因此很有必要讓表示一個模型所使用到的三角形數(shù)量盡可能的最小。此外,如果模型離視野很遠的話,需要三角形的數(shù)量應該比離視野近的要少。這表面以多細節(jié)層次處理(LOD level of detail )表示三角形是很有用的。
1.5 數(shù)值問題
許多圖形學程序?qū)嶋H上只是3D數(shù)學代碼。對這類程序來說數(shù)學問題通常是至關(guān)重要的。在“舊時代”,很難以健壯和可移植的方式處理這些問題,因為機器在內(nèi)部數(shù)字表示不同,更糟糕的是以不同和不兼容的方式處理異常。幸運的是,幾乎所有的現(xiàn)代計算機都符合IEEE浮點標準(IEEE標準協(xié)會,1985)。
這方便了程序員對如何處理某些特定數(shù)值作出判斷。
盡管IEEE 浮點有很多特性在編碼數(shù)字算法時非常好用,但對于圖形中遇到的大多數(shù)情況,只有少數(shù)幾個特性是關(guān)鍵的。首先,也是最重要的,是要理解在IEEE 浮點中有三個實數(shù)的“特殊”值:
IEEE浮點有兩種表示形式的零,正零和負零。 雖然?0和+0之間的區(qū)別偶爾很重要,但是當他發(fā)生的時候最好牢記它。
IEEE浮點標準的設(shè)計師做出的一些設(shè)計對于程序員來說非常方便。在處理除0異常的時候,許多處理方式于前面三個特殊值有密切關(guān)系。在這些情況下,異常會被計算機記錄下來,但在許多情況下,程序員可以忽略該異常。具體來說,對于任何正實數(shù)a,涉及無窮大除法的規(guī)則是這樣的:
+a/(+∞) = +0
?a/(+∞) = ?0
+a/(?∞) = ?0
?a/(?∞) = +0
涉及無窮的運算法則和人們預想的一樣,對于正數(shù)a,例如:
∞+∞= +∞
∞ ? ∞=NaN
∞ × ∞=∞
∞/∞=NaN
∞/a =∞
∞/0 =∞
0/0 = NaN
包含無窮值的布爾表達式中的規(guī)則如下所示:
涉及具有NaN值的表達式的規(guī)則很簡單:
IEEE浮點數(shù)最有用的方面可能是如何處理零除;對于任意正實數(shù)a,除以零的規(guī)則是這樣的:
+a/+0 = +∞
?a/+0 = ?∞
如果程序員利用IEEE規(guī)則,許多數(shù)值計算就會變得簡單得多。例如,考慮這個表達式:
這樣的表達會出現(xiàn)在電阻和透鏡情形中。如果除以零將導致程序崩潰(在IEEE浮點數(shù)出現(xiàn)之前,許多系統(tǒng)中都會這樣),則將需要兩個if語句來檢查b和c是否為很小的值或零值。而現(xiàn)在有了IEEE浮點數(shù),如果b或c為零,我們則將根據(jù)需要將a賦值為零。避免特殊情況檢查的另一種常用技術(shù)是利用NaN的布爾屬性。考慮以下代碼段:
A=f(x)
If(A>0)then
Do something
在這里,函數(shù)f可能會返回很不想看到的值,例如∞或NaN,但是if語句的條件是明確的:a = NaN或a =-∞時為false(a < 0),而a = +∞時為true(a > 0)。在確定返回什么值時,if語句通常可以做出正確的選擇,無需進行特殊檢查。這使程序更小,更可靠和更高效。
1.6 效率
沒有使代碼高效運行的魔法。效率是通過仔細權(quán)衡來實現(xiàn)的,對于不同的架構(gòu)這些權(quán)衡是不同的。但是在不久的將來,一個很好的啟發(fā)是程序員應該更多注重內(nèi)存訪問模式而不是操作次數(shù)。這與20年前最好的啟發(fā)相反。之所以會發(fā)生這樣的變化是因為內(nèi)存的速度已經(jīng)跟不上處理器的速度了。由于這種趨勢一直持續(xù)著,有限且一致的內(nèi)存訪問對于性能優(yōu)化的重要性只增不減。
加快代碼速度的合理方法是根據(jù)需求按以下步驟順序進行:
這些步驟最重要的一步是第一步。大多數(shù)優(yōu)化只會讓代碼可讀性更差而且優(yōu)化了個寂寞。而且,把時間花在優(yōu)化上還不如去修bug或者加功能。另外,要小心舊教材;一些經(jīng)典技巧,例如把實數(shù)換成整數(shù),可能不再提高速度,因為現(xiàn)代CPU執(zhí)行浮點運算的速度跟整數(shù)運算一樣快。在任何情況,我們應該對機器和編譯器盡可能的優(yōu)化。
1.7 設(shè)計和編寫圖形程序
某些通用的方法在圖形學程序很有用。在這一節(jié)中。我們提供了一些對你學習本書有所幫助的建議。
1.7.1 類設(shè)計
任何圖形學的關(guān)鍵部分在于為幾何實體(矩陣和向量)以及圖形實體(RGB三原色和圖片)提供良好的類或者示例。這些示例應該盡可能的有效和簡潔。一個常見的設(shè)計問題是我們是否需要把位置和位移歸為不同的類,因為他們的運算規(guī)則是不一樣的。位置1/2沒有任何幾何意義,但位移1/2是有的。在這個問題上幾乎是沒有共識的,這可能會引發(fā)圖形學從業(yè)者進行數(shù)小時激烈的爭論。但為了舉例,我們假設(shè)不會對它們做出分類。
這意味著我們要編寫一些基類,包括:
Vecrtor2:存儲x和y分量的2D向量類。他應該將這些組件存儲在長度為2的數(shù)組中以便能很好的支持索引操作。你也應該包含向量加法,向量減法,點乘,叉乘,標量乘法,和標量除法等運算
Vecrtor3:類似于Vector2
hvector:具有四個分量的同質(zhì)向量(齊次)
Rgb:存儲三個分量的RGB顏色。你也應該支持RGB加法,RGB減法,RGB乘法,標量乘法和標量除法的運算。
Transform:用于變換4*4的矩陣。你應該包含矩陣乘法和成員函數(shù),應用于位置,方向,表面法向量。這些都是不同的,在第六章會看到。
Image:就具有輸出操作的二維rgb像素數(shù)組
您可能還想到了用于單位矢量的特殊類,盡管它們很讓人痛苦
您可能還想到了用于單位矢量的特殊類,盡管它們很讓人痛苦
1.7.2 Float vs Double
現(xiàn)在體系結(jié)構(gòu)表面,降低內(nèi)存使用和保持內(nèi)存訪問一致是提高效率的關(guān)鍵。著以為使用單精度數(shù)據(jù)。然而,避免數(shù)值問題建議使用雙精度算法。權(quán)衡屈居于程序,但最好在類中使用有一個默認值。
我建議使用double進行幾何計算和顏色計算。對于占用大量內(nèi)存的數(shù)據(jù)(例如三角形網(wǎng)格),我建議使用float存儲,但是用成員函數(shù)訪問數(shù)據(jù)時轉(zhuǎn)換為雙精度。
1.7.3 調(diào)試圖形程序
如果你四處詢問,你可能會發(fā)現(xiàn),隨著程序員越來越有經(jīng)驗,他們使用傳統(tǒng)調(diào)試器的次數(shù)越來越少了。使用這樣的調(diào)試器對復雜的程序比簡單的程序要復雜的多。另一個原因是最難調(diào)試的是概念錯誤,即執(zhí)行了錯誤的內(nèi)容,并且很容易調(diào)試了半天缺還找到bug出現(xiàn)的地方。我們發(fā)現(xiàn)一些調(diào)試方法在圖形方面特別有用。
科學的方法:在圖形程序中,有一種很有用的替代傳統(tǒng)調(diào)試的方法。它的缺點是,它與計算機程序員在職業(yè)生涯早期被教導不要做的事非常相似。所以,如果你這樣做,你可能會覺得很”調(diào)皮”:我們創(chuàng)造一個圖像,并觀察他有什么問題,然后我們對出錯原因進行假設(shè)并測試它。例如,在光線追蹤程序中,我們可能會有許多看起來暗像素。這是大多數(shù)人在寫光線追蹤時遇到的典型的”陰影痤瘡“問題。傳統(tǒng)的調(diào)試在這里沒有幫助。相反,我們必須認識到,陰影射線擊中的是正在著色的表面。我們可能注意到,黑點的顏色是周圍環(huán)境的顏色,所以,缺少直射光。直射光可以在陰影中關(guān)閉,所以你可以會假設(shè)這些點被錯誤的標記為陰影,但他們不是。為了測試這個假設(shè),我們可以關(guān)閉陰影檢查,并重新編譯。這表面這些是錯誤的陰影測試,我們可以繼續(xù)檢查。這種方法有時候是良好的實踐,因為我們不必發(fā)現(xiàn)錯誤的值或真正確定概念錯誤。相反,我們只是通過試驗縮小了我們的概念誤差。通常只需要進行幾次試驗就可以找到問題所在,并且這種調(diào)試很有意思。
調(diào)試代碼輸出的圖像:在許多情況下,從圖形程序中獲取調(diào)試信息的最簡單方式是輸出圖形本身。如果你想知道計算每個像素所用到的某個變量的值,你可以臨時修改你的程序的值,并將這些值直接復制到輸出圖像并跳過其他的計算。例如,如果你認為是法平面導致渲染問題,你可以直接將法向量直接復制到圖像(x軸變?yōu)榧t色,y軸變?yōu)榫G色,z軸變?yōu)榧t色),這些色碼圖解就是你程序中實際向量。或許,你懷疑某個特定值有時會超出有效值的范圍,你可以讓你程序在發(fā)生這種情況的時候繪制出高紅亮色的像素。其他常見的技巧包括用明顯的顏色繪制表面的背面(背面是看不到的),根據(jù)物體的ID號給圖像上色,或者根據(jù)計算的工作量給像素上色。
使用調(diào)試器:仍然有一些實例,特別是當科學發(fā)展遇到了矛盾的時候,當沒有什么能代替現(xiàn)在正在發(fā)生的事情的時候。問題在于,圖形程序經(jīng)常涉及到對相同代碼的多次執(zhí)行(每個像素執(zhí)行一次,或者每個三角執(zhí)行一次),這使得從頭開始調(diào)試逐步調(diào)試變得不切實際。最難解決的bug通常只發(fā)生在復雜的輸入。
一種有用的方法是為bug“設(shè)置陷阱”。首先,確保您的程序是確定性的——在單線程中運行它,并確保所有隨機數(shù)都是從固定種子中計算出來的。然后,找出哪個像素或三角形出現(xiàn)了bug,并在您覺得寫錯的代碼前面添加一條語句,該語句僅在可疑情況下才會執(zhí)行。例如,如果您發(fā)現(xiàn)像素(126,247)出現(xiàn)錯誤,就添加:
if x=126 and y=247 then
Pirnt “blarg!”
如果你在打印的句子中設(shè)置了斷點,你可以在計算您感興趣的像素之前進入調(diào)試器。一些調(diào)試器具有“條件斷點”功能,可以在不修改代碼的情況下達到相同的效果。
在程序崩潰的情況下,傳統(tǒng)的調(diào)試器對于查明崩潰的位置很有用。然后,您應該使用斷點和重新編譯在程序中開始回溯,以查找程序出了問題的地方。這些斷言應留在程序中,以備將來可能添加的錯誤。這再次意味著避免了傳統(tǒng)的逐步過程,因為那樣就不會在程序中添加有價值的斷言。
數(shù)據(jù)可視化以進行調(diào)試:一般來說,很難理解你的程序在做什么,因為它會在最終出錯之前會計算出許多中間結(jié)果。這種情況類似于測量大量數(shù)據(jù)的科學實驗,它們的解決方案是相同的:為自己做好設(shè)計方案和圖解,以了解數(shù)據(jù)的含義。例如,在光線跟蹤中,你可能會編寫代碼以可視化光線樹,以便可以看到對像素有作用的路徑,或者在圖像重采樣例程中,你可能繪圖,來顯示從輸入中采樣的所有點。為可視化程序的內(nèi)部狀態(tài)所花費的時間,會得到回報,因為在優(yōu)化時,能夠更好地理解程序的行為。
總結(jié)
以上是生活随笔為你收集整理的《Fundamentals of Computer Grahpics》虎书第三版翻译——第一章 介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 开心一刻:今天下班后,我尾随一女同事,为
- 下一篇: 这只“鸭子不一般”科大讯飞申请“躺倒鸭”