WebGPU
What is WebGPU?
WebGPU is the next-generation graphics API for the web, designed to provide high-performance 3D graphics and general-purpose computing capabilities directly in web browsers. It offers several advantages over WebGL:
Key Benefits
- Better Performance: More efficient GPU utilization and reduced CPU overhead
- Modern GPU Features: Access to compute shaders, advanced texturing, and modern GPU capabilities
- Unified API: Single API for both graphics and compute operations
- Better Debugging: Improved error handling and debugging capabilities
- Future-Proof: Designed for modern GPU architectures
Browser Support
WebGPU is currently supported in:
- Chrome/Edge: Stable support (Chrome 113+)
- Firefox: Behind experimental flag
- Safari: Experimental support in Safari Technology Preview
Usage with TresJS
Import TresCanvas from @tresjs/core/webgpu. It creates a Three.js WebGPURenderer for you, and node materials work as template tags.
@tresjs/core/webgpu is available since @tresjs/core v5.10. On older versions, see Without the WebGPU entry.<script setup lang="ts">
import { TresCanvas } from '@tresjs/core/webgpu'
</script>
<template>
<TresCanvas>
<TresPerspectiveCamera :position="[3, 3, 3]" :look-at="[0, 0, 0]" />
<TresMesh>
<TresBoxGeometry :args="[1, 1, 1]" />
<TresMeshStandardNodeMaterial color="hotpink" />
</TresMesh>
<TresDirectionalLight :position="[3, 5, 2]" />
</TresCanvas>
</template>
The root import @tresjs/core does not change: its TresCanvas still uses WebGLRenderer.
What the WebGPU entry gives you
@tresjs/core | @tresjs/core/webgpu | |
|---|---|---|
Default renderer of TresCanvas, TresCanvasContext, useTresContextProvider and useRendererManager | WebGLRenderer | WebGPURenderer |
Node materials as tags (<TresMeshStandardNodeMaterial>) | No, needs extend() | Yes |
WebGL-only classes as tags (<TresWebGLCubeRenderTarget>) | Yes | No |
useTres().renderer type | WebGLRenderer | Renderer | WebGPURenderer |
All other exports (useLoop, useTresContext, extend, type guards, ...) are the same in both entries.
An app that imports only from @tresjs/core/webgpu does not bundle WebGLRenderer.
Node materials as tags
Importing @tresjs/core/webgpu adds every class of three/webgpu to the catalogue, so node materials are Tres components. Their node props take TSL nodes:
<script setup lang="ts">
import { TresCanvas } from '@tresjs/core/webgpu'
import { color, mix, positionLocal, sin, time } from 'three/tsl'
const colorNode = mix(
color('#82dbc5'),
color('#fbb03b'),
sin(time.add(positionLocal.y.mul(4))).mul(0.5).add(0.5),
)
</script>
<template>
<TresCanvas>
<TresMesh>
<TresTorusKnotGeometry :args="[0.6, 0.2, 128, 32]" />
<TresMeshStandardNodeMaterial :color-node="colorNode" :roughness="0.3" />
</TresMesh>
</TresCanvas>
</template>
The tags are typed. Import anything from @tresjs/core/webgpu once in your app, and the editor knows <TresMeshStandardNodeMaterial> and its props.
Typed useTres
Import useTres from @tresjs/core/webgpu in components inside the canvas. The renderer is typed as WebGPURenderer, so you do not need a cast:
import { useTres } from '@tresjs/core/webgpu'
const { renderer } = useTres()
console.log(renderer.backend) // WebGPURenderer-only API, no cast
TSL composables
To bind uniforms to refs, share TSL nodes between components or add post-processing, use useUniforms, useNodes, useLocalNodes and useRenderPipeline from @tresjs/core/webgpu. See TSL composables.
Standard materials and GLSL
- Standard materials still work.
WebGPURendererconverts<TresMeshStandardMaterial>,<TresMeshBasicMaterial>,<TresMeshPhysicalMaterial>and the other built-in materials to their node versions. ShaderMaterial,RawShaderMaterialandonBeforeCompile(GLSL) do not work withWebGPURenderer. Write the shader with wiki and a node material instead.
Mixed imports are safe
three and three/webgpu share their core classes. Mesh from three and Mesh from three/webgpu are the same class, so you can mix both import paths in one app.
WebGL2 fallback
When the browser does not support WebGPU, WebGPURenderer uses its WebGL2 backend. Node materials and TSL still work on that backend. To check which backend runs:
const { renderer } = useTres()
const isWebGPU = 'isWebGPUBackend' in renderer.backend
If the renderer cannot start at all, TresCanvas emits error with a TresRendererError:
<TresCanvas @error="(error) => console.error(error.message)">
Custom renderer options
You do not need the renderer prop for the normal case. The WebGPU TresCanvas passes antialias, alpha, depth, stencil, powerPreference and logarithmicDepthBuffer to WebGPURenderer.
For other WebGPURenderer options (for example samples, trackTimestamp or forceWebGL), give your own factory:
<script setup lang="ts">
import { TresCanvas } from '@tresjs/core/webgpu'
import type { TresRendererSetupContext } from '@tresjs/core/webgpu'
import { WebGPURenderer } from 'three/webgpu'
const createRenderer = (ctx: TresRendererSetupContext) => new WebGPURenderer({
canvas: toValue(ctx.canvas),
antialias: true,
trackTimestamp: true,
})
</script>
<template>
<TresCanvas :renderer="createRenderer">
<!-- Your scene -->
</TresCanvas>
</template>
Cientos
Import cientos from @tresjs/cientos/webgpu (since cientos v5.10, needs three r171 or newer). It has the same names and props as @tresjs/cientos, but it exports only the components that work under WebGPURenderer. Components built on GLSL shaders, such as ContactShadows, MeshReflectionMaterial and MeshTransmissionMaterial, are not exported yet, so importing one fails at build time and names it. See the cientos WebGPU guide for the full list.
Nuxt
Set renderer: 'webgpu' in the tres options. The module then auto-imports from the /webgpu entries:
export default defineNuxtConfig({
modules: ['@tresjs/nuxt'],
tres: {
renderer: 'webgpu',
},
})
<TresCanvas>usesWebGPURenderer, and the auto-importeduseTres()has theWebGPURenderertype.- Cientos components come from
@tresjs/cientos/webgpu. A component that has no WebGPU version yet (for example<ContactShadows>) still resolves, but it throws an error that names it when it mounts. @tresjs/post-processingis not auto-imported, because its effects work only withWebGLRenderer. The module shows a warning.- Packages that do not use the renderer, such as
@tresjs/leches, are auto-imported as usual.
The option applies to the whole app. To use WebGL on one page and WebGPU on another, keep the default renderer: 'webgl' and import TresCanvas from @tresjs/core/webgpu explicitly on the WebGPU pages. An explicit import is not client-only, so put it inside <ClientOnly>.
Without the WebGPU entry
On versions before v5.10, or to keep the root TresCanvas, pass a renderer factory and add the node classes to the catalogue yourself:
<script setup lang="ts">
import { extend, TresCanvas } from '@tresjs/core'
import type { TresRendererSetupContext } from '@tresjs/core'
import * as THREE_WEBGPU from 'three/webgpu'
// Makes <TresMeshStandardNodeMaterial> and the other node classes available as tags
extend(THREE_WEBGPU)
const createWebGPURenderer = (ctx: TresRendererSetupContext) => new THREE_WEBGPU.WebGPURenderer({
canvas: toValue(ctx.canvas),
antialias: true,
})
</script>
<template>
<TresCanvas :renderer="createWebGPURenderer">
<!-- Your scene -->
</TresCanvas>
</template>
Here useTres().renderer is typed as WebGLRenderer | Renderer, so check it with the isWebGPURenderer type guard before you use WebGPU-only APIs.
Advanced WebGPU Example
<script setup lang="ts">
import { TresCanvas } from '@tresjs/core/webgpu'
import { OrbitControls } from '@tresjs/cientos/webgpu'
import HologramCube from './HologramCube.vue'
</script>
<template>
<TresCanvas>
<TresPerspectiveCamera
:position="[3, 3, 3]"
:look-at="[0, 0, 0]"
/>
<Suspense>
<HologramCube />
</Suspense>
<OrbitControls />
<TresAmbientLight :intensity="1" />
</TresCanvas>
</template>