本發(fā)明涉及一種GPU上針對延遲著色反走樣繪制的優(yōu)化方法,屬于計算機軟件技術、計算機圖形學、虛擬現實技術領域。
背景技術:
延遲著色技術是為了解決正向繪制方法中大量的重復像素計算而發(fā)展出來的一項技術,它的核心思想是將三維圖元的光柵化操作和光照計算分離。該方法分為兩個階段,幾何繪制階段和光照計算階段。
在幾何繪制階段中,場景中的三維圖元(或稱為三維幾何圖元,含多邊形、參數表面等)經過正常的模型視圖變換和投影變換到屏幕空間執(zhí)行光柵化操作以及深度測試操作,但是在光柵化之后形成的像素處理過程中(即像素著色器或者片元著色器)不執(zhí)行光照計算,而只是將光照計算用到的所有參數—如位置、法向、材質等信息—記錄在若干離屏緩沖區(qū)中。這一組離屏緩沖區(qū)稱為“幾何緩沖區(qū)”(G-Buffer)。幾何繪制階段結束后,幾何緩沖區(qū)中每個像素存儲了該像素上離視點最近的(即最終可見的)三維圖元的光照參數。
第二步光照計算階段對幾何緩沖區(qū)的每一個像素進行光照計算,將光照計算結果輸出到幀緩沖并在顯示設備上顯示或者將結果輸出其它離屏緩沖區(qū)上,這一步得到真正的具有顏色屬性的繪制結果。
走樣(aliasing)現象泛指一切由于采樣率低于信號的分辨率而導致的顯示效果失真現象。多重采樣技術主要解決的是在由于顯示設備的像素分辨率不足導致的多邊形邊緣產生鋸齒的走樣問題,因此也稱為多重采樣抗鋸齒技術。該技術不僅可以處理單個多邊形(含三角形、四邊形等多邊形)光柵化產生的邊緣鋸齒,也可以處理多個多邊形彼此相交時在交線處產生的鋸齒。
該技術與超級采樣技術相似,通過提高像素分辨率,即屏幕空間的空間采樣分辨率來實現抗鋸齒的目的。無論是超級采樣還是多重采樣,每一個像素通常會根據模板產生多個采樣點(也就是一個像素包含多個采樣點),但是與超級采樣不同的是,多重采樣在光柵化階段,對每個多邊形覆蓋到的每個像素只產生一份像素數據(傳統上也稱顏色數據),多重采樣中只有深度信息和覆蓋率信息需要每個采樣點分別計算。這樣可以減少大量透視插值操作,也可以大大減少像素著色器的執(zhí)行次數,對計算資源的消耗與超級采樣相比大大降低。當然,由于屏幕緩沖區(qū)的大小和需要執(zhí)行的深度測試、模版測試和混合(blend)操作的數量仍然沒有減 少,該方法對于GPU的像素輸出單元(ROP unit)的壓力仍然較大。
多重采樣使用比超級采樣少得多的計算量,達到了非常接近的繪制效果,至今仍然是三維實時繪制應用程序中使用最為廣泛的抗鋸齒算法。當然多重采樣也并非完全沒有缺陷,如果需要在像素著色器中輸出深度,那么多重采樣的深度插值就會失效,在多邊形交線處會沒有抗鋸齒效果。
如果在延遲著色技術中進行反走樣(以多重采樣為例),則延遲著色最核心的光照計算階段在GPU的像素著色器(或者稱為片元著色器)中執(zhí)行流程可以表示為下列偽代碼:
在該流程中,首先通過紋理查找獲得當前像素是否需要進行多重反走樣的標記,然后根據該標記的值分別進行處理:如果當前像素需要進行反走樣,則依照反走樣采樣點的數目進行分別采樣并將個采樣點光照計算的結果進行融合處理以獲得最終該像素的光照和顏色;如果不需要進行反走樣,則直接計算出該像素點的光照和顏色。
實際實驗表明,按照該通用流程實現的系統執(zhí)行效率并不高。即使屏幕上需要執(zhí)行多重采樣光照計算的像素只占極小的比例,光照計算階段耗費的時間也比不使用多重采樣的情況長很多,在表1中所示的簡單方法即為上述方法所實現的結果。
技術實現要素:
針對現有延遲著色繪制中進行反走樣方法中存在的效率低的關鍵問題,本發(fā)明的目的在于提供一種GPU上針對延遲著色反走樣繪制的優(yōu)化方法。
本發(fā)明的技術方案為:
一種GPU上針對延遲著色反走樣繪制的優(yōu)化方法,其步驟為:
1)在幾何繪制階段中,將三維場景中的三維圖元變換到屏幕空間執(zhí)行光柵化操作以及深 度測試操作,形成與屏幕空間像素位置對應的多個離屏緩沖區(qū);然后將每個離屏緩沖區(qū)與紋理對象綁定,得到紋理數據;
2)繪制與屏幕等大的多邊形并使得多邊形在光柵化過程中填充整個屏幕,在像素處理器中首先對所有不需要多重采樣處理的像素計算光照,丟棄需要多重采樣處理的像素并記錄該像素的位置;
3)計算步驟2)中記錄的像素的光照;
4)將步驟2)計算的單采樣像素的光照和步驟3)計算的多重采樣像素的光照進行合成,得到該三維場景的光照繪制結果。
進一步的,在步驟3)中,計算步驟2)中記錄的像素的光照的方法為:使用計算著色器計算每一多重采樣像素的顏色,在計算著色器中直接將像素顏色存儲到紋理圖像的對應位置。
進一步的,所述計算著色器為每一像素分配一個線程來計算該像素的光照;其中,該線程依照反走樣采樣點的數目進行分別采樣,并對采樣點的光照進行計算,然后在該線程內將該像素所包含的多個采樣點的光照結果進行融合處理以獲得該像素點最終的光照和顏色。
進一步的,所述著色器為每個像素的每一采樣點分別分配一線程,然后并行執(zhí)行所分配的線程進行光照計算,最后將多個線程的光照計算結果按照對應關系融合到所屬的像素中,得到該像素的光照和顏色。
進一步的,在幾何繪制階段,為每個像素設置一個標記,標記該像素是否進行多重采樣光照計算;步驟2)中,像素處理器根據是該標記判斷像素是否進行多重采樣光照計算。
進一步的,在步驟3)中,計算步驟2)中記錄的像素的光照的可選方法為:根據記錄的每個需要多重采樣的像素位置,在該位置重新繪制為一個點圖元,該點圖元光柵化成為一個像素并觸發(fā)形成一個線程,在該線程中對該像素進行多重采樣的光照計算。
與現有技術相比,本發(fā)明的積極效果為:
實驗結果表明,本發(fā)明所提出的多種方法和手段可以不同程度地提升整個繪制中光照計算的效率,最低也有50%性能的提升,最高可以達到150%以上的性能提升。
附圖說明
圖1為本發(fā)明的方法流程圖;
圖2為典型場景中的多重采樣效果圖;
(a)需要執(zhí)行多重采樣的像素;(b)受到多重采樣影響的區(qū)塊。
具體實施方式
本發(fā)明著重解決了在延遲著色方法中執(zhí)行反走樣效率低下的問題,通過對流程的優(yōu)化提升了延遲著色反走樣繪制的效率。本發(fā)明首先分析出了通用延遲著色反走樣方法效率低下的兩個原因:執(zhí)行路徑分離(branch divergence)和光柵化管線阻塞。然后采用兩步法解決,第一步首先填充整個屏幕,對所有不需要多重采樣處理的像素計算光照,丟棄所有需要多重采樣處理的像素并把這些像素的坐標記錄下來,第二步再處理這些需要多重采樣的像素。在第二步中,本發(fā)明還設計了多種可行的策略和實現的手段。
通用延遲著色反走樣方法效率低下的兩個原因:
1)執(zhí)行路徑分離
現代GPU一般都采用線程編組的執(zhí)行策略,例如NVIDIA的GPU將32個線程編為一組,稱為一個warp,AMD的GPU將64個線程編為一組,稱為一個wavefront。同一組內的所有線程總是執(zhí)行同一條指令。如果在著色器程序執(zhí)行過程中發(fā)生了分支,同一個編組內部的某些線程需要執(zhí)行分支的一側,另一些線程需要執(zhí)行分支的另一側,那么GPU必須先執(zhí)行一側的指令,再執(zhí)行另一側的指令,總時間將是分支兩側的執(zhí)行時間之和。
在光柵化階段,在屏幕上相鄰的像素一般被分到同一個線程編組中執(zhí)行像素著色器。例如NVIDIA GPU會將屏幕劃分為許多4×8像素大小的矩形,每個矩形中的像素對應的像素著色器實例編為一個warp。這就意味著在光照計算階段,如果在4×8大小的矩形中哪怕只存在一個像素需要執(zhí)行多重采樣處理,整個矩形區(qū)域內所有32個像素的計算都會被拖慢。
一般而言對于一個場景,其中需要執(zhí)行多重采樣的像素并不多。但是如果將多重采樣像素所在的4×8矩形區(qū)域中的所有像素都做上標記,可以看到會有大量像素的需要執(zhí)行多重采樣光照,會嚴重影響繪制效率。
圖2(a)是本系統中的一個場景,其中需要執(zhí)行多重采樣的像素用純黑色標出,可以看到這樣的像素并不多。但是如果將多重采樣像素所在的4×8矩形區(qū)域中的所有像素都做上標記,則結果如圖2(b)所示,可以看到有大量像素(形成多重采樣像素的區(qū)塊)的計算過程由于受到多重采樣光照計算影響而被減慢了。
2)光柵化管線阻塞
同一個場景在GT 640GPU(包含一個流處理器(測試時使用的這個子型號與大多數GT 640不同,一般的GT 640包含兩個流處理器),192個浮點計算單元,線程并發(fā)數2048個。)上執(zhí)行延遲著色光照計算,如果某一時間段內處理的所有像素都不需要執(zhí)行多重采樣光照,那么這個時間段內幾乎所有邏輯核心都處于工作狀態(tài);如果有某個像素正在進行多重采樣光 照計算,那么對應的時間段內經常會有許多邏輯核心沒有分配到處理任務,處于閑置狀態(tài)。
根據GPU硬件光柵化引擎的設計原理可知,是像素著色器的執(zhí)行時間過長導致光柵化管線出現了阻塞,影響了新像素的順利生成,導致GPU核心利用率降低。
本發(fā)明的效率優(yōu)化方法
既然耗時較長的多重采樣光照計算會影響GPU的整體運行效率,本發(fā)明的解決方案是將延遲著色的反走樣方法的光照計算過程拆成兩步,將多重采樣光照計算和普通光照計算分離開來。本發(fā)明的步驟如下:
1)在幾何繪制階段中,場景中的三維圖元(或稱為三維幾何圖元,含多邊形、參數表面等)經過正常的模型視圖變換和投影變換到屏幕空間執(zhí)行光柵化操作以及深度測試操作,形成與屏幕空間像素位置對應的多個離屏緩沖區(qū)(即一個像素位置與多個離屏緩沖區(qū)中該位置的元素對應,都屬于該位置像素所包含的信息),這些離屏緩沖區(qū)中保存了后續(xù)階段光照計算需要用到的所有參數—如位置、法向、材質等信息。同時,每個像素都帶有一個標記,標記該像素是否進行多重采樣光照計算,這些標記形成了一個標記緩沖區(qū)。在實現時,每個離屏緩沖區(qū)均可與紋理對象綁定,從而變成紋理數據,可作為后續(xù)紋理采樣數據使用。
2)繪制與屏幕等大的多邊形并使得多邊形在光柵化過程中填充整個屏幕,在像素處理器中根據是否進行多重采樣光照計算的標記進行判斷(判斷的方式可采用紋理采樣獲得其標記值的方式),對所有不需要多重采樣處理的像素(即非多重采樣像素)進行計算光照,而丟棄所有需要多重采樣處理的像素(所謂丟棄一個像素,是指像素處理器中的一個操作,它可以終止處理該像素的線程,而不再執(zhí)行該線程后續(xù)的所定義的操作)并把這些像素的坐標(位置)記錄下來。
3)對所有需要進行多重采樣光照計算的像素進行處理,該步處理有如下多種不同的方法可以實現。
3.1)最簡單的實現方法是根據步驟2)所記錄的需要多重采樣的像素位置,重新在每個位置繪制一個點圖元(如采用OpenGL中的GL_POINT定義實現),利用GPU的光柵化功能填充這些像素,而每一個點圖元光柵化成為一個像素并觸發(fā)形成片元處理器(或者像素處理器,Fragment Processor/Pixel processor)上的一個線程,在該線程中可以進行多重采樣的光照計算,也就是依照反走樣采樣點的數目進行分別采樣并將采樣點的光照進行計算,最后將一個像素所包含的多個采樣點的光照結果進行融合處理以獲得最終該像素點的光照和顏色,該方法的結果對應表1中的點繪制方法。這種方法的優(yōu)點是實現簡單,基本可以復用之前未作優(yōu)化的著色器程序代碼。其缺點是GPU的光柵化引擎在處理點類型的圖元時仍然會遵循把同一個區(qū)域內的多個像素分到一個線程組中的策略,因此GPU的利用率還是不夠高。
3.2)較優(yōu)的方法是在執(zhí)行完步驟2之后使用計算著色器計算多重采樣像素的顏色,不需再借助光柵化操作填充像素,而是在計算著色器(Compute Shader)程序中進行光照計算并直接將像素顏色存儲到紋理圖像的對應位置。相對于光柵化的方法,這種方法對著色器程序的改動較大,而且需要自己編寫代碼才能實現像素混合(blend)操作,光柵化時自動進行的不同色彩模式之前的轉換(如sRGB與RGB的轉換)也必須在著色器程序中實現,總體來說實現較為復雜。但是使用計算著色器可以自由調整線程組的分配方式,因此這種方法是所有方法中GPU利用率最高的。
在計算著色器中進行多重采樣光照計算的方式又分為兩種:每個線程處理一個像素中所有的采樣點計算光照(對應表1中的每線程一個像素),或者每個線程處理一個采樣點計算光照(對應表1中的每線程一個采樣點)。前一種方式中,在每一個線程內部依照反走樣采樣點的數目進行分別采樣,并對采樣點的光照進行計算,最后在一個線程內將一個像素所包含的多個采樣點的光照結果進行融合處理以獲得最終該像素點的光照和顏色。后一種方式中,在每一個線程對應一個采樣點,并計算該采樣點的光照,多個采樣點的光照計算以線程并行的方式并行執(zhí)行,最后將多個線程的光照計算結果按照對應關系融合到所隸屬的一個像素中,以獲得最終該像素的光照和顏色。后一種方法需要啟動的線程數量較大,但是每一個線程需要執(zhí)行的計算量更小,在利用GPU的并行計算能力上更有優(yōu)勢(對應表1中的每線程一個采樣點)。另外,使用后一種方法時每個warp內有多個線程處理同一個像素中不同的采樣點,單個warp需要讀取的像素數據較少,在空間上的分布也相對較為集中,有助于提高warp內部的訪存局部性。
4)將非多重采樣像素的光照計算結果與多重采樣像素的光照計算結果進行融合,合成最終的繪制結果并輸出色彩圖像。
表1給出了同一場景在NVIDIA GeForce GT640和GTX970兩個型號的GPU上使用不同的多重采樣處理算法所用的時間(單位為毫秒)。不難看出,在GTX970上,每個線程處理一個采樣點的方法相比其他方法具有非常明顯的性能優(yōu)勢。在16×MSAA的情況下,每個像素包含16個采樣點,此時每個計算著色器線程處理一個像素的方法由于每個線程計算任務較重,訪存局部性很差,效率甚至不如點繪制方法。只有每個線程處理一個采樣點的方法始終保持了非常高的多重采樣處理性能。
表1 不同多重采樣處理方法的性能比較