原創(chuàng)文章舒帮,轉載請注明出處使用透明度實現(xiàn)Mask遮罩的Unity Shader
你好儿惫,用你的shader后在pc編輯器上是沒有問題的嗦随,在5.4環(huán)境下打包到手機上也沒問題列荔,但是升級到5.5后打包到手機(ios,android的還沒試)上就顯示為粉紅色枚尼,不知道博主有沒有解決方案
感謝提醒贴浙,有時間我會修正一下
關于遮罩的需求
將矩形的圖片做成圓角矩形、圓形
常用實現(xiàn)方式
- 使用UGUI自帶的Mask組件實現(xiàn)
- 使用網(wǎng)上一搜一大把的簡單切割shader實現(xiàn)
存在的問題
這些實現(xiàn)方案容易出現(xiàn)鋸齒問題署恍,見下圖
鋸齒的由來
由于屏幕都是像素化的崎溃,所以看似圓滑的曲線,在屏幕上其實都是有鋸齒的盯质,但由于人眼的識別能力有限袁串,所以當鋸齒小到一定程度的時候就會認為曲線是圓滑的。
然而呼巷,由于分辨率問題囱修,我們很難做到鋸齒足夠小,所以需要在產(chǎn)生鋸齒的邊緣添加顏色過渡王悍,避免明顯的分界線破镰,從而使人眼忽略鋸齒問題。
現(xiàn)有方案的鋸齒原因
由于現(xiàn)有方案是簡單的判斷遮罩的邊界:
- UGUI的Mask組件是通過透明度判斷配名,
如果遮罩某像素點透明度達到一個值啤咽,則該像素點對應的顏色透明度不變,否則透明度置為0,使用遮罩的透明度作為掩碼寫入緩沖區(qū)渠脉,之后只渲染緩沖區(qū)為1的區(qū)域宇整。
以下為官方文檔說明
Implementation
Masking is implemented using the stencil buffer of the GPU.
*The first Mask element writes a 1 to the stencil buffer *
All elements below the mask check when rendering, and only render to areas where there is a 1 in the stencil buffer
Nested Masks will write incremental bit masks into the buffer, this means that renderable children need to have the logical & of the stencil values to be rendered.
- 簡單切割shader的實現(xiàn)是通過邊緣檢測來判斷該點是否顯示,不顯示則透明度置為0
發(fā)現(xiàn)了嗎芋膘,這些方案都是非黑即白的的方案鳞青,根本實現(xiàn)不了顏色過渡霸饲,所以存在鋸齒的現(xiàn)象
解決方案
我給出的方案是使用透明度疊加來做
1.制作一張PS做的帶透明度過渡的遮罩
2.編寫shader,獲取這張遮罩的透明度臂拓,將該透明度和目標圖片的透明度進行混合
效果
shader代碼
Shader "ImageEffect/MaskIcon"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Mask ("Base (RGB)", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend SrcAlpha OneMinusSrcAlpha
ColorMask [_ColorMask]
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "UnityUI.cginc"
#pragma multi_compile __ UNITY_UI_ALPHACLIP
struct a2v
{
fixed2 uv : TEXCOORD0;
half4 vertex : POSITION;
float4 color : COLOR;
};
fixed4 _Color;
struct v2f
{
fixed2 uv : TEXCOORD0;
half4 vertex : SV_POSITION;
float4 color : COLOR;
};
sampler2D _MainTex;
sampler2D _Mask;
v2f vert (a2v i)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, i.vertex);
o.uv = i.uv;
o.color = i.color * _Color;
return o;
}
fixed4 frag (v2f i) : COLOR
{
half4 color = tex2D(_MainTex, i.uv) * i.color;
half4 mask = tex2D(_Mask, i.uv);
color.a *= mask.a;
return color;
}
ENDCG
}
}
}