把旋转坐标、极角映射、fract 重复三件事串起来,就能做出旋转的多扇区遮罩:
下面拆解它。
atan 提取极角
atan(y, x) 返回点 (x, y) 相对于原点的角度,范围是 -π 到 +π(约 -3.14 到 +3.14)。
把它映射到 0–1 方便后续处理:
先加 π 让范围变成 0–2π,再除以 2π,结果就是 0–1 的一圈。
fract 把角度切成扇区
fract(angle01 * 8.0) 把 0–1 的角度放大 8 倍,再取小数部分——一圈被均等切成 8 段,每段各自从 0 到 1。
smoothstep(0.32, 0.42, wedges) 取每段的后半部分截断,形成每个扇区的"开口"与"关闭"区域。1.0 - 翻转后,每个扇区靠开头的部分是白色,靠末尾的是黑色。
坐标旋转让图案动起来
p = rot(u_time * 0.8) * p 在提取极角之前先旋转坐标系。旋转之后 atan 读到的角度整体偏移,所以所有扇区都一起转,产生旋转动画。
如果先算角度再旋转,就无法达到这个效果——顺序很重要。
试着改一改
| 改动 | 效果 |
|---|---|
把 8.0 改成 12.0 | 从 8 扇区变成 12 扇区 |
把 0.32 改成 0.1 | 每个扇区的亮色部分更宽 |
把 u_time * 0.8 改成 u_time * 3.0 | 旋转加速 |
把 wedgeMask * ringMask 改成只用 wedgeMask | 去掉径向环,整个画面都显示扇区 |
练习
用 atan(p.y, p.x) 计算极角并映射到 0–1,再用 fract 和 smoothstep 构造重复扇区遮罩 wedgeMask。
答案解析
atan(p.y, p.x) 把 2D 坐标转成极角(-π 到 +π)。加 π 再除以 2π 把范围搬到 0–1 一圈。fract(angle01 * 8.0) 把这一圈均分成 8 段,smoothstep 在每段后部制造软截断,最终得到 8 个均匀分布的扇区遮罩。
练习的起始状态 angle01 = 0.0、wedgeMask = 0.0,遮罩全黑。按上述补全后就能看到旋转扇区效果。
试着把 smoothstep(0.32, 0.42, wedges) 改成 smoothstep(0.45, 0.55, wedges),看看扇区宽窄的变化。