TH1/Unity/Assets/Shaders/UI/RoundedCorners.shader
2025-07-17 18:26:28 +08:00

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
}
}
}