PCF無非就是把周圍的像素加吧加吧, 然後取個平均值. 結果的平滑程度, 跟Kernel的大小有直接關係.
下面來對這個描過邊的鋸齒茶壺PCF一把:
2x2:
3x3:
4x4:
當然, Kernel越大, 效果越好. 但大到一定程度效果就不明顯了, 而且還要考慮效能問題, 畢竟多次的紋理採樣很慢. 其實呢, 通過抖動也可以使用少量的採樣達到近似比較大Kernel的效果. 這裡用4次採樣來類比4x4PCF的效果, 採樣模板如下:
正好PS3.0中的增加了一個寄存器VPOS, 用於直接取當前像素的螢幕座標, 根據座標的奇偶性來決定取樣的位置:
sampler2D Texture0;<br />float2 fInverseViewportDimensions;</p><p>struct PS_INPUT<br />{<br /> float2 texCoord : TEXCOORD0;<br /> float2 screenPos : VPOS;<br />};</p><p>float4 ps_main(PS_INPUT input) : COLOR0<br />{<br /> float2 offset = fmod(input.screenPos, 2.0);</p><p> float4 color = 0;<br /> color += tex2D(Texture0, input.texCoord + (float2(-1.5,-1.5) + offset) * fInverseViewportDimensions);<br /> color += tex2D(Texture0, input.texCoord + (float2(-0.5, 0.5) + offset) * fInverseViewportDimensions);<br /> color += tex2D(Texture0, input.texCoord + (float2(-1.5, 0.5) + offset) * fInverseViewportDimensions);<br /> color += tex2D(Texture0, input.texCoord + (float2(-0.5, 1.5) + offset) * fInverseViewportDimensions);<br /> color *= 0.25;</p><p> return color;<br />}<br />
最終效果, 用在陰影模糊中會很一種效率很高的解決方案: