Shader实现新手指引挖空圆形和矩形
阅读原文时间:2023年07月10日阅读:1

这个是参考这个做的: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  
    }  
}  

}

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章