目录
场景:生成带圆角的 UI 按钮或卡片,避免纹理拉伸,支持动态调整圆角大小
场景:为材质添加带圆角的矩形网格(如包装盒表面、布料补丁的圆角边缘)
场景:用圆角矩形遮罩高亮特定区域(如屏幕底部的提示框、图片的圆角边框)
一、节点功能概述
圆角矩形节点(Rounded Rectangle Node)是 Unity Shader Graph 中用于生成带圆角的矩形形状的核心工具。它基于输入的 UV 坐标,结合宽度(Width
)、高度(Height
)和圆角半径(Radius
)参数,生成边缘平滑的圆角矩形图案。该节点通过距离场(Distance Field)计算实现 —— 矩形的直边部分保持规则形状,四个角落则由圆弧过渡,最终输出从矩形内部(值为 1)到外部(值为 0)的平滑过渡效果,且自动处理边缘抗锯齿。
该节点的核心特性在于:
- 圆角可控:通过
Radius
参数精确控制四个角落的圆角大小,半径越大,圆角越圆润; - 边界约束:自动限制圆角半径的最大值(不超过宽高的一半),避免圆角超出矩形范围导致形状失真;
- 边缘平滑:利用 GPU 的屏幕空间导数函数(
fwidth
)动态调整边缘过渡范围,确保在任何分辨率下圆角和直边都无锯齿; - 片段着色器限制:仅能在片段着色器中使用,适合生成 UI 按钮、卡片、材质纹理、粒子形状等像素级效果。
二、端口详解
端口名称 | 方向 | 类型 | 描述 |
---|---|---|---|
UV | 输入 | Vector 2 | 圆角矩形的 UV 坐标(默认绑定主纹理 UV,范围通常为 [0,1]) |
Width | 输入 | Float | 圆角矩形的宽度系数(水平方向大小,建议 > 0) |
Height | 输入 | Float | 圆角矩形的高度系数(垂直方向大小,建议 > 0) |
Radius | 输入 | Float | 圆角半径(控制角落圆润程度,默认被限制在合理范围:不超过宽高的一半) |
Out | 输出 | Float | 圆角矩形的距离场结果(范围 [0,1],内部为 1,外部为 0,边缘平滑过渡) |
三、技术原理解析
3.1 核心逻辑与代码解析
圆角矩形的生成基于 “矩形距离场 + 圆角修正” 的混合计算,核心步骤通过代码实现如下:
hlsl
void Unity_RoundedRectangle_float(float2 UV, float Width, float Height, float Radius, out float Out)
{
// 1. 限制圆角半径范围:不超过宽/高的一半,且不小于极小值(避免除零)
Radius = max(min(min(abs(Radius * 2), abs(Width)), abs(Height)), 1e-5);
// 2. 计算UV到矩形边缘的距离(含圆角补偿)
float2 uv = abs(UV * 2 - 1) - float2(Width, Height) + Radius;
// 3. 计算圆角区域的距离(直边区域距离为0,圆角区域为到圆弧的距离)
float d = length(max(0, uv)) / Radius;
// 4. 边缘平滑处理(抗锯齿)
Out = saturate((1 - d) / fwidth(d));
}
3.2 步骤解析
-
圆角半径限制(Radius Clamping):
代码中Radius = max(min(min(abs(Radius * 2), abs(Width)), abs(Height)), 1e-5)
的作用是确保圆角半径合理:- 最大值:不超过矩形宽度(Width)或高度(Height)的一半(因
Radius*2
需≤Width 和 Height); - 最小值:1e-5(避免半径为 0 导致的除零错误或形状异常)。
这一步保证圆角不会 “撑破” 矩形,始终在合理范围内。
- 最大值:不超过矩形宽度(Width)或高度(Height)的一半(因
-
UV 坐标映射与距离计算:
UV * 2 - 1
:将 UV 从 [0,1] 映射到 [-1,1],使矩形中心与 UV 原点对齐;abs(...) - float2(Width, Height) + Radius
:计算 UV 到矩形直边的距离,并加上圆角半径作为补偿 —— 直边区域的距离为负,圆角区域的距离为正。
-
圆角距离场生成:
max(0, uv)
:仅保留圆角区域的距离(直边区域距离设为 0);length(...) / Radius
:计算圆角区域到圆弧的归一化距离(范围 [0,1],圆弧上距离为 1,内部为 0)。
-
边缘平滑(抗锯齿):
(1 - d)
:将距离转换为 0-1 的形状值(内部为 1,外部为 0);fwidth(d)
:计算距离在屏幕空间的导数(相邻像素的距离变化),动态调整边缘过渡宽度;saturate(...)
:将结果限制在 [0,1],确保输出值有效。
3.3 视觉特性
- 形状控制:
Width
和Height
决定矩形的宽高比(如Width=2, Height=1
为宽矩形);Radius
控制圆角圆润度:Radius=0
时为标准矩形,Radius
接近最大值时为 “胶囊状”(圆角占满角落)。
- 边缘过渡:距离场计算确保直边和圆角的边缘都平滑过渡,无锯齿 —— 过渡范围由屏幕分辨率自动适配(分辨率越高,过渡越窄)。
四、应用场景与实战案例
4.1 UI 圆角按钮 / 卡片
场景:生成带圆角的 UI 按钮或卡片,避免纹理拉伸,支持动态调整圆角大小
- 需求:创建一个宽高比 3:2 的圆角按钮,圆角半径为 0.2(中等圆角)
- 实现步骤:
hlsl
// 输入UI的UV(已归一化到[0,1]) float2 uv = IN.uv; // 生成圆角矩形(Width=0.6, Height=0.4, Radius=0.2) float roundedBtn = RoundedRectangleNode.Out; // UV=uv, Width=0.6, Height=0.4, Radius=0.2 // 应用按钮颜色与透明度 float3 btnColor = _BtnBaseColor * roundedBtn; float alpha = roundedBtn; // 边缘外透明 o.Albedo = btnColor; o.Alpha = alpha;
4.2 材质纹理(圆角网格 / 包装纹理)
场景:为材质添加带圆角的矩形网格(如包装盒表面、布料补丁的圆角边缘)
- 步骤:
hlsl
// UV添加平铺(控制网格密度) float2 uv = IN.uv_MainTex * 8; // 8x8网格 // 用Fraction Node处理UV,实现重复图案 float2 tiledUV = frac(uv); // 生成圆角矩形网格(小尺寸,圆角半径0.1) float grid = RoundedRectangleNode.Out; // UV=tiledUV, Width=0.8, Height=0.8, Radius=0.1 // 混合网格颜色与基础色(网格边缘为深色) float3 color = lerp(_BaseColor, _GridColor, 1 - grid); o.Albedo = color;
4.3 粒子形状(圆角矩形粒子)
场景:模拟带圆角的矩形粒子(如激光束、能量护盾的边缘)
- 实现:
hlsl
// 粒子UV([0,1]范围,Y轴拉伸模拟长条形) float2 uv = IN.uv * float2(1, 5); // 高度拉伸5倍 // 生成圆角矩形粒子(窄宽高比,圆角半径0.15) float particle = RoundedRectangleNode.Out; // UV=uv, Width=0.3, Height=4.5, Radius=0.15 // 应用形状到粒子亮度(中心亮,边缘渐变) float3 particleColor = _ParticleColor * (1 + particle * 0.3); // 中心增强 float alpha = particle * _Intensity; o.Albedo = particleColor; o.Alpha = alpha;
4.4 遮罩效果(圆角区域高亮)
场景:用圆角矩形遮罩高亮特定区域(如屏幕底部的提示框、图片的圆角边框)
- 示例:
hlsl
// UV添加偏移(控制遮罩位置,如屏幕底部) float2 uv = IN.uv + float2(0, 0.3); // 向下偏移30% // 生成圆角矩形遮罩(宽全屏,高占30%,圆角半径0.1) float mask = RoundedRectangleNode.Out; // UV=uv, Width=1, Height=0.3, Radius=0.1 // 高亮遮罩区域(内部为提示色,外部为原色) float3 highlight = lerp(_BaseColor, _TipColor, mask); o.Albedo = highlight;
五、使用技巧与注意事项
5.1 圆角半径的合理范围
- 建议
Radius
设置为宽高的 1/5 到 1/3(如Width=1
时,Radius=0.2-0.3
),避免过大(导致形状接近胶囊)或过小(圆角不明显); - 若需 “胶囊状” 效果(圆角占满角落),可将
Radius
设为宽高的最小值的一半(代码会自动限制)。
5.2 重复图案的处理
节点默认不会自动重复,若需生成重复的圆角矩形阵列,需先用Fraction Node
处理 UV:
hlsl
// 生成4x4重复圆角矩形阵列
float2 tileCount = 4;
float2 tiledUV = frac(IN.uv_MainTex * tileCount);
float repeatedRounded = RoundedRectangleNode.Out; // UV=tiledUV, Width=0.8/tileCount.x, Height=0.8/tileCount.y, Radius=0.1/tileCount.x
5.3 性能优化
- 圆角矩形的计算仅包含基础算术运算、
length
和fwidth
,属于轻量级操作,适合片段着色器高频调用; - 移动平台可适当减小
Radius
(减少圆角区域的计算量),或预烘焙静态图案到纹理。
5.4 边缘锐利度调整
默认边缘锐利度由fwidth
自动控制,若需手动调整,可添加缩放系数:
hlsl
float sharpness = 1.2; // 系数越大,边缘越锐利
Out = saturate((1 - d) / (fwidth(d) * sharpness));
六、总结与拓展应用
圆角矩形节点通过距离场计算生成带圆角的矩形,兼具规则几何与柔和边缘的特点,其核心价值在于:
- 形状精准可控:通过
Width
、Height
和Radius
的组合,可快速生成从标准矩形到胶囊状的全范围圆角形状。 - 边缘自动抗锯齿:基于
fwidth
的动态过渡确保在任何分辨率下都有平滑边缘,无需手动调整参数。 - 轻量高效:计算逻辑简单,性能开销低,适合 UI、材质、粒子等多场景高频调用。
拓展方向:
- 结合
Animation Curve
驱动Radius
,实现 “矩形→圆角矩形→胶囊” 的动态形状过渡; - 用噪声节点扰动
UV
,使圆角矩形边缘不规则(如模拟撕裂的纸张、磨损的卡片); - 叠加多个圆角矩形节点,通过
Subtract
操作生成 “圆角矩形挖空” 效果(如相框、边框)。