三、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的輸出為黃色。