摘 要:隨著科技的進步,3D實時渲染越來越走近每一個人,而人們對于該項技術的運用也隨之增加,除了電子游戲以外,3D實時渲染技術普遍應用于醫療、工業、科研等領域。近年來興起的3D打印和虛擬現實更是把3D實時渲染作為基石而快速成長。3D實時渲染技術一直以來存在幾個重大難題,快速處理大量法光源就是其中之一。現實中,因為有光,人們才能觀察到這個世界。在3D實時渲染中,雖然不一定需要有光,但是模擬出光的效果對于增加真實性至關重要,本文提出一種全新的渲染方法,在可接受的渲染開銷范圍內,實現快速多光源渲染,并且不會對半透明和反走樣有任何限制。通過低分辨率軟光柵化為屏幕每一個區塊單獨計算光源列表,把光源限制在屏幕可見區域內,來剔除絕大多數不必要的計算。這種方法不會對傳統的向前光照有任何影響,僅僅在像素著色階段添加額外的光源列表,具有兼容性好、開發便利、容易模塊化等優點。
關鍵詞:OpenGL實時渲染;3D;
中圖分類號:TN-9 文獻標識碼:A 文章編號:1674-3520(2014)-03-000267-01
一、為什么傳統向前光照不能處理多光源
在講述快速多光源渲染之前,首先需要說明一下傳統的向前光照的基本流程。首先,3D物體通過頂點著色器,變換到投射空間,經過GPU硬件光柵化之后,在像素著色器里,通過被插值過的3D物體的法線與光照相關信息,進行光照計算[1]。以前可能在頂點著色器里計算光照比較多,不過無論如何,光照信息一般都是通過uniform變量傳給著色器,無論頂點還是像素,著色器每次獲取到的數據都是相同的,如果要進行多光源處理,需要把所有光源信息都一起傳進來。對于光源來說,不可能所有光源都會在投射空間占據所有像素點,絕大多數光源可能僅僅占用不到5%,為了5%而在所有的像素內計算光照顯然并不明智。由于GPU的特殊構造,分歧計算開銷很大,無論是在著色器內判斷每個光源是否占用當前像素,還是不判斷直接進行光照計算,都是非常巨大的開銷,也許十幾個光源的開銷還能接受,但是幾百個光源顯然是不可能接受了。
二、快速多光源渲染的基本流程
第一步,通過與屏幕比例相同的超低分辨率軟光柵化,為每一個軟光柵化像素生成一個獨立的光源數據列表。第二步,把所有像素的光源數據列表合并為一個總列表,同時記錄下每個軟光柵化像素列表數據在總列表內的開始位置,以及當前像素列表內的光源數量。第三步,把每個像素在總列表內的開始位置與光源數量,按照像素在GPU內的分布,組成一個雙通道紋理,一個通道是像素在總列表內的開始位置,另一個通道是光源數量。第四步,把第二步得到的總列表和第三步得到的紋理,傳給顯存。第五步,在渲染3D物體的像素著色器內,根據當前像素在屏幕上的坐標,從第三步的紋理中,采樣出對應的像素值,接下來就是,逐個獲取總列表中的光源數據,然后計算光照結果。下圖為實際效果:
三、為什么要軟光柵化與軟光柵化步驟詳細
現代GPU最初的目的,就是為了把光柵化從CPU手中接過來,以并行計算替代串行計算,從而實現至少3個數量級的提速[2] 。但是付出了代價,GPU的并行計算導致每個象素之間沒有辦法進行任何直接數據交流,每個象素的計算結果的大小必須是完全相同的。在快速多光源渲染的第一步,每個象素都是一個列表,而且每個象素的列表大小一般都是不同的,如果相同,某個象素列表里很可能會儲存超過200個光源數據,所有的列表就都要超過200,否則就要丟失光源,這會導致總列表尺寸暴增,顯然不可行。因此光源列表,就必須由CPU進行串行處理,也就是軟光柵化。雖然軟光柵化效率非常低,但是光源列表的分辨率并不需要與實際渲染窗口的分辨率相同,通常是四十分之一,例如1280X720分辨率的渲染窗口,光源列表分辨率可以只有32*18,總共576個象素。對于現代CPU來說,這樣低分辨率的軟光柵化當然不會很慢。快速多光源渲染的軟光柵化目的不是繪制圖形,而是生成光源列表,光源除了太陽光之外,都可以抽象為點光源,也就是一個球體,因此并不需要實現完整的標準軟光柵化計算過程。光源列表不需要處理深度、半透明、顏色、模板,因此相關計算一律都可以省略,唯一需要的,就是把覆蓋到當前像素的光源信息,添加到當前像素的列表里。
四、快速多光源渲染的硬件需求、適用范圍和缺陷
快速多光源渲染最低需要顯卡支持Opengl2.0,并且支持動態分支,相當于DirectX9.0c,如果可能,建議在支持Opengl3.0也就是DirectX10的顯卡上實現,Opengl3.0可以用Texture Buffer Objects,在著色器獲取光源數據的時候,可以大幅提高效率。快速多光源渲染最適合小尺寸場景,而且比較分散的場合,比如室內。如果一個場景內,上百個光源出現在攝像機附近,并且都覆蓋了整個攝像機范圍,這時候,相當于每個列表中都存了相同的數據,快速多光源渲染在這時候就無法起到任何作用了,這是最大的缺陷,因此,一定要避免此現象出現,其實此時跟GPU像素填充率不足的情況非常近似,也可以用近似的方法來處理。
參考文獻:
[1]OpenGL體系結構審核委員會/Dave Shreiner/Mason Woo等 編著,OpenGL編程指南(第四版),人民郵電出版社,2005
[2]詹鵬;面向移動設備的3D圖形光柵化處理單元的設計與實現[D];西安科技大學;2012年
作者簡介:張鴻浩,男,1984年生,本科,工程師助理,黑龍江省電子信息產品監督檢察院。