WebGL 与流体玻璃的交汇
网页上大多数流体玻璃效果都使用 DOM 克隆。它们复制 HTML 元素,对其进行扭曲、添加模糊,并将其置于玻璃层下方。
这种方法在 WebGL 中会失效。DOM 克隆无法复制实时 canvas 的像素。canvas 是一个每一帧都在变化的帧缓冲(framebuffer)。
要让流体玻璃在 canvas 上生效,你有两个选择。你可以每一帧都捕获 canvas,但这非常消耗性能。或者,你可以将玻璃效果直接移入 WebGL 管线本身。
我做了一个实验来测试第二种方法。我需要一个带有动态效果的背景来展示这种效果。我从 Konmari 的交互式水波纹演示中汲取了灵感。
我构建了自己的版本,具有真实的波纹物理效果和漂浮的花朵。
结果是一个带有流体玻璃面板的 WebGL 水景。该面板会折射其下方的实时 canvas。
工作原理:
- 水面使用高度场波纹模拟(height-field ripple simulation)。
- 指针移动在网格上产生波浪。
- WebGL 着色器将这些波浪转化为光影和畸变。
- 2D canvas 上的花朵有助于清晰地展示折射效果。
玻璃面板并不克隆 DOM。相反,它进行像素采样。
渲染流程遵循以下步骤:
- 渲染 WebGL 水面。
- 渲染 2D 花朵。
- 将两者合并到一个隐藏的源 canvas 中。
- 使用玻璃着色器对该源 canvas 进行采样。
着色器会估算一个软边缘法线(soft edge normal)。它利用这一点来弯曲源纹理。我添加了色调(tint)和色散(chromatic split)效果,使材质看起来更有厚度感。
目标并不是完美的物理模拟。目标是让面板感觉像是置于动态场景之上的真实材质。
这之所以可行,是因为场景本身就是像素。对于整个网页的完整解决方案会更难。真实的网站包含文本、视频和滚动效果。
我正在密切关注这一领域。性能将是未来解决方案面临的最大挑战。
Demo: https://ripple.carsonye.com/ Repo: https://github.com/Whynotmetoo/water-ripples
Source: https://dev.to/_carson_ye_/where-webgl-meets-liquid-glass-401l
