摘要:隨著圖形處理器性能的提高及其可編程特性的發展,圖形處理流水線的某些處理階段和圖形算法逐漸從CPU向GPU轉移。文章介紹了可編程圖形硬件基礎,分析了基于GPU的光線跟蹤技術的實現原理。設計的6個實驗場景所包含的三角形面片數,從2016個到60960個成復雜度遞增,在3種不同分辨率下,分別實現GPU和CPU的光線跟蹤繪制。對實驗結果比較、分析后,得到了GPU加速的光線跟蹤技術的特點。
關鍵詞:圖形硬件;圖形處理器;可編程性;光線跟蹤
0 引言
光線跟蹤是一種圖像合成技術,它通過模擬光線與物體表面的交點來實現圖像的繪制。目前的一些交互式光線跟蹤和全局光照的應用都是基于超級計算機和PC機集群的。這類系統因其昂貴的價格嚴重阻礙了其發展與推廣。隨著圖形處理器(GPU)性能的大幅度提高以及可編程特性的發展,圖形處理流水線的某些處理階段和圖形算法逐漸從CPU向GPU轉移。GPU的體系結構是一種高度并行的單指令多數據(singleInstruction Multiple Data,SIMD)指令執行體系,其計算速度非常高。GPU的指令執行方式和CPU不一樣,不能直接執行在CPU中實現的算法。圖形硬件技術一個最主要的突破是引入了可編程功能,它允許用戶編制自定義的著色器程序(shaderProgram)來替換原來固定流水線中的某些功能模塊。結合當前GPU特性,文中提出了一種高質量的渲染方法,把光線跟蹤表示成一種流計算模式,把目前可編程的圖形處理器抽象成通用的流處理器,充分利用了GPU并行處理體系結構的性能優勢。
1 可編程圖形硬件基礎
圖形硬件的可編程能力允許用戶編寫特定的程序來取代固定的圖形管道。在圖形管道中,有兩個可編程單元:點處理單元和片元處理單元。點處理單元由點編程引擎(Vertex ProgramEngine)控制,片元處理單元由片元編程引擎(Fragment ProgramEngine)控制。每個單元可由用戶編寫的小程序來控制。這個小程序可用匯編語言
或c語言(cg)編寫,是一組順序執行的指令代碼。這組指令代碼通過圖形驅動程序編譯,并在圖形硬件的相應的編程引擎上執行,從而取代固定圖形管道中相應單元的功能。
1.1 點編程引擎
點編程引擎可實現完全控制點的轉換、光照計算、復雜的點操作,產生紋理坐標、操作紋理矩陣等功能。這些實現都由圖形硬件來處理。用戶可用點編程引擎實現用戶定制的功能。當點編程被允許時,幾何數據流會由點程序來處理,繞過了固定的圖形管道。同時,如果用點程序來處理點數據流,就必須處理所有要處理的功能。點程序由嚴格按順序執行的SIMD指令組成,不能使用條件語句。點程序代碼越少,執行越快。使用點程序的優點有:比軟件實現快,一個優化的光照模型的點程序要比固定圖形管道提供的光照模型要快。
1.2 片元編程引擎
固定圖形管道的片元處理單元用于定義紋理應用、紋理環境、顏色疊加和霧化操作。正像點編程模型中提到的一樣,這個固定的處理不能給用戶提供更大的靈活性和擴展性。可編程的片元處理單元提供了基于每個片元的靈活的計算。片元程序是一組順序執行的指令代碼,它在像素被渲染時執行。片元程序的指令和點程序的指令非常接近。片元程序不能像點程序那樣,單獨存在。片元程序在運行的時候,必須有一個點程序被激活。
2 基于GPU的光線跟蹤實現
2.1 可編程圖形處理器抽象化
紋理內存通常用于存儲場景中幾何體的紋理。光柵器產生的片元都有自己的紋理坐標。這個紋理坐標可作為包含顏色信息的二維內存區域的索引。這個方法的一個主要限制是:從內存中提取的地址沒法通過計算獲得,它僅是一個被光柵化了的幾何體屬性。
為了解決這個問題,本文使用圖形處理器中新增加的功能——依賴紋理查找。依賴紋理訪問允許由片元程序計算從紋理內存中要提取的地址。同時,它允許紋理查找的結果用于其它內存地址的計算。圖形處理器性能的增強,使得在單渲染通道能夠實現反射、凹凸映射等效果。
通過依賴紋理查找,能把紋理內存子系統作為一個通用的只讀內存來使用,以便在圖形硬件上實現通用計算。圖形處理器的這個功能使得可在GPU上實現許多包含復雜數據結構的算法,和實現查找這些復雜數據結構中的元素。依賴紋理查找具體的實現方法如圖1所示。圖中顯示了一個簡單的三角形網格數據結構,其中to、t1、t2、t3分別表示4個不同的三角形面片,v0、v1、v2、v3、v4分別表示三角形面片的頂點坐標。4個三角形網格使用兩個紋理分別存儲三角形的頂點編號和頂點坐標。
每個三角形被存儲成一個RGB紋理單元,利用R、G、B通道保存每個三角形面片的頂點編號。三角形的頂點坐標同樣分別用R、G、B通道存儲x、y、z分量。若想獲取一個三角形的3個頂點位置,只需完成4次依賴紋理提取:先從三角形紋理中提取頂點編號,后根據紋理中的R、G、B通道中編號,從頂點坐標紋理中分別提取頂點的位置。
目前,圖形處理器不支持一維紋理,許多數據結構超過了一維紋理的最大尺寸。本文使用二維紋理來實現紋理內存的抽象。紋理內存的簡單抽象能把復雜的數據結構載入顯示內存以及使用片元程序進行處理。更重要的是,它使GPU上的紋理內存可作為一個簡單的只讀內存來使用。這是GPU作為一個通用處理器的關鍵所在。
用紋理內存的抽象來遍歷網格加速結構。每個網格單元包含一個指向這個網格單元中三角形列表的起始地址。若網格單元是空的,則用一個空指針表示。三角形列表用另外一個紋理表示,三角形列表中的每個實體是一個指向表示三角形的頂點數據集合的指針。三角形頂點存儲在3個獨立紋理的集合中。在系統實現過程中,每個三角形面片的頂點都是獨立存儲,不共享任何頂點數據。頂點法向量、頂點顏色等渲染數據,頂點位置也是獨立存儲。紋理內存作為存儲系統中不同內核之間傳遞數據的流緩沖區使用。
2.2 基于流的光線跟蹤設計
實現基于流的光線跟蹤最大的難度是如何把光線跟蹤映射到設計的流計算模型中。GPU有很強的流處理能力,但在GPU上實現遞歸非常困難。本文把光線跟蹤細分成多個內核,內核通過數據流聯系在一起。以下將分析如何把光線跟蹤形式化為一個流計算。
不管是繪制靜態場景還是動態場景,首先要確定光線跟蹤能夠處理的幾何體片元的類型,以及系統實現中所使用的加速結構的類型。假設場景中所有幾何體都使用三角形表示。光線跟蹤能夠渲染由不同幾何體片元組成的場景,其中最適合的是三角形。因為圖形硬件僅支持三角形渲染,其它表面形狀雖能使用,但在渲染之前它們都要被轉換成三角形。其次,建模程序和掃描軟件產生的模型都是由三角形網格組成的,當只有一種簡單圖形單元被允許時,光線跟蹤會顯得更加簡單有效。對于流計算來說,這些限制意味著所有的繪制可以被相同的內核集來處理,這種方式簡化了系統的數據流。
為了實現基于流模式的光線跟蹤,把基于流實現的光線跟蹤細分成4個內核,分別是:視光線產生器、網格遍歷、光線與三角形求交和渲染。如圖3所示,每個內核的輸入顯示在盒子的左邊,內核之間傳輸的流數據的類型由虛線所指的內容表示。這種細分的方式在流編程模型中并不是強制性的,因為在目前GPU執行的片元程序還缺乏分支功能(不過最新的Nvidia GeForce6800、Nvidia GeForce7800片元處理器已經支持分支處理功能)。
視光線產生器內核產生一束視光線流,每根視光線都和圖像中的某個像素相關聯,以此形成光線向量集。網格遍歷內核讀取由視光線產生器產生的光線流,然后作用光線,使光線一步一步地遍歷網格直到碰到一個包含三角形面片的體素,光線和體素對被輸出并傳遞到光線與三角形面片求交測試內核里。
求交測試內核主要負責測試該光線是否和體素中包含的三角形面片有交點。光線和體素對被求交測試器處理后有兩種輸出情況,若光線和體素包含的三角形面片相交,則交點所在的三角形面片被輸出到繪制階段;若光線與體素中包含的任何三角形面片都沒有交點,則光線返回遍歷內核并按照遍歷算法搜索下一個包含三角形面片的體素。
繪制內核的功能主要是計算顏色值。如果一根光線終止在相交點上,那么把這個相交點的顏色值寫進累加的圖像上。此外,繪制內核可能產生陰影或次光線,這種情況下,將這些新產生的光線返回到遍歷階段,開始新的跟蹤。
3 實驗結果與分析
實驗目的:在場景復雜度不同的測試環境下,對兩種光線跟蹤繪制方式(方式1:基于GPU加速;方式2:基于CPU的傳統遞歸方式)的性能進行測試。
算法和數據實驗的硬件平臺:512M內存和3.0GHzPentium CPU的主機,配備具有64M顯存的Nvidia 6800圖形顯卡。
用Visual C++.NET、OpenGL以及cg語言來實現算法程序。系統中使用的場景加速結構的網格精度都使用了默認模式,即由128*128*128個體素組成。
3.1 實驗結果
6個不同復雜度的場景效果圖都是基于GPU的光線跟蹤繪制實現的。場景1至場景6包含的三角形面片數,從2016個到60960個成復雜度遞增。
基于GPU加速的光線跟蹤繪制速度的測試不包含加速結構構建的時間,因為實驗的目的是測試GPU加速對場景繪制速度的影響。對于靜態場景的繪制,加速結構構建可以在預處理階段完成。以下將對基于GPU加速的光線跟蹤繪制進行分析。這兩種實現方式在分辨率為256*256、512*512、1024*1024的情況下,分別繪制場景1-6時。
3.2 結果分析
數據結果和系統實現所采用的軟硬件環境,對基于GPU加速的光線跟蹤實現方法,得出以下結論:
(1)與方式2相比,方式1更適合復雜場景的繪制。場景復雜度越高,GPU高性能的計算能力體現越明顯。
(2)當場景復雜度較低時,場景的加速結構中存在大量的空體素(體素中沒有包含場景對象)。這導致光線遍歷加速結構中的空體素消耗大量的計算時間,且分辨率越高這種消耗越明顯。當光線遍歷空的加速結構所耗的時間和有效場景繪制所耗的時間達到一定的比例程度時,方式1的整體效果不會得到很好的體現,甚至不如傳統的光線跟蹤繪制。
(3)在相同的分辨率情況下,當場景復雜度的增加時,方式1消耗時間的增加并不明顯。這主要由光線遍歷加速結構所致。實驗繪制的場景使用的加速結構是由128*128*128個體素組成,不管場景是否復雜,光線遍歷加速結構都要耗費一定的時間。
(4)實驗所采用的圖形硬件還不支持條件分支以及循環,這降低了系統實現的靈活性及其繪制速度。
(5)在選用加速結構時,主要考慮硬件表示的方便性。若要使加速性能更優,則應降低光線遍歷加速結構所耗的時間。可從兩方面改進系統性能,一是通過使用層次包圍盒技術來進一步優化;另一是在現有的加速結構的基礎上,通過降低光線遍歷空的加速結構的消耗來優化遍歷。如果在未來幾年,圖形硬件的發展速度像過去幾年一樣迅速,未來圖形硬件完全有可能實現實時的光線跟蹤。
4 結束語
本文通過對基于GPU加速的光線跟蹤技術,設計了6個不同復雜度的場景,在分辨率分別為:256*256、512*512、1024*1024時,實現了GPU和CPU實現光線跟蹤繪制。從實驗結果可得到基于GPU加速的光線跟蹤的優勢。基于可編程圖形硬件的算法,既達到了實時的效率,也保證了算法的質量。
目前最迫切需要解決的問題是,CPU和GPU之間的數據交換限制與負載均衡算法。在本論文完成之時,PCI-Expres技術已經開始實用化,市場上已經出現了支持PCI-E的顯卡。顯然,這將有利于解決GPU應用中的帶寬限制問題。隨著GPU可編程能力的進一步增強,可以將GPU作為CPU的協處理器。