圖片邊緣出現黑點的問題分析和解決(紋理過濾)

圖片邊緣出現黑點的問題分析和解決(紋理過濾)

最近在項目中遇到UI圖片非透明區域邊緣出現黑色雜點的問題,經過分析和紋理過濾有關,並提出解決方案,需要美術製圖時特別注意。本文是此問題的分析與解決方案。

問題

  • 我的項目使用的FairyGUI,然而此問題與UI框架無關。

這裏寫圖片描述

上圖爲出現問題的圖片,一個綠色的環形圖片,周圍爲透明。

通過修改渲染所用shader,並在片源着色中修改out顏色的alpha = 1,可以獲得排除透明通道的顏色圖。

這裏寫圖片描述

對比兩張圖片可以看到,有一些#00000000的色塊在和綠色部分相交的地方產生這些黑塊。

那麼可以想見就是這些相交的區域產生了這些黑色雜點。爲什麼會產生這些雜點呢?下面將會分析

紋理過濾(texture filter)

我們的紋理是要貼到三維圖形表面的,而三維圖形上的pixel中心和紋理上的texel中心並不一至(pixel不一定對應texture上的採樣中心texel),大小也不一定一至。當紋理大於三維圖形表面時,導至一個像素被映射到許多紋理像素上;當維理小於三維圖形表面時,許多個像素都映射到同一紋理。

紋理過濾一般常見的有四種:
1. Nearest Point Sampling(最近點採樣)
最近點採樣取最接近的圖片上的像素點進行採樣。
2. Bilinear(雙線性過濾)
雙線性過濾以pixel對應的紋理座標爲中心,採該紋理座標周圍4個texel的像素,再取平均,以平均值作爲採樣值。
3. Trilinear(三線性過濾)
三線性過濾以雙線性過濾爲基礎。會對pixel大小與圖片像素大小最接近的兩層Mipmap level分別進行雙線性過濾,然後再對兩層得到的結果進行線性插值。
4. Anisotropic Filtering(各向異性過濾)
各向同性的過濾在採樣的時候,是對正方形區域裏行採樣。各向異性過濾把紋理與屏幕空間的角度這個因素考慮時去。簡單地說,它會考濾一個pixel(x:y=1:1)對應到紋理空間中在u和v方向上u和v的比例關係,當u:v不是1:1時,將會按比例在各方向上採樣不同數量的點來計算最終的結果(這時採樣就有可能是長方形區域)。

問題分析

通過了解紋理過濾的定義,我們可以很清楚的意識到,幾種過濾方式中後三種都使用了插值運算。也就是說插值出的像素點都會是一個新的顏色。只要使用過插值運算,就有可能會產生圖片上本來不存在的顏色。

如過存在插值,那麼下面2*2的圖片被渲染爲2倍大小的話就會出現類似這種情況(實際上並不是完全相同,具體結果間上面不通紋理過濾的算法)

a b
白色不透明 紅色透明
白色不透明 紅色透明

==變爲===>>>>>>

a b c d
白色不透明 粉色半透明 粉色半透明 紅色透明
白色不透明 粉色半透明 粉色半透明 紅色透明
白色不透明 粉色半透明 粉色半透明 紅色透明
白色不透明 粉色半透明 粉色半透明 紅色透明

其中粉色半透明就是新產生的顏色。

也就是說黑色透明色 #00000000 和綠色不透明色#00ff00ff之間在插值過程中產生了灰色半透明,就是這些邊緣的雜點。

問題確認

看一下圖片的導入設置中,Filter Mode中的選項,選擇了Bilinear 即在紋理過濾是使用的模式是 雙線性過濾 ,使用了插值。

這裏寫圖片描述

改成Point ,即使用 最近點採樣 。再看效果

這裏寫圖片描述

黑點消失了,但是邊緣變得不整齊了。這也是最近點採樣的缺點。

問題解決

很簡單,美術作圖的時候儘量避免使用橡皮擦。保證一個透明過度關係應該爲:

綠色不透明 -> 綠色半透明 -> 綠色透明 -> 黑色透明

這樣插值就不會插出灰色半透明之類的情況。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章