SDF 矩形

11 / 18
练习着色器中常用的数学基础积木。

矩形的有符号距离函数(SDF)用一行代码计算每个像素到矩形边界的距离:

下面拆解它。


什么是 SDF

SDF(Signed Distance Field,有符号距离场)给每个像素一个距离值:

  • 负值:在形状内部
  • 0:正好在边界上
  • 正值:在形状外部

知道了距离,用一个 smoothstep 就能画出带柔软边缘的形状,不需要复杂的光栅化判断。


sdBox 的逻辑

p 是像素相对于矩形中心的位置,b 是矩形的半宽/半高(比如 vec2(0.2, 0.12) 表示宽 0.4、高 0.24 的矩形)。

abs(p) - b 利用对称性只看第一象限:

  • 结果为负 → 当前像素的 x 或 y 分量在矩形范围内
  • 结果为正 → 超出矩形范围

length(max(d, 0.0)) 计算外部角落区域的距离(让角落是圆润还是尖锐取决于后续);min(max(d.x, d.y), 0.0) 计算内部和外侧边的贡献,两者相加得到完整的 SDF 值。


用 smoothstep 把距离变成遮罩

  • d < 0(内部)→ smoothstep 输出 0 → 遮罩为 1(白色)
  • d > 0.01(外部)→ smoothstep 输出 1 → 遮罩为 0(黑色)
  • 0 到 0.01 之间 → 柔和过渡

0.01 是边缘柔化的宽度,值越小边缘越硬。


试着改一改

改动效果
vec2(0.2, 0.12) 改成 vec2(0.3, 0.3)正方形
vec2(0.2, 0.12) 改成 vec2(0.4, 0.05)细长横条
0.01 改成 0.05边缘更模糊
1.0 - smoothstep(0.0, 0.01, d) 改成 1.0 - smoothstep(-0.01, 0.01, d)边缘更宽的柔化

练习

调用 sdBox(p, vec2(0.2, 0.12)) 计算距离 d,让画面显示一个白色矩形。

答案解析

p = vUv - 0.5 把坐标原点移到屏幕中心,sdBox 计算每个像素到以中心为原点、半宽 0.2、半高 0.12 的矩形的有符号距离。1.0 - smoothstep(0.0, 0.01, d) 把负值(内部)转为 1(白色),把正值(外部)转为 0(黑色),边界处有 0.01 宽的柔化过渡。

练习起始 float d = 0.0,整个画面都处于"恰好在边界"的状态,遮罩计算会显示一片均匀的值。把它换成正确的 sdBox 调用就能看到矩形。

试着把 vec2(0.2, 0.12) 改成 vec2(0.1, 0.25),看看竖条形状。

GLSL 代码编辑器

正确代码预览

当前代码预览