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