Sprite抠图效果:
前言
在PhotoShop中我们经常会用到抠图操作,现在就用Shader实现一个简单的抠图效果。
实现原理:
使用当前像素颜色与需要抠掉的颜色相减作比较,然后与一个指定的阈值比较以决定是否将其显示出来;
Unity Shader实现代码如下:
Shader "Custom/SpriteShader"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Alpha Color Key", Color) = (0,0,0,1)
_Range("Range", Range(0, 1.01)) = 0.1
[MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
// 关键修复:添加Stencil块以支持Mask组件
Stencil
{
Ref 1
Comp Equal
Pass Keep
Fail Keep
}
Pass
{
Cull Off
Lighting Off
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile _ PIXELSNAP_ON
sampler2D _MainTex;
float4 _Color;
half _Range;
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
#ifdef PIXELSNAP_ON
o.vertex = UnityPixelSnap(o.vertex);
#endif
return o;
}
half4 frag(v2f IN) : SV_Target
{
half4 c = tex2D(_MainTex, IN.uv);
// 计算颜色差值
half3 diff = abs(c.rgb - _Color.rgb);
half maxDiff = max(diff.r, max(diff.g, diff.b));
// 使用clip函数直接丢弃像素,兼容AlphaTest
clip(maxDiff - _Range);
return c;
}
ENDCG
}
}
}
_Color是用于比较的基色
_range是决定抠图范围的域
可以看到使用当前像素颜色与基色相减,然后与域相比较以决定是否将其显示出来。