一、如何使用 Soft Mask 插件
下载地址:Soft Mask | GUI Tools | Unity Asset Store
和常用的 Mask 和 RectMask2D 组件一样,SoftMask 也可以用来对 Image、RawImage 等图形单元进行遮罩,仅显示部分区域,不过相对于传统的遮罩,SoftMask 的区域便于更加的平滑,也可以理解为是渐进式遮罩,往往可以通过它来实现一些边缘羽化等效果:
1.1 组件挂载
在需要使用 Soft Mask 遮罩的父节点上,添加 Soft Mask 组件,其中 Source 选择 Texture 或 Sprite,然后选择对应的蒙版图片即可,成功设置后该父节点下的子节点上挂载的对应图形单元会应用遮罩(当然对应图形单元的 shader 需要注入一些额外的逻辑,具体可以参考下一节)
1.2 自定义 Shader 实现支持 Soft Mask
若想要 Soft Mask 的表现正确,需要修改现有的 Shader 以支持,需要注意的是:不同 shader 改动可能有所差异,具体可以参阅 Soft Mask - Custom Shader Tutorial v. 1.2 - Google 文档
1. 在 Properties 中添加如下变量
Properties
{
…
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
_SoftMask ("Mask", 2D) = "white" {}
}
2. 添加 #pragma 与 #include,其中 #12 和 #18 两行为新添加的内容
SubShader
{
…
Pass
{
…
CGPROGRAM
#pragma target 3.0
#pragma vertex VertShader
#pragma fragment PixShader
…
#pragma multi_compile __ SOFTMASK_SIMPLE SOFTMASK_SLICED SOFTMASK_TILED
#include "UnityCG.cginc"
#include "UnityUI.cginc"
#include "TMPro_Properties.cginc"
#include "TMPro.cginc"
#include "Assets/ThirdParty/SoftMask/Shaders/SoftMask.cginc"
}
}
3. 添加相关参数并计算
v2f 中加入 SOFTMASK_COORDS(texCoord) ,TEXCOORD 序号顺延即可
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
float4 worldPosition : TEXCOORD1;
SOFTMASK_COORDS(2)
};
顶点着色器中添加 SOFTMASK_CALCULATE_COORDS(output, pos) 语句
v2f vert(appdata_t IN)
{
v2f OUT;
OUT.worldPosition = IN.vertex;
OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);
OUT.texcoord = IN.texcoord;
#ifdef UNITY_HALF_TEXEL_OFFSET
OUT.vertex.xy += (_ScreenParams.zw - 1.0) * float2(-1,1) * OUT.vertex.w;
#endif
OUT.color = IN.color;
SOFTMASK_CALCULATE_COORDS(OUT, IN.vertex);
return OUT;
}
最后在片段着色器中应用遮罩 SOFTMASK_GET_MASK(input)
fixed4 frag(v2f IN) : SV_Target
{
fixed4 color = tex2D(_MainTex, IN.texcoord);
color.a *= SOFTMASK_GET_MASK(IN);
...
color.a = lerp(1, color.a, IN.color.a);
return color;
}
需要注意的是:
- 如果你的 shader 有做 alpha 的预乘,那么 rgb 通道也应乘于如上系数
- 考虑到更特殊的情况:对于每种不同的混合模式,应用遮罩的算法应当都不相同,具体可以反向推下公式,一个混合的例子是 [_SrcBlend = One, _DstBlend = SrcAlpha],对应的代码就应如下:
color.rgb *= SOFTMASK_GET_MASK(IN);
color.a = 1 - (1 - color.a) * SOFTMASK_GET_MASK(IN);
成功!此时该 Shader 即支持 Soft Mask 了