把圆形、矩形和 smooth min 组合起来,构造一个平滑融合的复合形状。
把两个 SDF 形状用 smin 融合,再分别绘制填充层和轮廓层:
下面拆解它。
为什么不直接用 min
min(a, b) 是硬取最小值——两个形状在交界处会突然切换,边缘生硬。
smin(a, b, k) 是平滑最小值:在两个形状接近的区域,距离场被"软化",过渡区域混合了两者,连接处自然圆润,就像两团泥巴捏在一起,而不是两块积木拼在一起。
参数 k 控制融合的柔软程度:k 越大,融合区域越宽、越圆润;k 趋近 0 时退化为硬 min。
形状的位置
两个形状都有偏移:
body:p + vec2(0.05, 0.0)向左偏移,圆角矩形是主体lobe:p - vec2(0.14, 0.02)向右偏移,圆形是附加突起
偏移让两个形状相互重叠,smin 在重叠区域产生圆润融合,整体看起来像一个有机形状。
填充层和轮廓层
融合后的 SDF 值 d 既能做填充,也能做轮廓:
- 填充:
1.0 - smoothstep(0.0, 0.012, d)→ d < 0 的区域(形状内部)亮 - 轮廓:
1.0 - smoothstep(0.018, 0.028, abs(d))→ d ≈ 0 的边界区域(很窄的一圈)亮
轮廓用的是 abs(d)——不管在形状里还是外,靠近 0 都会有响应,形成一条细细的边界线。
试着改一改
| 改动 | 效果 |
|---|---|
把 0.16 改成 0.04 | 融合区域变窄,接近硬边 |
把 lobe 的圆半径从 0.16 改成 0.08 | 突起变小 |
把 smin 换成 min | 融合变成硬切,边缘不圆润 |
把 outlineColor 改成 vec3(1.0, 1.0, 0.2) | 轮廓变黄 |
练习
用 smin(body, lobe, 0.16) 融合两个形状的距离场,再用 smoothstep 分别构造填充层 fill 和轮廓层 outline。
答案解析
smin(body, lobe, 0.16) 平滑合并两个距离场,融合宽度约为 0.16。负值区域是形状内部,正值是外部,0 是边界。
fill 使用 smoothstep(0.0, 0.012, d) 在边界处做很窄的柔化,内部(d < 0)几乎全是 1,外部(d > 0.012)几乎全是 0。
outline 使用 abs(d) 对称地检测边界:无论在哪一侧,只要 d 的绝对值小于 0.028,就会有亮度——产生一条宽约 0.01 的发光轮廓线。
练习的起始状态 d = 0.0,fill = 0.0,outline = 0.0,画面只显示背景。补全三行后就能看到完整的融合形状。
试着把 smin 的第三个参数从 0.16 改成 0.3,看看融合区域更大时形状的变化。