这个是参考这个做的:https://blog.csdn.net/tracyzly/article/details/80279692
Shader "UI/ImageWithHole"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_TintColor ("Tint", Color) = (,,,)
\_StencilComp ("Stencil Comparison", Float) =
\_Stencil ("Stencil ID", Float) =
\_StencilOp ("Stencil Operation", Float) =
\_StencilWriteMask ("Stencil Write Mask", Float) =
\_StencilReadMask ("Stencil Read Mask", Float) =
\[KeywordEnum(ROUND, RECTANGLE, NULL)\] \_MaskMode("Mask mode", Float) =
\_Center("Center", vector) = (, , , )
\_Radius("Radius", Range(,)) = // 圆半径
\_RectangleSize("Rectangle Size", vector) = (, , , ) // 矩形边长
\_TransitionRange("Transition Range", Range(, )) =
}
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
Blend SrcAlpha OneMinusSrcAlpha
ColorMask RGBA
Pass
{
Name "Default"
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#include "UnityCG.cginc"
#include "UnityUI.cginc"
#pragma multi\_compile \_\_ UNITY\_UI\_CLIP\_RECT
#pragma multi\_compile \_\_ UNITY\_UI\_ALPHACLIP
#pragma multi\_compile \_MASKMODE\_ROUND \_MASKMODE\_RECTANGLE \_MASKMODE\_NULL
struct appdata\_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
UNITY\_VERTEX\_INPUT\_INSTANCE\_ID
};
struct v2f
{
float4 vertex : SV\_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
float4 worldPosition : TEXCOORD1;
UNITY\_VERTEX\_OUTPUT\_STEREO
};
fixed4 \_TintColor;
fixed4 \_TextureSampleAdd;
float4 \_ClipRect;
float2 \_Center;
half \_Radius;
float2 \_RectangleSize;
half \_TransitionRange;
v2f vert(appdata\_t v)
{
v2f OUT;
UNITY\_SETUP\_INSTANCE\_ID(v);
UNITY\_INITIALIZE\_VERTEX\_OUTPUT\_STEREO(OUT);
OUT.worldPosition = v.vertex;
OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);
OUT.texcoord = v.texcoord;
OUT.color = v.color \* \_TintColor;
return OUT;
}
sampler2D \_MainTex;
fixed4 frag(v2f i) : SV\_Target
{
half4 color = (tex2D(\_MainTex, i.texcoord) + \_TextureSampleAdd) \* i.color;
#ifdef UNITY\_UI\_CLIP\_RECT
color.a \*= UnityGet2DClipping(IN.worldPosition.xy, \_ClipRect);
#endif
#ifdef UNITY\_UI\_ALPHACLIP
clip (color.a - 0.001);
#endif
#ifdef \_MASKMODE\_ROUND
// 计算片元世界坐标和目标中心位置的距离
half dis = distance(i.worldPosition.xy, \_Center.xy);
// 过滤掉距离小于(半径-过渡范围)的片元
clip(dis - (\_Radius - \_TransitionRange));
// 是否在圆里面
int inside = step(dis, \_Radius);
// 计算过渡范围内的alpha值
color.a \*= ( - inside) + inside \* (dis - (\_Radius - \_TransitionRange)) / \_TransitionRange;
#elif \_MASKMODE\_RECTANGLE
// 计算片元世界坐标和目标中心位置的距离
half disX = distance(i.worldPosition.x, \_Center.x);
half disY = distance(i.worldPosition.y, \_Center.y);
// x决定像素点应该去掉返回1,不去掉返回0
int clipX = step(disX, \_RectangleSize.x-\_TransitionRange);
int clipY = step(disY, \_RectangleSize.y-\_TransitionRange);
clip(disX - (\_RectangleSize.x -\_TransitionRange) \* clipY);
clip(disY - (\_RectangleSize.y -\_TransitionRange) \* clipX);
// x在范围内返回1,不在范围内返回0
int insideX = step(disX, \_RectangleSize.x);
int insideY = step(disY, \_RectangleSize.y);
half alphaX= ( - insideX) + insideX \* (disX - (\_RectangleSize.x - \_TransitionRange)) / \_TransitionRange;
half alphaY= ( - insideY) + insideY \* (disY - (\_RectangleSize.y - \_TransitionRange)) / \_TransitionRange;
color.a \*= max(alphaX, alphaY);
#endif
return color;
}
ENDCG
}
}
}
手机扫一扫
移动阅读更方便
你可能感兴趣的文章