107 lines
3.1 KiB
Plaintext
107 lines
3.1 KiB
Plaintext
Shader "UI/RoundedCorner"
|
|
{
|
|
Properties
|
|
{
|
|
_Color("Color", Color) = (1,1,1,1)
|
|
_Radius("Corner Radius", Range(0, 5)) = 0.1
|
|
}
|
|
|
|
SubShader
|
|
{
|
|
Tags
|
|
{
|
|
"Queue" = "Transparent"
|
|
"RenderType" = "Transparent"
|
|
"PreviewType" = "Plane"
|
|
}
|
|
|
|
Blend SrcAlpha OneMinusSrcAlpha
|
|
ZWrite Off
|
|
|
|
Pass
|
|
{
|
|
CGPROGRAM
|
|
#pragma vertex vert
|
|
#pragma fragment frag
|
|
#pragma multi_compile_instancing
|
|
|
|
#include "UnityCG.cginc"
|
|
|
|
struct appdata
|
|
{
|
|
float4 vertex : POSITION;
|
|
float2 uv : TEXCOORD0;
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
};
|
|
|
|
struct v2f
|
|
{
|
|
float2 uv : TEXCOORD0;
|
|
float4 vertex : SV_POSITION;
|
|
float4 rectSize : TEXCOORD1;
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
};
|
|
|
|
UNITY_INSTANCING_BUFFER_START(Props)
|
|
UNITY_DEFINE_INSTANCED_PROP(fixed4, _Color)
|
|
UNITY_DEFINE_INSTANCED_PROP(half, _Radius)
|
|
UNITY_INSTANCING_BUFFER_END(Props)
|
|
|
|
v2f vert(appdata v)
|
|
{
|
|
v2f o;
|
|
UNITY_SETUP_INSTANCE_ID(v);
|
|
UNITY_TRANSFER_INSTANCE_ID(v, o);
|
|
|
|
o.vertex = UnityObjectToClipPos(v.vertex);
|
|
o.uv = v.uv;
|
|
|
|
// 获取实际矩形尺寸
|
|
float4 rectParams = float4(
|
|
length(float3(unity_ObjectToWorld[0].x, unity_ObjectToWorld[1].x, unity_ObjectToWorld[2].x)),
|
|
length(float3(unity_ObjectToWorld[0].y, unity_ObjectToWorld[1].y, unity_ObjectToWorld[2].y)),
|
|
0, 0
|
|
);
|
|
o.rectSize = rectParams;
|
|
|
|
return o;
|
|
}
|
|
|
|
// 圆形圆角SDF函数
|
|
float roundedBoxSDF(float2 uv, float2 size, float radius)
|
|
{
|
|
// 计算宽高比
|
|
float aspect = size.x / size.y;
|
|
uv.x *= aspect; // 标准化为正方形坐标系
|
|
|
|
float2 cornerSize = float2(1.0 - radius, 1.0 - radius);
|
|
float2 q = abs(uv) - cornerSize;
|
|
return length(max(q, 0.0)) + min(max(q.x, q.y), 0.0) - radius;
|
|
}
|
|
|
|
|
|
fixed4 frag(v2f i) : SV_Target
|
|
{
|
|
UNITY_SETUP_INSTANCE_ID(i);
|
|
|
|
float2 size = i.rectSize.xy; // 直接使用 UI 元素的宽高
|
|
float maxRadius = min(size.x, size.y) * 0.5;
|
|
float radius = UNITY_ACCESS_INSTANCED_PROP(Props, _Radius) * maxRadius;
|
|
|
|
// 计算 UV 并修正长宽比
|
|
float2 uv = (i.uv - 0.5) * 2.0;
|
|
uv *= size / min(size.x, size.y); // 确保 uv 坐标缩放一致,避免变形
|
|
|
|
// 计算 SDF
|
|
float sdf = roundedBoxSDF(uv, float2(1.0, 1.0), radius);
|
|
|
|
float alpha = 1.0 - smoothstep(0.0, 0.02 * maxRadius, sdf);
|
|
|
|
fixed4 color = UNITY_ACCESS_INSTANCED_PROP(Props, _Color);
|
|
return fixed4(color.rgb, alpha * color.a);
|
|
}
|
|
|
|
ENDCG
|
|
}
|
|
}
|
|
} |