Deferred 框架下的AA
前面說過Deferred 框架下無法使用硬件AA,這句話不嚴謹:
- Deferred Shading在G-Buffer之後,物體幾何信息全被拋棄了,導致後續每個像素都獨立計算,所以不能使用硬件AA;
- 但是:Deferred Lighting,在Shading Pass階段,物體會被再次渲染一遍,此時打開硬件MSAA,肯定是能用的(儘管光照部分取自lighting Pass階段得到的texture,沒能享受到AA,但對最終結果影響很小)。
所以,總結來看,Deferred Lighting能用硬件AA,而Deferred Shading不能使用!
即便如此,由於硬件AA處理的是primitive的邊界,而非真正的“物體邊緣”,所以對時間和空間的衝擊那是相當巨大。
這一問題在deferred框架下尤其明顯,所以各種基於post process的AA方法應聲而出!
目前主要的各類Post process AA:
-
GPU Gems2 “Deferred Shading in S.T.A.L.K.E.R.” 一章介紹了 Edge
AA
- 對每像素做邊緣檢測,得到一權重值,最終根據權重值和閥值做比較,提取出“物體邊緣”
- 對“物體邊緣”,根據其權重值,與周圍像素融合,得到AA效果
- 缺點:“閥值”和分辨率相關
-
GPU Gems3 “Deferred Shading in Tabula Rasa” 一章介紹了由NCSoft改進的Edge
AA
- 改進邊緣提取算法,使其“閥值”和分辨率無關
- AMD 的 Directionally Adaptive Edge AA
- MLAA
- DLAA
- Humus 的GPAA
- NVidia的FXAA
其中,FXAA效果不錯,時空效能也不錯,自面世以來一直比較受寵,可重點關注一下!
處理半透明物體
-
RGame現在在用的,也是最常見的做法:
- 在defferred Rendering之後專門再開一條forward Rendering 管線專門來繪製半透明物體
- 雖然不利於擴展維護,但是簡單、粗暴、有效;
- 值得注意的是,萬一場景中半透明物體很多,且需要接受光照影響,那不能通過Deferred Rendering處理的物體就多了,此時這種方法不可取。
-
KlayGE 4.0開源引擎中提出的方法:
- 首先得到不透明物體的G-Buffer,正常流程經過Lighting Pass 和 Shading Pass繪製不透明物體
- cull mode設置爲front(根據座標系的不同爲CW或CCW),得到半透明物體的背面的G-Buffer(中間需clip掉比不透明物體更遠的pixel),然後經過Lighting Pass + Shading Pass + Alpha Blend得到最終結果
- cull mode設置爲back,與上面過程一樣,繪製半透明物體的正面並Alpha Blend得到最終結果 -- 缺點也很明顯:3倍的內存、帶寬消耗,目前使用價值不大
-
對光照計算結果的正確性做妥協。
- G-Buffer的引入實際上是隻保留了屏幕上同一塊區域的一個片元的幾何信息;
- 對於多個片元重合的情況,如果都是不透明物體,那沒問題;如果有半透物體, 那麼只有在透明度達到一定閥值時,才寫入G-Buffer
- Deferred Lighting的優勢凸顯:畢竟要在shading pass階段再渲染一遍物體,那麼渲染半透明物體時,關閉Z-Test,按照正常流程去Shading, 之後做alpha blend融合就好;不正確的只是光照結果部分。
- 據說,QQ飛車就是這樣做得,透明度閥值取75%,不仔細看發覺不出問題
- 當然,這種方法不適用於Deferred Shading
- 補充:注意大前提“半透明物體需要受光照影響”;否則不如直接進入foward Rendering管道