圖片“變灰”處理是再尋常不過的要求了,特別按鈕,頭像等UI圖片的“變灰”處理非常常見。比如:
網上已經有很多的實現方法,但是Unity5.3.8以后,對於使用sprite packer,並將包含透明通道的圖片進行etc1格式壓縮的圖集來說,稍微有些不一樣。新的uishader中,加入了
[PerRendererData] _AlphaTex("Sprite Alpha Texture", 2D) = "white" {}
這段代碼,用來獲取指定位置上的透明通道。我認為unity是將透明通道單獨提取出來進行保存,把剩下的rgb通道保存到另一張圖片中進行etc壓縮。
這就牽扯到圖片變灰處理中的一些細節問題,如果我們的圖集使用了etc1壓縮方式,那么透明通道就需要單獨獲取,在fragment shader中,我們應該修改原先的操作為:
fixed4 frag(v2f IN) : SV_Target
{
// 這里首先獲取MainTex中的rgb顏色信息
fixed4 colorTex = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
// 之后獲取AlphaTex中的透明通道信息,注意透明通道保存的在r通道中
fixed AlphaTexAlpha = tex2D(_AlphaTex, IN.texcoord).r + _TextureSampleAdd.a;
// 創建color變量,設置透明通道為colorTex.a和AlphaTexAlpha的乘積
fixed4 color = fixed4(colorTex.rgb, colorTex.a * AlphaTexAlpha);
color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
#ifdef UNITY_UI_ALPHACLIP
clip (color.a - 0.001);
#endif
color.rgb = Luminance(color.rgb);
return color;
}
計算colorTex.a和AlphaTexAlpha的乘積是為了即使unity沒有給我們傳遞_AlphaTex時,也能讓圖片正常顯示,因為並不是所有的圖片都按照sprite packer方式打包。