三、SSAA(super-sampling anti-aliasing)
SSAA最初的思路是先上採樣渲染映像,然後再下採樣輸出映像,比如我們要渲染輸出一個256*256的映像,可以設定color buffer為512*512(4倍的SSAA),這個時候我們的ps需要執行512*512個thread,同時深度模版測試也要進行512*512次,最後把4倍的color buffer resolve成256*256,就是4個像素取平局值,得到最終的映像。這種方法運算量和儲存空間都會增大4倍,cost很高,但效果也最好。
是一個3*3映像4xSSAA的例子,綠色的RGB為(34,177,76),深紅色的RGB為(136,0,21),邊緣處的顏色為((34,177,76)*3 + (136,0,21))/4 = (59, 133, 62)
對於現在的電腦硬體來說,我們可以針對每個像素,進行子像素級的採樣,其中採樣點的位置選擇有多種方式,常用的有grid,隨機等等,如所示:
其中,旋轉方式是最常用的採樣方式。
在D3D11中,我們能夠在sample層級來執行ps,如果採用grid方式的採樣點分布,就間接實現了SSAA,就是每個採樣執行一次ps(採樣的中心就是ps的位置),對於每個採樣來說,我們可以輸出顏色。下面是一段在sample上執行ps的代碼,其中一個像素中不同的sample用SV_SampleIndex區分:
float 4PSMainPerSample(infloat4screenPos:SV_Position,
in uint subSamplelndex:SV_SampleIndex):SV_Target0
{
float 3normal;
fioat 3position;
floatspecularPower;
GetGBufferAttributes(screenPos.xy,ViewRay,subSamplelndex, normal,position,specularPower);
Return CalcLighting(normal,position,specularPower);
}
四、MSAA(multi-sampling anti-aliasing)
MSAA基本上是現在gpu硬體上反鋸齒的標配,大多數gpu都實現了該功能。
MSAA的基本思想就是每個像素有多個採樣,但ps只對該像素執行一次(ps在像素中心位置被調用),即ps輸出的color被所有sample使用,然後每個sample進行深度模版測試,通過該測試後,會接受ps輸出的顏色,如果沒有通過深度模版測試,則會拒絕ps輸出的顏色(此時會使用color buffer中的原來的顏色,一般就是我們clear背景的顏色),產生該sample的輸出映像,最後resolve所有採樣的映像,產生最終的輸出映像。就是就是說對於32*32的輸出映像,如果是4xMSAA,則要輸出4個32*32的映像。[注:ps 會對每個光柵化後的primitive的像素來進行]
就是4xMSAA的例子,我們看如何得到最終的結果:
1. 執行到黃色三角形,該三角形覆蓋到了該像素中心,執行ps,輸出黃色,三個sample深度測試fail,保持原來的像素顏色(背景色為白色),第二個採樣深度測試pass,對於4個採樣,採樣像素顏色為
2. 藍色三角形進行光柵化,覆蓋到了該像素中心位置,像素執行ps,輸出藍色,對於4個採樣,2個採樣深度測試pass,用藍色替代原來的顏色,最終的採樣顏色為:
3. 最後resolve這個sample的顏色,得到最終的顏色
在shader3 model之前,ps執行都在像素的中心,後來加入了centroid插值,PS的輸入屬性就可以是三角形所覆蓋的所有採樣點的中心。如所示,對於昨天的no centroid,ps輸出為白色,而對右邊的centroid,則ps的輸出為黃色。