石上清泉
三维水面实验:清浅的溪底铺满鹅卵石,按住水面拖动,像手指划过水面;拖动小太阳,改变阳光的方向和高低。另有实时合成的水声和一首 AI 作曲的背景音乐。
怎么玩
- 划水:在水面上按住并拖动,就像手指伸进水里划过——指尖前面推起一道小浪,身后拖出一串尾迹,涟漪向四周散开,溪底的石头跟着晃动,光纹碎开又聚拢。手机上直接用手指划。
- 太阳:画面里发光的小圆盘就是太阳,可以拖到任何地方。拖到中间,太阳升到头顶,影子缩到石头底下;拖向边角,阳光斜照,影子拉长。划出的波纹经过太阳的倒影时,水面会闪出几点光。太阳的位置会记在本机,下次打开还在原处。
- 声音:浏览器规定页面要先有一次点击才能出声。「音效」开关水声,「音乐」播放背景音乐《涟漪》。
- 全屏:点「全屏」让水面铺满整个屏幕(部分手机浏览器不支持)。
- 键盘:先点一下画面,或用 Tab 键选中它;方向键移动太阳,回车或空格在水面上轻点一下。
是怎么做的
整个场景用 three.js 在浏览器里实时渲染,没有加载任何图片、模型或音频文件。
- 水波:在 GPU 上逐格求解二维波动方程,再加上色散项:短波跑得比长波快,一圈涟漪后面会拖出更细、更快的小波纹,这正是真实水面上毛细波的样子。模拟区域比画面大一圈,外圈是吸收波浪的“海绵”,波浪出了画面就消失,不会从边上反弹回来,看上去是一片开阔的水面。
- 指尖:按下时把水面压出一个小坑;移动时,前方的水被挤开、身后的水回填,再顺着运动方向推一把,划过的地方就留下 V 形的尾迹。
- 折射:水面着色器按水深把视线沿折射方向“追”到溪底,再取那里的画面,所以波纹经过时,底下的石头会跟着扭动。
- 焦散:把阳光穿过起伏水面后的折射光线投到溪底,比较投影前后的面积,光线汇聚的地方就是那张晃动的光网。电脑上红、绿、蓝三色光按略有不同的折射率各投一次,亮纹边缘带一点彩虹色。水面平静时,溪底只有很淡、很慢的光影浮动;划水激起波纹,光纹才亮起来。
- 倒影:太阳在水面上的倒影藏在小太阳底下,波纹经过时才碎成几点闪光,再由 Bloom 泛出光晕。
- 鹅卵石:每块石头都是随机捏出来的扁椭球,有花岗岩、玄武岩、砂岩、石英、红碧玉等好几种;斑点、条纹、白色的石英脉和细颗粒都由着色器里的噪声函数实时生成。石头泡在水里,颜色更深、更饱和,表面反光比在空气中弱得多;石缝和石头底下压暗,看上去是真的堆在一起。
- 声音:全部用 Web Audio 实时合成。划水声是随指尖速度起伏的滤波噪声,划得越快越响、越亮,还会冒出细小的气泡声;指尖入水、离开水面各有一声轻响。
背景音乐《涟漪》
由 AI(Claude)作曲并编配:D 大调五声音阶,每分钟 72 拍,引子之后按 A、B、A′、尾声循环。旋律稀疏、留白多,长音上带古筝式的揉弦和上滑音,像一颗颗落进水里的石子。
音乐同样在浏览器里实时合成:拨弦用 Karplus-Strong 弦振动算法生成,铺底和弦、低音和偶尔响起的“水滴”钟声都由振荡器合成。每一遍循环里,伴奏的细节都略有不同。