为心理治疗实践构建生产级 WebGPU 引擎...

发布: (2025年12月24日 GMT+8 05:36)
5 min read
原文: Dev.to

Source: Dev.to

请提供您希望翻译的完整文本内容,我将按照要求保留源链接、格式和技术术语,仅翻译正文部分。

挑战:噪声化为流动

当为 Therapy Warsaw 打造数字形象时,我们遇到了一个不同寻常的需求。我们不想使用库存照片或静态插图。我们想要一种有生命感的东西——一种始终在变化但又不抢眼的生成式纹理。

视觉隐喻很简单:复杂的图案寻找清晰。噪声场慢慢自组织成连贯、流动的线条。

技术需求

  • 有机且密集:约 10,000 个相互作用的粒子。
  • 性能关键:在移动设备上滚动时保持 60 FPS。
  • 兼容性强:必须在十年前的笔记本(WebGL2)和前沿设备(WebGPU)上均能运行。
  • 无框架:不使用 React、Three.js,仅使用受控、流畅的逻辑。

架构:双栈 WebGPU + WebGL2 引擎

主线程外渲染

在网页上进行高负载图形渲染的第一条原则:脱离主线程

线程职责
主线程DOM、可访问性、路由、UI 状态
工作线程物理、几何生成、通过 OffscreenCanvas 渲染

即使物理模拟出现卡顿,页面滚动仍然流畅。通信通过专用的消息系统进行,可同步视觉“预设”(颜色、速度、湍流),且不会阻塞。

// main.js
const worker = new Worker(new URL('./worker.js', import.meta.url), { type: 'module' });
const offscreen = canvas.transferControlToOffscreen();

// Hand ownership to the worker
worker.postMessage({ type: 'init', canvas: offscreen }, [offscreen]);

WebGPU 实现

我们从 WebGPU 开始,因为 计算着色器 非常适合粒子系统。

Compute Passes

通道目的
映射通道生成噪声纹理(燃烧、密度、空洞图)
流动通道计算向量场
生命周期通道更新粒子年龄并处理重置
物理通道根据流向向量移动粒子

关键的性能提升在于:避免 CPU‑GPU 往返。整个模拟全部在 GPU 上运行。

使用 Transform Feedback 的 WebGL2 回退

WebGPU 的支持正在增长,但并非普遍,因此我们需要一种不会变成“笨拙”回退的方案。

  • Transform Feedback 允许 WebGL2 在顶点着色器中更新粒子位置并将其写回缓冲区,模拟计算着色器。
  • 这种方法在不让 CPU 负担过重的情况下保持功能等价。

平滑参数过渡:临界阻尼弹簧系统

当用户在页面之间切换时,可视化会发生形变(颜色变化、混沌改变、速度调整)。简单的线性插值显得机械化,于是我们实现了一个临界阻尼弹簧系统:

function updateSpring(state, target, dt) {
    const tension = 120;
    const friction = 20;

    const displacement = target - state.value;
    const force = tension * displacement - friction * state.velocity;

    state.velocity += force * dt;
    state.value += state.velocity * dt;
}

每帧我们更新约 20 个受弹簧驱动的参数,并将它们上传到 Uniform Buffer Object (UBO),从而产生一种更具物理感而非纯计算的过渡效果。

高效轨迹渲染

传统的粗线渲染方式需要为每段生成两个三角形(六个顶点)——对长轨迹来说开销很大。

我们的方法

  • 只存储每条线的 头部位置
  • 在顶点着色器中运行一个循环(约 60 次),向后追踪路径,通过流场实时重建轨迹。

优点:带宽大幅降低(每条线只需 1 个点,而不是成千上万个顶点)。
缺点:每个顶点的 ALU 开销更高。

在现代 GPU 上,ALU 成本低廉,而带宽昂贵。此权衡使我们能够在移动设备上渲染成千上万条长且平滑的轨迹。

Result

最终站点 therapywarsaw.com 采用了活跃的背景——一种安静的纹理,既体现了工作的本质,又在各种设备上保持良好的性能。

开源

该引擎是开源的:

github.com/23x2/generative-flow-field

欢迎探索着色器管线或 Transform Feedback 实现。

Back to Blog

相关文章

阅读更多 »