粒子一多 Three.js 就掉帧,WebGPU 用这个思路解决了
打开 null-graph.web.app (opens in a new tab),你能看到几十个运行在浏览器里的实时渲染 Demo:太空舰队、粒子烟花、量子星云、全息特效、CRT 滤镜……这些效果全靠 WebGPU 驱动,不依赖任何游戏引擎。

它跟 Three.js 有什么不一样
大多数人接触 WebGPU 是通过 Three.js 或 Babylon.js——这些框架用场景图管理所有 3D 对象:每个物体是一个 JavaScript 对象,挂在父节点下,每一帧引擎遍历整棵树、计算矩阵变换、提交绘制命令。
这套结构对几百个物体来说完全没问题。但当场景里有几万个动态实体时(比如太空舰队里的每一艘飞船、烟花模拟里的每一个粒子),情况就不一样了:
- 每帧遍历成千上万个 JS 对象,CPU 开销涨上来
- 对象频繁创建销毁,GC 开始介入,帧率出现抖动
- 主线程被占满,UI 交互也开始卡
NullGraph 的做法是把场景图整个删掉。

底层思路:数据直接喂给 GPU
NullGraph 借鉴了游戏引擎里的一种设计思路——Data-Oriented Design(面向数据设计):与其为每个实体创建一个 JS 对象,不如把所有实体的数据打包进一整块连续内存(Float32Array),直接映射到 GPU 的 Storage Buffer,让 GPU 自己去读取和处理。
没有对象树,没有矩阵遍历,主线程只负责每帧往数组里写新数据,GPU 负责其他所有事。
这带来几个实际变化:
不再有 GC 抖动:所有内存在启动时预分配好,运行中不创建新对象,GC 没有机会介入。
零拷贝流式传输:配合 Web Workers 使用时,可以在 Worker 线程里跑物理/AI 计算,算完直接把 Float32Array 所有权转交给主线程(不复制),再流式写入 GPU 显存。
GPU 自己做剔除:支持把视锥剔除(判断物体是否在摄像机视野内)的逻辑搬到 GPU 的 Compute Shader 里执行,CPU 不参与,减少无效的绘制请求。
多通道后处理:支持链式渲染通道(G-Buffer → 后处理),Demo 里的全息效果、CRT 滤镜、泛光都是通过这套机制实现的。

怎么用
安装
npm install null-graph gl-matrixgl-matrix 是数学运算依赖,需要一并安装。NullGraph 基于 WebGPU,需要 Chrome 113+ 或其他支持 WebGPU 的浏览器。
框架分两个模块:
null-graph:核心引擎(初始化、渲染通道管理、Buffer 写入)null-graph/geometry:几何工具包(内置 Cube、Plane、Pyramid、Octahedron 生成器)
路径一:手动模式(适合自定义顶点数据)
| 步骤 | 调用 | 作用 |
|---|---|---|
| 1 | await engine.init(canvas) | 初始化 WebGPU 设备,绑定 Canvas |
| 2 | engine.createPass(config) | 创建渲染通道 |
| 3 | engine.createBatch(pass, pipelineConfig) | 创建渲染批次,传入着色器代码 |
| 4 | engine.setBatchGeometry(batch, vertices, indices, count) | 绑定顶点/索引数据 |
| 5 | 每帧:engine.updateBatchData(batch, float32Array, instanceCount) | 上传实例数据 |
| 6 | 每帧:engine.render() | 执行渲染 |
比如渲染 10000 个每帧位置变化的粒子:只需更新 Float32Array 里对应的坐标字节,调用 updateBatchData 和 render,不需要遍历任何对象。
路径二:几何构建器模式(推荐快速上手)
用内置的 Primitives 类直接生成形状数据:
import { Primitives, VertexLayout } from 'null-graph/geometry';
const layout = new VertexLayout(['position', 'normal']);
const cube = Primitives.createCube(layout, 1, 1, 1);
// cube.vertices、cube.indices 可直接传入 setBatchGeometry后续 init → createPass → createBatch → render 流程与手动模式相同。
能看到的 Demo 效果
官方 Demo 站按类型分了几组:
视觉特效类:Quantum Core、Quantum Nebula、Aetherial Flow、Cymatic Resonance、Stellarator Flux——大多是粒子流、流体模拟和几何共鸣效果。
后处理类:CRT Effect、Hologram Effect、Bloom Effect、SynthWave CRT——展示多通道渲染管线的实际表现。
游戏 Demo 类:Space Fleet(太空舰队实时模拟)、Fireworks Simulation(烟花粒子)——这两个能直观看出框架处理大量动态实体的能力。
架构对比类:AoS / SoA / AoSoA / OOP (Scene Graph)——分别跑同样的场景,可以对比不同内存布局下的帧率表现。

当前状态与适用场景
已完成的功能:多对象批次渲染、深度缓冲、Compute Shader 视锥剔除、几何构建器。
还在规划中:PBR 材质与贴图、GLTF 模型解析、级联阴影贴图。
这意味着目前它还不具备开箱即用的材质系统和模型加载能力,需要自己写 WGSL 着色器。对于大多数业务项目,Three.js 依然是更合适的选择——工具链完善、社区资源丰富、上手门槛低。
NullGraph 更适合这样的情况:你在做对实体数量有极端要求的场景(MMO、体素引擎、大规模粒子模拟),传统场景图已经成为瓶颈,并且你有能力自己掌控底层渲染逻辑。
写在最后
NullGraph 的核心主张是:Web 渲染不一定要走面向对象那条路,游戏引擎里用了多年的面向数据设计同样可以在浏览器里跑起来,WebGPU 提供了这个可能。
Demo 站可以直接打开体验,架构对比那组 Demo 值得重点看一下,切换 AoS/SoA/OOP 能直观感受到不同内存布局对帧率的影响。
GitHub:https://github.com/Vikas593-cloud/NullGraph (opens in a new tab)