在圖形學渲染中,由于采樣頻率不足會導致信號失真的問題。其中有兩類問題比較常見:
- 由于紋理尺寸過小而導致的失真問題
- 由于紋理尺寸過大而導致的失真問題
上面的過大和過小都是和我們的視口相比較而言的。也就是最終我們繪制到屏幕上或者緩沖區(qū)對應的大小。
這里介紹的是應用解決上述第一種:由于紋理尺寸過?。ɡL制的分辨率而言)而導致的鋸齒問題。第二種問題可以參照圖形學抗鋸齒:多重采樣(二)
紋理尺寸過小產生鋸齒的原因
當紋理尺寸過小,即相較而言繪制的分辨率較大。紋理上某個像素點對應到繪制目標上將覆蓋多個像素點。因此,在繪制過程中,我們將繪制目標上這些區(qū)域的像素點映射到紋理上對應的位置進行采樣得到的像素值將是一樣的。這也是產生鋸齒的原因。也就是說這時候,咱們提高傳統(tǒng)意義上的采樣頻率(目標像素值)是無法解決這個失真問題。這個失真是由于采樣源信號已經是失真信號導致的。此時,為了使繪制目標平滑過渡,我們可以使用插值的方法
插值法
下面進行一個實驗,來看一下插值法在解決因為紋理本身過小導致的鋸齒問題的效果。

原圖
如上所示,我們先把原圖()進行尺寸壓縮(壓縮成
),使其信號失真。得到的圖作為我們的實驗輸入圖。并繪制回512*512的尺寸并顯示,如下圖:

壓縮后采樣
上面是我壓縮到的壓縮圖。接著,我們應用雙線性插值對結果圖進行平滑,并重新繪制回
的尺寸。代碼如下:
uniform sampler2D inputTexture0;
uniform vec2 material_size;
varying vec2 v_texCoord;
void main()
{
vec2 st = v_texCoord * material_size;
vec2 f_co = fract(st);
vec2 i_co = (st - f_co);
vec2 i_co00 = i_co / material_size;
vec2 i_co10 = (i_co + vec2(1.0, 0.0)) / material_size;
vec2 i_co01 = (i_co + vec2(0.0, 1.0)) / material_size;
vec2 i_co11 = (i_co + vec2(1.0, 1.0)) / material_size;
vec3 x_color1 = mix(texture2D(inputTexture0, i_co00).rgb, texture2D(inputTexture0, i_co01).rgb, f_co.y);
vec3 x_color2 = mix(texture2D(inputTexture0, i_co10).rgb, texture2D(inputTexture0, i_co11).rgb, f_co.y);
vec3 res_color = mix(x_color1, x_color2, f_co.x);
gl_FragColor = vec4(mix(
mix(texture2D(inputTexture0, i_co00).rgb, texture2D(inputTexture0, i_co01).rgb, f_co.y),
mix(texture2D(inputTexture0, i_co10).rgb, texture2D(inputTexture0, i_co11).rgb, f_co.y),
f_co.x), 1.0);
}
其中,material_size為vec2(25, 25),表示被采樣紋理的分辨率。
平滑過后的圖如下:

雙線性插值平滑
相較于上面的圖,這張圖更加平滑,鋸齒問題沒那么突出了。
總結:
插值法可以優(yōu)化由于紋理尺寸過小而產生的鋸齒問題