Deferred 延遲渲染

轉自:博客園 作者 水煮魚丸

Deferred Shading(延遲渲染)

1、簡介
     在計算機圖形學的詞典裏,Shading表示“對受光物體的渲染”,這個渲染過程包括下面幾步[1]:
     1) 計算幾何多邊形(也就是Mesh)。
     2) 決定表面材質特性,例如法線、雙向反射分佈函數(bidirectional reflectance distribution function, BRDF)等等。
     3) 計算入射光照。
     4) 計算光照對表面的影響,並最終顯示。
     一般渲染引擎,渲染場景中的物體的時候,是將這四步一次執行完的。延遲渲染則將前兩步和後兩步分開到渲染管道相互獨立的兩個部分來執行。
2、背景知識
     對比前向渲染(聚光燈的最簡單的前向渲染見DirectX 9.0c的sample"Shadow Map"),前向渲染有多種問題[1]:
     1) 計算每個幾何體受那些光影響耗費了CPU的時間,更壞的是,這是個O(n*m)的操作。
     2) Shader經常需要超過一次以上的Pass來渲染光照,渲染n個燈光,對於複雜的Shader,可能需要O(n)次運算。
     3) 增加新的光照模型和新的光源類型,可能需要改變所有Effect的源文件。
     4) Shader很快就將達到或者超出SM2的指令限制。
     在MMO裏,我們對遊戲環境很少會有過於苛求的要求。我們無法控制同屏可見的玩家數量、無法控制同屏會有多少特效和光源。由於傳統前向渲染缺乏對環境的控制,且對於光源的複雜度難於估量,因此我們選擇了延遲渲染。這可以讓我們的畫面更接近於當今頂尖的遊戲引擎,並且讓光照所耗費的資源獨立於場景的幾何複雜度。
     延遲渲染提供了下面的好處:
     1) 光照所耗費的資源獨立於場景複雜度,這樣就不用再費盡心機去想着處理那些光源影響幾何體了。
     2) 不必要再爲幾何體的受光提供附加的Pass了,這樣就節省了Draw Call和狀態切換的數量。
     3) 在增加新的光源類型和光照模型時,材質的Shader不需要做出任何改變。
     4) 材質Shader不產生光照,這樣就節省了計算額外的幾何體的指令數。
     延遲渲染需要顯卡提供MRT的支持,且利用了不斷增加的存儲器的帶寬——這也就意味着我們可能得對玩家所使用的硬件提出更高的要求。因此我們既實現了前向渲染,也實現了延遲渲染。我們優化了前向渲染管道,並在此基礎上完成了延遲渲染管道。
3、基本原理
     目前我們看到最終畫面都是2D的,只能看到有限的像素數,理論上我們只要處理(指光照,陰影處理)最終我們可以看到的點的效果就夠了,多餘的處理是浪費的。而正常的前向渲染(Forward Shading)流程是把空間的點進行各種剪裁後,進行處理,所處理量遠遠大於我們最終看到的。所以延遲渲染出現了。它先將攝像機空間的點光柵化轉化成屏幕座標後再進行處理。這樣就能減少處理的次數,從而提高效率[5]。
     既然把處理流程放在了後面,那麼處理所需要的參數也必須帶到後面的流程。這裏使用MRT(multi target render)就很重要,RT佔用的顯存越大,對顯卡的的帶寬要求也就越高,DX10支持8個MRT(DX11的MRT數量我沒查到,在DX11的新特徵中,也沒有提到增加MRT,所以可能也是8個)。後面的處理至少需要空間位置信息,可以通過Depth(至少16位)獲得,其他可以將法線信息(normal),高光信息(specular),AO係數,diffuse,自發光(emissive),材質編號等信息放入MRT中。
     延遲渲染管線可分爲四個階段(和第一節說的4個階段有一些不同,只是某些功能進行不一樣的劃分而已,大致還是一樣的):Geometry,Lighting, Composition, Post-processing[4],Post-processing階段與傳統的forward shading沒有太大差別,這裏不提,只說明一下前三個階段。
     1) Geometry階段:將本幀所有的幾何信息光柵化到G-buffer。包括位置,法線,貼圖等。
     2) Lighting階段:以G-buffer作爲輸入(位置,法線)進行逐像素的光照計算,將diffuse lighting和specular lighting 結果分別保存在兩張RT上作爲lighting buffer。
     3) Composition階段:將G-buffer中的貼圖buffer和lighting buffer融合,得到渲染結果。
4、延遲渲染核心部分
  4.1、G-buffer
     Geometry階段將幾何信息渲染到multi render target上(MRT),當前最多支持4個MRT。並且驅動要求4個MRT必須相同的bit寬度。RT對顯存佔用過大會增加帶寬,降低cache命中。而簡單格式的RT又會影響畫質。因此決定使用32bit的RT(如A8R8G8B8,R16G16F)或64bit寬度的RT(如A16R16G16B16F)。需要在畫質和性能間做出折衷。(開發時儘可能可以方便的配置)[3]。

     MRT中必須的信息:position(depth), normal, diffuse(texture)
     可能需要的信息:specular, power, emissive, ao, material id
     這些信息需要在這4個RT上用合理格式,合理的組織。這裏還可以就存儲空間和shader的複雜性做折衷。如只保存depth,然後在光照時計算position,以及用球面座標保存法線。以目前的資料得出的結論是應該儘可能地pack數據,減少內存佔用,多出來的若干條shader指令不會明顯影響性能。

  4.2、光照計算及相關優化
     使用延遲渲染技術最大的好處就是可以渲染光照極爲複雜的場景。這裏場景中的光照可以分爲兩類。影響整個場景的scenelight。如directionallight。渲染一個screenquad,逐像素光照計算,沒什麼好說的;另一類是隻影響一部分區域的locallight,如點光源、聚光燈、和特效等等。這些locallight隻影響到屏幕上的某些像素,當然不需要逐像素的進行光照計算。最簡單的方法是繪製這些光源的包圍體(點光源的包圍體是球,聚光燈的包圍體是圓錐),包圍體的大小要大於等於光源的衰減範圍。這些包圍體經過變換投影到屏幕上的對應區域,隨後在pixelshader中計算光照[3]。

     優化:
     1.光源包圍體的視錐剔除,遮擋剔除。
     2.光源包圍體投影后很小時剔除;若干個靠的比較近的小光源合併成一個較大的光源
     3.光源包圍體的backfaceculling
     4.屏幕空間中沒有被光源照到的,或者被更近的物體遮擋住的像素不需要光照計算,因此可以逐像素的深度剔除。有兩種方法:a.使用正確的stencillightvolume。類似shadowvolume的方案,將渲染lightvolume的正反兩面,得到正確的stencilmask,然後光照計算時使用stencilbuffer。這種方法可以得到正確的結果,但是需要渲染每盞燈時頻繁改變renderstate,可能會帶來一定性能上的損失。b.使用ztest,可以得到“一定程度上正確”的結果。

  4.3、陰影計算
     光照計算的同時計算陰影。使用傳統的shadowmap,預先生成一張陰影圖(相關)。考慮在編輯場景的時候指定那些重要的光源纔會產生陰影。在計算shadowmap時要針對光源的bindingvolume進行剔除[3]。

     方向光和聚光燈可以使用基本的Shadow Map投影(正交投影,透視投影),點光源會複雜一些,需要使用Cube Shadow Map,由於較老的硬件不支持在不同紋理之間插值,使得不同紋理之間會有接縫(見[6] P171),在DX10中才支持Cube Map紋理之間的插值。

5、優缺點分析
     延遲渲染主要的好處包括[1,6]:
     1) 光照的開銷與場景複雜度無關。
     2) Shader可以訪問深度和其他像素信息。
     3) 每個象素對每個光源僅運行一次。也就是說,那些被遮擋的像素是不會被光照計算到的。
     4) 材質和光照的Shader完全分開。
     延遲渲染還需要克服的主要障礙包括:
     1) 較高的顯存帶寬佔用
   2) G-buffer消耗較多的填充率,這個問題在遊戲機上比較嚴重
     3) 無硬件反鋸齒的支持
     4) 對Alpha Blend支持較差
     解決方案:
     1) 我們發現當前駐留的顯卡已經可以在稍低的分辨率下解決貸款問題了,而在當今最高端的機器上,可以在開啓全部特性的前提下,適應更高的分辨率。在DX10 即便顯卡上,ATI和NVIDIA都增強了MRT的性能。DX10和SM4都提供了GPU支持的整數處理,以及從深度緩衝中讀取數據。所有這些都可以減少顯存帶寬。當提供了新的硬件和特性時,性能自然就會提升。
     2) 在合適的Filter作用下,精確的邊緣檢測可以減少幾何體邊緣的鋸齒。雖然這些方法並不像硬件全場景反鋸齒那樣精確,但是仍然可以以假亂真。
     3) 對不透明物體採用延遲渲染,透明物體採用正向渲染,可以解決Alpha Blend的問題(Unity3D採用這種解決方案)。
 
PS:對某個具體項目的說明,包括其中的一些優化見資料[1],GPU GEMS2和3中都有這個引擎延遲渲染的文章,值得一看。
 
參考文獻:
[6]Akenine-Möller T, Haines E, Hoffman N. Real-time rendering 3 [M]. 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章