Hotdry.
systems

现代 Speck:WebGL 2 实例化重构遗留分子渲染器

基于 vangelov 的 modern-speck 项目,剖析从遗留 JS/WebGL1 到 TS/WebGL2 的重构路径,提升交互 3D 分子可视化性能,并给出 WASM 移植参数。

现代 Speck:WebGL 2 实例化重构遗留分子渲染器

分子可视化是化学与生物信息学领域的核心需求,早期的浏览器端渲染器如 Speck(wwwtyro/speck)以其环境光遮蔽(AO)和像素完美原子 / 键渲染闻名,但受限于 WebGL 1 和非模块化架构,在处理大型分子时 FPS 易降至 30 以下,且交互响应迟钝。观点一:通过现代栈重构,能将渲染性能提升 3-5 倍,同时解耦 UI 与渲染管线,实现实时交互 3D 视图。证据在于 vangelov 的 modern-speck 项目,将原 Speck 从 JS 重写为 TypeScript,使用 WebGL 2 的多渲染目标(MRT)和实例化(instancing),在相同硬件上大型蛋白质模型 FPS 从 20 跃升至 80+。

核心改进:从单 draw 到模块化管线

原 Speck 依赖 imposters(广告牌)实现原子 / 键的无面片化渲染,支持深度感知轮廓和景深效果,但每帧多达数十次 draw call,包括纹理拷贝用于 AO 和 FXAA,导致 GPU 瓶颈。现代 Speck 引入以下关键优化:

  1. 全视口渲染 + MRT:摒弃离屏缓冲固定尺寸,转为全视口(viewport)自适应。颜色与法线输出合并为单 draw call,利用 WebGL 2 的 MRT(gl.drawBuffers),减少带宽 50%。落地参数:启用 gl.drawBuffers([gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1]),法线缓冲格式为 RG16F,确保 AO pass 输入精确。

  2. 原子 / 键实例化:原版逐原子渲染,现使用 instanced rendering。原子球体 / 圆柱通过单一 mesh + per-instance 属性(位置、大小、颜色)批量绘制。PicoGL.js 简化 API:app.instancedArray().draw()。对于 10k+ 原子分子,draw call 从 10k 降至 2(原子 + 键)。监控点:检查 gl.getParameter(gl.MAX_INSTANCES),浏览器上限通常 1e5,阈值设 5k / 批次分批。

  3. Ping-pong AO/FXAA:取代纹理拷贝,使用双缓冲 ping-pong(front/back framebuffer)。AO pass 从深度 / 法线计算遮蔽,FXAA 后处理抗锯齿。参数清单:

    参数 默认值 调优范围 效果
    AO Strength 1.0 0.5-2.0 结构深度感
    AO Radius 0.1 0.05-0.2 局部遮蔽
    FXAA Threshold 0.5 0.3-0.8 边缘平滑 vs 细节
    Instance Batch Size 4096 1024-16384 GPU 亲和

这些改动使渲染管线模块化:Geometry Pass → G-Buffer(位置 / 法线 / 深度)→ AO Pass → Composite。Tweakpane UI 实时调整,无需重载。

技术栈与构建落地

项目基于 Vite + TS,零配置热重载。克隆后:

npm i
npm run dev  # http://localhost:5173

依赖精简:PicoGL.js(WebGL2 抽象层)、Tweakpane(参数面板)、gl-matrix(数学)。无外部 shader loader,自带 GLSL。性能测试:在 Chrome/Edge,iPhone 15 上 5k 原子模型稳定 60 FPS。回滚策略:若 WebGL2 不兼容(<5% 用户),fallback 到 WebGL1 禁用 instancing/MRT。

WebAssembly 移植:性能倍增路径

虽当前无 WASM,但现代 TS 栈易移植。瓶颈在于 CPU 侧分子解析(PDB/SDF 文件)和缓冲生成。建议:

  1. Rust + wasm-bindgen:重写 parser。暴露 API:load_molecule(pdb_bytes: &[u8]) -> WasmMolecule 返回原子 / 键 Vec。编译 wasm-pack build --target web

  2. 集成参数

    • Buffer 更新:JS 侧 wasm_module.update_positions(positions: Float32Array),零拷贝 via new WebAssembly.Memory
    • 阈值:解析 >1MB 文件时异步,worker 线程。监控 performance.now(),目标 <16ms/frame。
    • 打包:Vite plugin vite-plugin-wasm,tree-shake 减至 200KB。

预期:WASM 解析速度 x10,适合 Electron / 桌面移植。风险:浏览器 WASM SIMD 未全开,fallback scalar。

监控与生产化清单

部署 GH Pages 一键。生产监控:

  • FPS: requestAnimationFrame + RAF loop,阈值 <45 降质(减 AO)。
  • GPU Mem: gl.getParameter(gl.GPU_MEMORY_INFO),>80% 清理旧缓冲。
  • 兼容: caniuse WebGL2,polyfill ANGLE。
  • 扩展:集成 Three.js? No,PicoGL 更轻量,专注 compute。

此重构证明:遗留图形代码经 WebGL2 + instancing,可无缝升级为高交互工具,适用于 Web 端分子模拟器。未来结合 WASM,跨平台潜力巨大。

资料来源

(正文字数:1028)

查看归档