探索噪声流场
噪声流场:如果画布上有一阵看不见的风
如果画布上什么都没有,只有一片空白。现在,我们在里面放入几千个小小的粒子。然后告诉它们:“向前走。”
但是,我们并没有告诉所有粒子应该往哪里走。因为在画布上,还隐藏着一股看不见的“风”。这里的风向可能是向左,那里可能是向右。再往前一点,风又开始转弯。有些地方,风形成旋涡。有些地方,风像河流一样向前流动。还有一些地方,风会慢慢改变方向。
粒子无法看到这张“风的地图”。它们只知道到了哪里,就按照哪里的风的方向走。于是,成千上万个粒子开始运动。它们走过的地方,留下细细的轨迹。
慢慢地,一张复杂的图案出现了。看起来像🌬️ 风,🌊 水流,☁️ 烟雾,🪶 羽毛。🧵 丝绸,甚至像某种看不见的力量正在空间中流动。这就是 噪声流场。
想象一张“风的地图”
理解 噪声流场 最简单的方法,不是先看公式。而是: 想象一张风的地图。
假设整个画布上都有风。在这里:→ → → 风向右。走到旁边:↗ ↗ ↗ 风开始向右上方吹。再往前:↑ ↑ ↑ 风变成向上。然后:↖ ↖ ↖ 又开始转向。如果把整个画布都画满这样的箭头,我们就得到了一张 流场,它描述的是 画布上的每一个位置,应该向哪个方向流动。在流场中,粒子只需要“顺着风走”。
现在,把一个小粒子放进去。它来到这里,这里的风向是 ↗ ,所以它向右上方移动。下一步,它来到了一个新的位置,这里的风向变成 → ,于是它向右移动。再下一步,↘ ,于是它开始向右下方移动。注意:粒子自己并不知道整个地图长什么样。它甚至不需要知道:“我要去哪里?”,它只需要不断询问:“我现在这里,风往哪里吹?”,然后:跟着走。
如果只有一个粒子,其实没有什么特别的。它只是走,转弯,再走,再转弯。
但是,如果我们放进去 100 个粒子,开始有一点感觉了。
如果是 1000 个粒子,轨迹开始交织。
如果是 10000 个粒子,一幅完整的流动图案就出现了。
最神奇的地方:我们没有画线,但是看起来这么自然
看到最终图案,你可能会以为:“这些曲线是不是数学家直接画出来的?”,不是,我们甚至没有规定:“这里画一条弯曲的线。”,我们只规定:粒子应该向哪里走,然后让粒子自己走。粒子走过的地方,留下轨迹。很多粒子的轨迹叠加起来,就形成了最终的图案。
所以,噪声流场不是直接画出流动的线,而是让流动自己留下线。
那为什么它看起来这么自然?
如果我们真的随机决定每个位置的方向,可能会得到:↗ ← ↓ → ↖ ↑ ← ↘,完全没有规律,粒子走起来,会非常混乱,看起来就像电视机上的雪花噪声。但是 噪声流场 使用的“噪声”并不是这种完全独立的随机数,它使用的是一种具有连续性、平滑变化的噪声,最常见的实现之一就是 柏林噪声。柏林噪声可以产生相邻位置之间变化平滑的数值,因此非常适合用来构造连续的流场。
于是,这里向右。旁边还是差不多向右。再旁边,稍微向右上。再往前,继续慢慢转。而不是这里向右。下一个位置突然变成向下,类似这样,→ → ↗ ↗ ↑ ↖ ↖ ← ,方向慢慢发生变化。于是粒子的运动也会平滑地转弯。这就是为什么噪声流场经常会产生一种非常自然的感觉。
“噪声”到底是什么?
看到这里,你可能会问:“可是它明明看起来这么有规律,为什么叫噪声?”
这里的“噪声”不要简单理解成毫无规律的随机。柏林噪声更接近一种 平滑、连续、带有随机性的变化。比如: 0.41、0.43、0.45、0.48、0.52、0.55……,数字在变化,但不会突然 0.42 → 0.97 → 0.03 → 0.81 这种剧烈跳跃。
因此,它既不会完全规则,又不会完全混乱,恰恰处于 规律与随机之间,这正是它特别适合生成自然视觉效果的原因之一。柏林噪声的设计目标之一,就是产生比普通随机数更连续、更自然的数值变化。
于是,我们把噪声变成了“风”。
噪声本身只是一些数值,但我们可以把这些数值转换成 角度。例如,某个位置的噪声值 → 转换成一个角度 → 得到一个方向 → 变成一个箭头 → 成为流场的一部分,整个画布都这样计算,于是,噪声 → 方向 → 流场 → 粒子 → 轨迹 → 噪声流场。
回顾一下整个过程
现在把整个过程放在一起:
第一步:生成一张平滑变化的噪声。
第二步:把噪声转换成不同方向。
第三步:这些方向组成一张看不见的流场。
第四步:在覆盖了流场的画布上放入大量粒子。
第五步:每个粒子根据流场不断查询自己所在位置的方向。
第六步:粒子沿着查询到的流场方向运动。
第七步:粒子在身后留下轨迹。
最后,一幅流动的噪声流场图案出现了。
为什么有时候像水,有时候像烟?
因为 流场可以有不同的尺度和变化方式。如果流场变化得非常缓慢,大范围的方向会比较一致,粒子会形成 宽阔、平滑的流动。如果流场变化更加细密,粒子的运动会更加复杂,于是可能产生 细密的卷曲和交织。所以,只需要改变一些参数,就可以让同一个系统产生完全不同的视觉效果。
其中一个非常重要的参数是 噪声尺度,也就是 紊流细腻度,可以粗略理解成 “风的变化有多大。”。如果尺度很大,风的方向变化比较缓慢,粒子可能形成 🌊 大面积的流线。如果尺度比较小,风的方向变化更加细密,粒子可能形成 🌀 更复杂、更密集的纹理。
还有一个有趣的问题:风会动吗?当然可以。如果我们让噪声不只是水平和垂直两个维度,还增加一个随时间变化的维度,那么,这会儿这里的风向,和下一秒这里的风向,就可以稍微不同。于是,整个流场开始缓慢变化,粒子继续运动,但是,它们所处的“风”也在变化。于是画面不再是一张静态图,而变成 一个不断呼吸、流动、变化的世界。
你看到的是“风”,其实没有风
如果我们只显示粒子本身,你只会看到很多小点。但如果每个粒子都留下轨迹,情况完全不同。粒子, ● ,移动, —— ,继续,再继续。最后,一条完整的流线出现了。大量粒子的流线交织起来,就形成了我们看到的 噪声流场。所以最终的美感,其实来自 粒子的运动 + 轨迹的累积。
画面中没有真正的风,没有真正的水,没有真正的烟,甚至没有真正的粒子,一切都是 数学计算。
但是,当大量粒子按照一个平滑变化的方向场运动时,我们的眼睛会自然地把它理解成流动。于是,数学 → 变成运动,运动 → 变成轨迹,轨迹 → 变成视觉,视觉 → 让我们联想到自然。
噪声流场 和吸引子有什么不同?
如果你已经探索过数学吸引子,噪声流场 会是一个很不一样的体验。
例如,德容吸引子 重点是 一个点按照递推公式不断计算。
池田吸引子 重点是 旋转、缩放和位置之间的反馈。
洛伦兹吸引子 重点是 三维动力系统与混沌。
而 噪声流场,重点不是一个点最终会被吸引到哪里,而是大量粒子如何沿着一张“看不见的流场”运动,所以它更像 一张数学风场地图。
噪声流场甚至不一定需要“吸引”,吸引子通常强调 系统长期运动后形成某种稳定的结构,噪声流场则完全可以没有这样的“终点”。粒子可以一直向前,遇到边界后重新出现。或者不断产生新的粒子。甚至,整个流场都可以随时间变化。所以它更适合被理解为 一种流场驱动的生成艺术系统,而不是严格意义上的“吸引子”。
一张看不见的地图
如果要把 噪声流场 浓缩成一个最简单的故事,可以这样想:画布上有一张 看不见的地图。地图上每一个地方,都有一个箭头。这些箭头不是完全随机的,它们会慢慢转弯,彼此连接,形成连续的流动。然后,我们放入成千上万个粒子。粒子不知道地图长什么样,它们只知道:“我现在在哪里?”,然后:“这里的风往哪里吹?”。于是,它们开始走。走过的地方,留下轨迹。最终,这张看不见的地图,被粒子的轨迹 画了出来。
你看到的不是一幅图片,而是一场运动留下的痕迹。没有粒子运动,就没有轨迹。没有流场,粒子也不知道该往哪里走。没有噪声,就没有这种平滑而自然的方向变化。这些东西组合起来:噪声 → 方向 → 流场 → 粒子 → 轨迹 → 噪声流场,于是,一张看不见的“数学风场”,终于被我们看见了。
继续探索吸引子的世界
噪声流场 和的吸引子一样,都在展示一个有趣的思想:简单的规则,也可以创造复杂的视觉世界。
如果你喜欢 参数创造抽象纹理,可以继续探索 德容吸引子 和 克利福德吸引子。
如果你喜欢 旋转、反馈与混沌,可以探索 池田吸引子。
如果你喜欢 三维空间中的奇异运动,可以尝试 相泽吸引子 和 洛伦兹吸引子。
而 噪声流场 提供的是另一种体验:不是等待一个点找到它的终点,而是观察成千上万个点一起顺着一张看不见的地图流动。
你看不到风,看不到流场,甚至看不到控制它们的数学规则。你只能看到 它们走过的路。而这些路,最终组成了一幅 会流动的数学画。
你还可以继续欣赏更多奇妙的数学图形,或者查看维基百科上更多关于噪声的介绍