鏈接:https://www.zhihu.com/question/20236638/answer/44821615
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
首先所有MSAA, SSAA, FXAA, TXAA等都是抗鋸齒(Anti-Aliasing)技術。
鋸齒的來源是因為場景的定義在三維空間中是連續的,而最終顯示的像素則是一個離散的二維數組。所以判斷一個點到底沒有被某個像素覆蓋的時候單純是一個“有”或者“沒有"問題,丟失了連續性的信息,導致鋸齒。
最直接的抗鋸齒方法就是SSAA(Super Sampling AA)。拿4xSSAA舉例子,假設最終屏幕輸出的分辨率是800x600, 4xSSAA就會先渲染到一個分辨率1600x1200的buffer上,然后再直接把這個放大4倍的buffer下采樣致800x600。這種做法在數學上是最完美的抗鋸齒。但是劣勢也很明顯,光柵化和着色的計算負荷都比原來多了4倍,render target的大小也漲了4倍。
MSAA(Multi-Sampling AA)則很聰明的只是在光柵化階段,判斷一個三角形是否被像素覆蓋的時候會計算多個覆蓋樣本(Coverage sample),但是在pixel shader着色階段計算像素顏色的時候每個像素還是只計算一次。例如下圖是4xMSAA,三角形只覆蓋了4個coverage sample中的2個。所以這個三角形需要生成一個fragment在pixel shader里着色,只不過生成的fragment還是在像素中央(位置,法線等信息插值到像素中央)然后只運行一次pixel shader,最后得到的結果在resolve階段會乘以0.5,因為這個三角形只cover了一半的sample。現代所有GPU都在硬件上實現了這個算法,而且在shading的運算量遠大於光柵化的今天,這個方法遠比SSAA快很多。順便提一下之前NV的CSAA,它就是更進一步的把coverage sample和depth,stencil test分開了。

因為MSAA這個問題現代引擎里都用的是Post Processing AA這一類技術。這一類東西包括FXAA,TXAA等,不依賴於任何硬件,完全用圖像處理的方法來搞。有可能會依賴於一些其他的信息例如motion vector buffer或者前一貞的變換矩陣來找到上一貞像素對應的位置,然后再做一些hack去blur或者blend上一貞的顏色等。通常非常hacky,FXAA的發明人原來是我們組的,他自己都不知道這個為什么會work- -”,但是精心調校之后后效果還是很好的,例如下面是UE4的Post Processing AA開關對比圖:


最后再扯一下NV最新的那個MFAA(Multi-Frame AA),因為Maxwell架構支持的programmable coverage sample location,所以可以做到貞間用不同的coverage sample位置,當FPS足夠高的時候,2xMFAA就可以達到4xMSAA的效果。
對玩家來說,看着舒服就行。當然像使命召喚這種明明是forward rendering還要用SSAA來抗鋸齒的,在顯卡爛的機子上開還是要慎重的。