实现一个圆角正多形蒙版

正多边形蒙版

圆角正六边形

(1)先画个正多边形alpha1

(2)在每个内角处画个相切圆,求uv坐标是否每个圆面向多边形内角的那一方位上angleArea,求uv坐标到每个圆的原点的距离curR,求圆半径r,可得总的 alpha2 += step(r, curR) * angleArea;

(3)蒙版透明度为 alpha1 + alpha2;

 

代码如下:

Shader "Hidden/PolygonMask" 
{
    Properties
    {
        _Color("Color ", Color) = (0, 0, 0, 1)
        _Ratio("Ratio", Range(0, 1)) = 0.25 // 屏幕比例
        _Angle("Angle", Range(0, 360)) = 0 // 旋转角
        _VertexNum("VertexNum", Range(3, 50)) = 3
        _Length("Length", Range(0, 1)) = 0.5
        _Smooth ("Smooth", Range(0, 0.5)) = 0
    }
    SubShader
    {
        Pass
        { 
            Blend SrcAlpha OneMinusSrcAlpha
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            
            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }
            
            float4 _Color;
            float _Ratio;
            float _Length;
            float _Smooth;
            int _VertexNum;
            float _Angle;

            fixed4 frag(v2f input) : SV_Target
            {
                float ave = 360 / floor(_VertexNum);
                float a = _Color.a;
                
                float2 uv = input.uv.xy - float2(0.5, 0.5);
                
                float2 polygoUv = uv;
                polygoUv.x /= _Ratio;

                float dis = distance(polygoUv, float2(0, 0));
                float mindis = 1;

                float circle;
                float innerAngle = radians((_VertexNum - 2) * 180 / floor(_VertexNum));
                float r = 0.5 * _Length - _Smooth * sin(0.5 * innerAngle);

                for (int i = 0; i < _VertexNum; i++)
                {
                    float degress = radians(ave * i + _Angle);

                    // N边形
                    float2 pos = _Length * float2(cos(degress), sin(degress));
                    float dis = distance(polygoUv, pos);
                    mindis = min(mindis, dis);
                    
                     N角圆滑
                    float angle = degress + radians(ave * 0.5);
                    float2 circleCenter = _Smooth * float2(cos(angle), sin(angle));
                    circleCenter.x *= _Ratio;
                    float2 circleUv = uv.xy - circleCenter;
                    circleUv.x /= _Ratio;
                    float showAngle = degrees(atan2(circleUv.y, circleUv.x));
                    showAngle += showAngle < 0 ? 360 : 0;
                    float startAngle = fmod(degrees(angle) - ave * 0.5, 360);
                    float endAngle = fmod(degrees(angle) + ave * 0.5, 360);
                    float angleArea = step(startAngle, endAngle) * step(showAngle, endAngle) * step(startAngle, showAngle)
                        + step(endAngle, startAngle) * (step(showAngle, endAngle) + step(startAngle, showAngle));
                    float curR = distance(circleUv, float2(0, 0));
                    circle += step(r, curR) * angleArea;
                }

                _Color.a = step(mindis, dis) + circle;

                return _Color;
            }
            ENDCG
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值