https://www.jianshu.com/p/0297850ec360
今天美術說要將ui圖片置灰,發現怎麼搞都不太符合要求。
開始的思路是,全部置黑,然後更改透明度。但是美術要求是,白色的地方不要置灰,如下圖:
我們要的是第一種效果,這裏就參考上面給的網址即可。直接算明度即可。
代碼如下:
fixed4 frag(v2f IN) : SV_Target
{
half4 color = tex2D(_MainTex, IN.texcoord) * IN.color;
float grey = dot(color.rgb, fixed3(0.22, 0.707, 0.071));
return half4(grey,grey,grey,color.a);
}
這個代碼很簡單,但是如果到這裏,不免就太簡單。
我想說的是,在unity的源碼中,ui源碼,這裏的image的顏色:
其實是頂點的顏色。
struct UIVertexInput
{
float4 vertex : POSITION;
float4 color : COLOR; //頂點色
float2 uv0 : TEXCOORD0;
};
這樣我們就可以這樣計算了:
inline void TransformColor(inout float4 color, float4 vColor)
{
float mask = sign(vColor.r + vColor.g + vColor.b);
float l = Luminance(color.rgb);
color = float4 (float3(l, l, l)*(1 - mask ) + color.rgb * vColor.rgb * mask , color.a);
}
color是採樣的貼圖的顏色
vColor就是上面的屬性面板上的頂點色
mask計算頂點色rgb分量的和,求符號。
sign(a),如果a>0,返回1;a=0,返回0;a<0,返回-1
Luminance是上面的函數:dot(color.rgb, fixed3(0.22, 0.707, 0.071));
最後的一樣,是根據mask,來取是否用灰度,還是使用主紋理*頂點色的乘積。
可以想象,當頂點色都是黑色,那麼也就是vColor.rbg 都等於0,那麼mask的值爲0,那麼1-mask=1
也就是取灰度了。
ok,到此結束。
其實,我們的UI,都是自定義的shader,而且是blend的,blend模式是:Blend One OneMinusSrcAlpha
那麼還有一個注意點是,查看ugui的源碼,主要的屬性的變換,導致頂點髒,然後刷新UI。
最後一個是,如果頂點的顏色,和自己寫的shader,中定義的:
_Color (“Tint”, Color) = (1,1,1,1)
這個是不同的,所以如果讓這個顏色也生效的話,那麼則要使用material.SetColor方法進行設置屬性,才能生效。
屬性名面板上的顏色,是UI的頂點色,切記,切記。