Three.js教程
R3F
r3f-webgpu-starter
r3f-webgpu-starter

R3F 接入 WebGPU 渲染器,关键就这几行代码

React Three Fiber 默认用 WebGL 渲染器,要切换到 Three.js 的 WebGPU 渲染器,不是改一个配置项那么简单——渲染器初始化是异步的,R3F 的 Canvas 不知道怎么处理这个时序,写法要专门适配。

r3f-webgpu-starter 把这套接入方式完整实现了一遍,还加了 TSL 节点材质和 WebGPU 后处理管线。源码读下来,关键思路集中在几个地方。

渲染器怎么注入

第一个关键:从 three/webgpu 而不是 three 导入。

import * as THREE from "three/webgpu";
import { Canvas, extend } from "@react-three/fiber";
 
extend(THREE);

extend(THREE) 把 WebGPU 版本的所有 Three.js 类注册进 R3F,这样 JSX 里的 <meshStandardNodeMaterial /> 这类节点材质才能直接用。

渲染器本身通过 Canvasgl prop 注入:

<Canvas
  gl={(canvas) => {
    const renderer = new THREE.WebGPURenderer({
      canvas,
      powerPreference: "high-performance",
      antialias: false,
    });
    renderer.init().then(() => setFrameloop("always"));
    return renderer;
  }}
  frameloop={frameloop}  // 初始值是 "never"
>

这里有个细节:WebGPU 渲染器的 init() 是异步的,要等它完成才能开始渲染。所以 frameloop 默认设为 "never"init() 的 Promise resolve 之后再切换成 "always"。如果不做这个处理,可能拿到一个还没初始化好的渲染器就开始跑了。

TSL 节点材质

项目里 Naboo 星舰的引擎喷焰用的是 meshStandardNodeMaterial,这是 Three.js WebGPU 体系里的节点材质:

<meshStandardNodeMaterial
  key={key}
  colorNode={colorNode}
  transparent
  blending={AdditiveBlending}
  emissiveNode={colorNode}
/>

TSL(Three Shader Language)是 Three.js 新引入的节点图着色器系统,colorNodeemissiveNode 这类 prop 接收的是用 TSL API 构建的节点,而不是普通的颜色值。节点里可以做时间驱动的动画、噪声函数、数学运算,最终编译成 WebGPU 的 WGSL 着色器(WebGL 下降级到 GLSL)。

这和传统的 meshStandardMaterial 写法不同——后者通过 onBeforeCompile 注入 GLSL 片段,前者是用 JS API 构建整个着色器图。

WebGPU 后处理管线

后处理部分用的不是 drei 里的 EffectComposer,而是 Three.js WebGPU 渲染器自带的后处理系统:

import { bloom, smaa, ssr } from "three/tsl";
 
const postProcessing = renderer.postProcessing;
postProcessing.add(ssr(...));
postProcessing.add(bloom(...));
postProcessing.add(smaa());

SSR(屏幕空间反射)、Bloom 泛光、SMAA 抗锯齿,三个效果叠加。这套 API 和 EffectComposer 的 Pass 叠加模式思路类似,但是直接跑在 WebGPU 管线上,不走 WebGL 的那套路径。

项目里还做了一个运行时开关,可以直接在页面上切换后处理的开启/关闭,对照着看效果差异比较直观。

跑起来

git clone https://github.com/ektogamat/r3f-webgpu-starter.git
cd r3f-webgpu-starter
npm install
npm run start

在线演示:https://r3f-webgpu-post-processing.vercel.app/ (opens in a new tab)

需要 Chrome 113+ 才能跑 WebGPU,Safari 和 Firefox 目前支持有限。Three.js 的 WebGPU 渲染器还在积极开发中,three/webgpu 的 API 尚未稳定,生产项目接入前建议锁定 Three.js 版本。

这个项目本身就是一份参考实现,适合对照着读源码——渲染器注入、异步初始化、节点材质、后处理管线,每个部分都有对应的完整代码可以直接拿来改。


GitHub:https://github.com/ektogamat/r3f-webgpu-starter (opens in a new tab)