One Logo Pool Ball
wwwwwwwwwwwwwwwwwww

WebGPU

GPU rendering through react-native-webgpu

One ships no GL view. The blessed GPU surface on native is react-native-webgpu, which vendors Dawn on iOS and Android and exposes the web navigator.gpu API plus a Canvas component: raw WebGPU, TypeGPU, or three.js all build on it, and nothing else is needed.

Three.js runs through three/webgpu with WebGPURenderer, including under React Three Fiber. R3F mounts through createRoot on the webgpu canvas. Do not use @react-three/fiber/native, which requires expo-gl:

import { Canvas, useCanvasRef } from 'react-native-webgpu'
import * as THREE from 'three/webgpu'
import { createRoot, events, extend } from '@react-three/fiber'
// inside a component, once layout has a nonzero size:
const ref = useCanvasRef()
extend(THREE)
const context = ref.current.getContext('webgpu')
const renderer = new THREE.WebGPURenderer({ canvas: context.canvas, context })
await renderer.init()
const renderFrame = renderer.render.bind(renderer)
renderer.render = (scene, camera) => {
renderFrame(scene, camera)
context.present()
}
const root = createRoot(context.canvas)
root.configure({ size, events, gl: renderer, frameloop: 'always', dpr: 1 })
root.render(<Scene />)
// and render the surface itself:
<Canvas ref={ref} style={{ flex: 1 }} />

Every frame ends with context.present(). On unmount, call setAnimationLoop(null) and dispose() on the renderer: R3F’s unmount alone never stops three’s internal frame loop.

One three instance must serve the whole graph. On native, bare three resolves to the three/webgpu build and @react-three/fiber to its web entry, while web keeps WebGL three. The alias option’s native map does this:

import { createRequire } from 'node:module'
import { one } from 'one/vite'
const require = createRequire(import.meta.url)
export default {
plugins: [
one({
alias: {
native: {
three: require.resolve('three/webgpu'),
'@react-three/fiber': require.resolve(
'@react-three/fiber/dist/react-three-fiber.esm.js'
),
},
},
}),
],
}

Metro mode does not apply One’s aliases, so R3F on WebGPU needs the default bundler. WebGPURenderer runs no GLSL: ShaderMaterial and onBeforeCompile do not work under it. Use node materials, or bake static gradients into vertex colors or DataTextures. PMREMGenerator.fromScene works; compileEquirectangularShader does not exist on this backend.

Edit this page on GitHub.