如何制作类似Figma的圆角矩形虚线轮廓Shader?
如何制作类似Figma的圆角矩形均匀虚线轮廓
Figma中的圆角矩形虚线轮廓是沿轮廓弧长均匀分段实现的,你之前用极坐标y值处理导致效果不均,核心原因是单一轴的分段无法适配圆角与直边的不同曲率。以下是精准实现的方案:
核心思路
要让虚线均匀,必须基于轮廓的弧长做分段,而非直角/极坐标的单一维度。步骤分为:
- 保留你已实现的「双圆角矩形相减」轮廓基础
- 给轮廓上的每个点计算其沿轮廓的弧长位置
- 基于弧长做周期化的显示/隐藏处理,得到均匀虚线
具体实现步骤
1. 明确轮廓参数
假设你的圆角矩形参数为:
- 外矩形尺寸:
(W, H) - 圆角半径:
R - 轮廓宽度:
B(内外矩形的尺寸差为2B,即内矩形尺寸为(W-2B, H-2B))
2. 计算轮廓弧长位置
将轮廓分为4段直边+4段圆角,对每个点判断所属区域,计算从轮廓起点(比如左上角圆角起始点)到该点的弧长:
| 区域 | 弧长计算公式 |
|---|---|
| 顶部直边 | 弧长 = x - R(x范围[R, W-R],y范围[H-R, H]) |
| 右上角圆角 | 以(W-R, H-R)为圆心,计算极角θ(0到π/2),弧长 = (W-2R) + R*θ |
| 右侧直边 | 弧长 = (W-2R) + πR/2 + (H-R - y)(x范围[W-R, W],y范围[R, H-R]) |
| 右下角圆角 | 以(W-R, R)为圆心,计算极角θ(π/2到π),弧长 = (W+H-4R) + πR/2 + R*(θ-π/2) |
| 底部直边 | 弧长 = 2*(W+H-4R) + πR + (W - x)(y范围[0, R],x范围[R, W-R]) |
| 左下角圆角 | 以(R, R)为圆心,计算极角θ(π到3π/2),弧长 = 2*(W+H-4R) + πR + R*(θ-π) |
| 左侧直边 | 弧长 = 2*(W+H-4R) + 3πR/2 + (y - R)(x范围[0, R],y范围[R, H-R]) |
| 左上角圆角 | 以(R, H-R)为圆心,计算极角θ(3π/2到2π),弧长 = 2*(W+H-4R) + 3πR/2 + R*(θ-3π/2) |
3. 生成均匀虚线遮罩
得到弧长后,用周期函数控制虚线显示:
// 示例:GLSL风格的伪代码 float dash_length = 10.0; // 虚线段长度 float gap_length = 5.0; // 间隔长度 float period = dash_length + gap_length; // 计算弧长在周期中的占比 float dash_frac = fract(arc_length / period); // 生成遮罩:弧长占比小于虚线占周期的比例则显示,否则隐藏 float dash_mask = step(dash_frac, dash_length / period); // 将遮罩与原轮廓相乘,得到最终虚线轮廓 float final_outline = original_outline * dash_mask;
为什么你的旧方法效果不均?
用极坐标y值做frac运算,是基于角度分段,但:
- 圆角区域的弧长与角度成正比,角度变化均匀则弧长变化均匀
- 直边区域的角度不变,弧长随x/y线性变化,导致该区域的虚线间隔会被拉伸/压缩,最终出现疏密不均的问题
内容的提问来源于stack exchange,提问作者deadbit
相关产品推荐
相关产品推荐

