102 lines
3.0 KiB
Plaintext
102 lines
3.0 KiB
Plaintext
Shader "UI/RoundedRectangle"
|
|
{
|
|
Properties
|
|
{
|
|
_Color("Color", Color) = (1,1,1,1)
|
|
_Radius("Corner Radius", Range(0, 2.5)) = 0.1
|
|
}
|
|
|
|
SubShader
|
|
{
|
|
Tags
|
|
{
|
|
"Queue" = "Transparent"
|
|
"RenderType" = "Transparent"
|
|
"PreviewType" = "Plane"
|
|
}
|
|
|
|
Blend SrcAlpha OneMinusSrcAlpha
|
|
ZWrite Off
|
|
Cull 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;
|
|
float2 size : TEXCOORD1; // 传递 UI 组件的宽高
|
|
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;
|
|
|
|
// 计算 UI 组件的实际宽高
|
|
float2 size = float2(
|
|
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))
|
|
);
|
|
o.size = size; // 传递宽高信息
|
|
|
|
return o;
|
|
}
|
|
|
|
// 计算 SDF 圆角边界
|
|
float roundedBoxSDF(float2 uv, float2 size, float radius)
|
|
{
|
|
// 归一化 UV 到 [-1,1],保持正确比例
|
|
uv = (uv - 0.5) * 2.0;
|
|
uv *= size / min(size.x, size.y); // 保持等比例缩放
|
|
|
|
// 计算边界
|
|
float2 corner = float2(1.0 - radius, 1.0 - radius);
|
|
float2 d = abs(uv) - corner;
|
|
return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0) - radius;
|
|
}
|
|
|
|
fixed4 frag(v2f i) : SV_Target
|
|
{
|
|
UNITY_SETUP_INSTANCE_ID(i);
|
|
|
|
float radius = UNITY_ACCESS_INSTANCED_PROP(Props, _Radius) * min(i.size.x, i.size.y) * 0.5;
|
|
|
|
// 计算 SDF 圆角
|
|
float sdf = roundedBoxSDF(i.uv, i.size, radius);
|
|
|
|
// 抗锯齿处理
|
|
float alpha = 1.0 - smoothstep(0.0, 0.01 * min(i.size.x, i.size.y), sdf);
|
|
|
|
fixed4 color = UNITY_ACCESS_INSTANCED_PROP(Props, _Color);
|
|
return fixed4(color.rgb, alpha * color.a);
|
|
}
|
|
ENDCG
|
|
}
|
|
}
|
|
}
|