title: WebGPU
::warning Experimental Feature: WebGPU support in TresJS is experimental and requires modern browser support. WebGPU is still being developed and may have breaking changes. ::
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:
WebGPU is currently supported in:
::note Check current WebGPU browser support at Can I Use WebGPU and the official WebGPU support matrix. ::
TresJS supports WebGPU through Three.js's WebGPU renderer. You can enable WebGPU by providing a custom renderer factory to the <TresCanvas>
component.
<script setup lang="ts">
import { TresCanvas } from '@tresjs/core'
import { WebGPURenderer } from 'three/webgpu'
import type { TresRendererSetupContext } from '@tresjs/core'
// Create WebGPU renderer factory
const createWebGPURenderer = (ctx: TresRendererSetupContext) => {
const renderer = new WebGPURenderer({
canvas: toValue(ctx.canvas),
// WebGPU specific configuration
alpha: true,
antialias: true,
})
return renderer
}
</script>
<template>
<TresCanvas :renderer="createWebGPURenderer">
<TresPerspectiveCamera :position="[3, 3, 3]" />
<TresBoxGeometry :args="[1, 1, 1]" />
<TresMeshBasicMaterial color="hotpink" />
<!-- Your 3D scene here -->
</TresCanvas>
</template>
:::examples-web-gpu :::
::code-preview{class="[&>div]::my-0 [&>div]::w-full"} :::code-tree{default-value="app.vue"}
<script setup lang="ts">
import { isMesh } from '@tesjs/core'
import { useGLTF } from '@tresjs/cientos'
import { add, cameraProjectionMatrix, cameraViewMatrix, color, Fn, hash, mix, normalView, positionWorld, sin, timerGlobal, uniform, varying, vec3, vec4 } from 'three/tsl'
import { AdditiveBlending, DoubleSide, MeshBasicNodeMaterial } from 'three/webgpu'
const { nodes } = useGLTF('https://raw.githubusercontent.com/Tresjs/assets/main/models/gltf/blender-cube.glb', { draco: true })
const model = computed(() => nodes.value.BlenderCube)
/**
* Material
*/
const material = new MeshBasicNodeMaterial({
transparent: true,
side: DoubleSide,
depthWrite: false,
blending: AdditiveBlending,
})
// Position
const glitchStrength = varying(0)
material.vertexNode = Fn(() => {
const glitchTime = timerGlobal().sub(positionWorld.y.mul(0.5))
glitchStrength.assign(add(
sin(glitchTime),
sin(glitchTime.mul(3.45)),
sin(glitchTime.mul(8.76)),
).div(3).smoothstep(0.3, 1))
const glitch = vec3(
hash(positionWorld.xz.abs().mul(9999)).sub(0.5),
0,
hash(positionWorld.yx.abs().mul(9999)).sub(0.5),
)
positionWorld.xyz.addAssign(glitch.mul(glitchStrength.mul(0.5)))
return cameraProjectionMatrix.mul(cameraViewMatrix).mul(positionWorld)
})()
// Color
const colorInside = uniform(color('#ff6088'))
const colorOutside = uniform(color('#4d55ff'))
material.colorNode = Fn(() => {
const stripes = positionWorld.y.sub(timerGlobal(0.02)).mul(20).mod(1).pow(3)
const fresnel = normalView.dot(vec3(0, 0, 1)).abs().oneMinus()
const falloff = fresnel.smoothstep(0.8, 0.2)
const alpha = stripes.mul(fresnel).add(fresnel.mul(1.25)).mul(falloff)
const finalColor = mix(colorInside, colorOutside, fresnel.add(glitchStrength.mul(0.6)))
return vec4(finalColor, alpha)
})()
watch(model, (newModel) => {
newModel.traverse((child) => {
if (isMesh(child)) {
child.material = material
}
})
})
</script>
<template>
<primitive v-if="model" :object="model" />
</template>
<script setup lang="ts">
import { TresCanvas } from '@tresjs/core'
import { WebGPURenderer } from 'three/webgpu'
import type { ShadowMapType, ToneMapping } from 'three'
import type { TresRendererSetupContext } from '@tresjs/core'
import HologramCube from './HologramCube.vue'
const createWebGPURenderer = (ctx: TresRendererSetupContext) => {
const renderer = new WebGPURenderer({
canvas: toValue(ctx.canvas),
// WebGPU specific configuration
alpha: true,
antialias: true,
})
return renderer
}
</script>
<template>
<TresCanvas :renderer="createWebGPURenderer">
<TresPerspectiveCamera
:position="[3, 3, 3]"
:look-at="[0, 0, 0]"
/>
<Suspense>
<HologramCube />
</Suspense>
</TresCanvas>
</template>