正多边形蒙版
(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
}
}
}