✦设计雷达
知识地图
2026-09-23 · 今日最炫

Ferrofluid Microphone

对着麦克风吹口哨,黑色磁流体会颤动、长刺、塌落;声音输入被翻译成了触感十足的形变。

Ferrofluid Microphone 截图 打开网站 ↗
大白话拆解

它是什么:对着麦克风说话或唱歌,屏幕上的黑色磁流体就会长出尖刺;安静下来,它又塌回一滩。

好在哪:声音 → 形状的因果关系一眼就懂,而且材质像真的磁流体,黑亮、带反光。

怎么做到的:

  1. 液体由很多小粒子组成,每帧计算它们之间的推拉,形成流动感。
  2. 麦克风的音高和音量被实时分析,数值越大,“磁场”越强、尖刺越高。
  3. 鼠标/手指也能当作磁铁去拨它。
完整技术拆解

今日拆解 · Ferrofluid Microphone

为何选它

在 8 条里它把「麦克风音高 → 黑色磁流体长刺 / 塌落」做成可感知的因果链:既有完整的 GPU 流体模拟,又有 Web Audio 分析,视觉材质也够炫。Splish Splash 主要是流体玩具;Beat Machine 偏 UI/节奏反馈;bleibtgleich / Rows 更偏排版与微交互。Ferrofluid 的技术深度与「一眼就懂」的效果同时成立。

实际在源码里找到的技术栈

twgl.js 5.2.0许可证注释:/* @license twgl.js 5.2.0 ... http://github.com/greggman/twgl.js */
WebGL2 / GLSL ES 3.00多段 shader 以 #version 300 es 开头;扩展枚举含 webgl2
Tweakpane 3.1.0(调试)const Ls=new e("3.1.0") 且导出 Pane / BladeApi;仅在 URL 带 ?debug 时挂载
Web Audionew AudioContext、getUserMedia({audio:...})、createAnalyser()、fftSize = 2048
RxJS(推测用于 resize)ge(window,"resize").pipe(...) 的操作符形态;未在 bundle 内找到明确的 rxjs@x.y.z 字符串
未使用源码中未找到 three.js / OGL / R3F / GSAP / WebGPU 标识

粒子数默认:NUM_PARTICLES = 500。平面高度图分辨率:planeResolution = 256。

核心效果怎么工作(源码 + 标明推测)

1. SPH 粒子模拟(确认)

GPU 上做经典 SPH(Smoothed Particle Hydrodynamics):

  • 状态存在纹理:u_positionTexture、u_velocityTexture、u_forceTexture、u_densityPressureTexture
  • 邻域用网格哈希:u_indicesTexture / u_offsetTexture + CELL_TEX_SIZE / CELL_SIZE(有 bitonic 风格的多 pass 排序)
  • 核函数常量在 UBO u_SimulationParams 里:POLY6 / SPIKY_GRAD / VISC_LAP / REST_DENS / GAS_CONST / VISC / MASS / H / HSQ —— 这是 Müller 式 SPH 的标准组合

Pass 大致顺序(确认):

  1. 按位置写入 cell index
  2. 排序 indices
  3. 建 offset 表
  4. density + pressure(poly6Weight)
  5. 力(压力梯度 + 粘度 VISC_LAP)
  6. integrate:ai = fi / rho; vi += ai * dt,再叠加 pointer 力与边界阻尼

2. 麦克风 → 形变(确认)

mic → MediaStreamSource → AnalyserNode (fftSize=2048, minDecibels=-90)
     → getByteFrequencyData
     → 取能量最大的 frequency bin
     → freq = index * (sampleRate/2 / bufferLength)
     → 在 [MIN_FREQ=400, MAX_FREQ=2400] 上做 log2 归一化,再映射到 [-1, 1]
     → 经弹簧阻尼(targetZoomLerp / zoomOffsetMomentum)驱动 this.ZOOM
     → ZOOM 写入 shader uniform:u_zoom、u_spikeFactor

集成 shader 里有明确的 zoom 力:

pi.xy += zoomForce * 0.008 * max(0., (1. - u_zoom * 2.5));

高度/网格绘制 shader 里用 u_zoom 控制边缘与 spike 位移(u_spikeFactor)。

推测:尖刺观感主要来自「粒子被径向/向上推开 + 高度网格按密度/位移抬起 + 高光黑材质」,而不是单独的铁磁学方程;铁流体是视觉隐喻。

3. 指针交互(确认)

UBO u_PointerParams:pointerPos / pointerVelocity / pointerRadius / pointerStrength。在 integrate 中若粒子距指针 < radius,则叠加 pointerVelocity * pointerStrength * (1 - pr/radius)。另有一处 idle 微扰力。

4. 伪代码(忠实于源码结构)

each frame:
  audio = peakFreqNorm()          # [-1,1] or 0 if silent
  ZOOM = spring(ZOOM, audio)      # zoomOffsetMomentum damping

  # GPGPU SPH
  hash particles into cells
  sort + build neighbor offsets
  density, pressure = SPH_poly6(neighbors)
  force = SPIKY_grad(pressure) + VISC_lap(velocity)
  integrate(pos, vel, force, pointerForce, zoomForce(ZOOM))

  # render
  draw points / height mesh with spikeFactor(ZOOM), dark glossy shading

如果我来重做(步骤清单)

  1. Vite + Canvas,申请 webgl2,引入 twgl.js 管 framebuffer / program。
  2. 实现 500 粒子的 RGBA32F 状态纹理 + ping-pong FBO。
  3. 写 SPH:density → force → integrate(先 2D),网格哈希邻域。
  4. getUserMedia + AnalyserNode,把峰值频率映射到一个 zoom uniform。
  5. 用粒子生成 height map 或直接画 metaball/points,加高光黑色材质。
  6. 可选:Tweakpane 调 REST_DENS / VISC / POINTER_STRENGTH。
  7. 最后再加 entry 动画与麦克风按钮 UX。

证据文件

  • artifact.html、index-8a2ccd9a.js、index-295bf82f.css(本目录)
小白课

零基础也能看懂。先认识这件作品用到的技术,再学一个知识点。

1技术栈小白版

只列拆解里在源码中确认过的技术。点开看它在这件作品里做了什么。

WebGL2 / GLSL网页通往显卡的「直通车」:借它,网页可以直接指挥电脑里专门画图的芯片(GPU)干活。 GLSL 则是写着色器用的语言。

在这件作品里粒子模拟和黑色磁流体的绘制,全都在 GPU 上跑。

怎么认出来画面能实时回应你的声音和手指,而且非常流畅。

twgl.js 5.2.0WebGL 的「省力手套」:原本要写几十行的准备工作(编译着色器、准备贴图、管理画布),用它几行就搞定。

在这件作品里帮作者管理着色器程序和「画布」——模拟每一步的结果都存在图片一样的数据里,来回倒着用。

怎么认出来看不出来,它是幕后工具。(它和 09-28 的 Liquid Geo 出自同一位作者,用的也是同一个库。)

Web Audio + 麦克风浏览器里的「声音分析仪」,外加一个需要你同意才会打开的麦克风开关。

在这件作品里实时听麦克风,找出此刻最响的那个音高(在 400 到 2400 赫兹之间),换算成一个数字去推磁流体。

怎么认出来网页会请求麦克风权限;你一出声,画面就变。

GPU 上的 SPH 流体模拟把液体想象成一群互相推挤的小弹珠:挤太近就推开,太远就拉回。

在这件作品里默认 500 个粒子,每一帧依次算:谁和谁挨着 → 挤得多密 → 受多大的力 → 往哪儿移动。

怎么认出来东西会流动、会聚成一团、有粘稠感。

Tweakpane 3.1.0(调试面板)作者自己用的「调音台面板」,上面是一排滑杆。

在这件作品里只有在网址后面加上 ?debug 时才会出现,用来调粒子的粘度、密度等参数;普通访客看不到。

怎么认出来页面角落出现一个满是滑杆的小面板(一般只在调试时)。

2今日知识点

游戏与交互设计 · 第 1 课

交互是什么:输入 → 处理 → 反馈

看一幅画,是你单方面地「看」它;玩一件交互作品,是你和它在「对话」:你做一件事(输入),它想一想(处理),然后回应你(反馈)。你再根据它的回应做下一件事——这就是交互回路。

Ferrofluid Microphone 把这个回路做得特别清楚:

  • 输入:你对着麦克风发声,或者用手指去拨;
  • 处理:程序找出你声音里最响的音高,换成一个 -1 到 1 之间的数字,再像弹簧一样让它平滑地变化;
  • 反馈:黑色的磁流体长出尖刺,或者塌回一滩。

为什么它让人忍不住一直玩?因为它的反馈快(几乎没有延迟)、清楚(声音和形状直接对应)、还带点惊喜(每次形状都不太一样)。好的交互,几乎都满足这三点。

一句话记住:交互 = 输入 → 处理 → 反馈,然后循环。 反馈越快、越清楚,人就越觉得「是我在控制它」。

它从哪里来

认知科学家、设计师唐·诺曼(Don Norman)在 1988 年出版的《设计心理学》(The Design of Everyday Things)里强调:好的设计要让人清楚地看到自己的操作带来了什么结果——这就是「反馈」。这本书至今仍是交互设计的入门必读。

游戏设计师把这件事推到了极致。2008 年,Steve Swink 写了《Game Feel》,专门讨论实时操控带来的「手感」;2012 年,Martin Jonasson 和 Petri Purho 在一场叫「Juice it or lose it」的演讲里演示:同一个小游戏,只是加上抖动、粒子和音效这些反馈,就变得好玩得多。

经典参考

  • 唐·诺曼《设计心理学 1:日常的设计》英文名 The Design of Everyday Things。讲门、开关、水龙头为什么有的好用、有的难用。
  • 「Juice it or lose it」(2012 演讲)Martin Jonasson 与 Petri Purho 的演讲,网上能搜到视频,15 分钟看懂「反馈让东西变好玩」。
  • Steve Swink《Game Feel》(2008)专门讲游戏「手感」的书,适合以后进阶。
怎么看 / 怎么练 · 约 8 分钟
  1. 打开 Ferrofluid Microphone,先不出声看 10 秒;然后轻轻「嗯——」一声,再大声一点,再分别试试高音和低音。每次都留意磁流体怎么回应。
  2. 画三个格子:输入 / 处理 / 反馈,把你看到的填进去(「处理」那格可以写「它好像在听我的音高」)。
  3. 在生活里找一个「反馈很差」的东西,比如按了没反应的电梯按钮、不知道发没发出去的表单。想一想:给它加一个什么反馈就好了?

小词典

交互(interaction)
人和作品之间你来我往的「对话」。
输入(input)
你对作品做的事:点、拖、说话、晃手机。
反馈(feedback)
作品对你的回应:动画、声音、震动、文字提示。
延迟(latency)
从你操作到看到反馈之间的时间。越短越好。
交互回路(loop)
输入 → 处理 → 反馈,然后你再输入,不断循环。

3知识地图进度

游戏与交互设计第 1 课 / 共 14 课
这条线已学 1 课全部已学 10 / 89
下一课建议交互 第 2 课 · 反馈:让人知道「我做到了」 打开知识地图 ›
当天另外 7 个
App UI
ARCHIV
大号衬线字、居中藏品与米白留白,把“拍照归档万物”的工具入口做成安静的编辑页。
小游戏
Beat Machine
点击组成节拍循环,程序化脉冲像直接连着扬声器锥盆;画面很少,节奏反馈很足。
App UI
Humanoid Index
近白界面、浅灰卡片与并排比较,把复杂的机器人规格整理成一眼能扫、两步能比的目录。
App UI
Rows
窄栏列表、拖拽手感、完成烟花和删除燃烧,让极简协作工具的每一次操作都有反馈。
小游戏
Splish Splash
拖动水流,它会弯折、打结、散成粒子再重新汇合;把流体反馈压缩成一个纯粹的小玩具。
App UI
Uni
桃蓝渐变、圆角控件和手写批注,让本地优先的桌面 AI 助手显得轻、快,也不冰冷。
网站
bleibtgleich'26
从 brutalism 转向极简:黑白网格、海报式排版和精准转场,把作品集做成一组可玩的视觉实验。

设计雷达 · 每天 8 个值得看的网站、App UI 和网页小游戏