# Why WebGPURenderer performance significantly lower than WebGLRenderer?

**URL:** <https://discourse.threejs.org/t/why-webgpurenderer-performance-significantly-lower-than-webglrenderer/77629>\
**Category:** Questions\
**Tags:** webgl-renderer, tsl, performance, webgpu\
**Created:** [February 5, 2025, 5:55pm UTC](https://discourse.threejs.org/t/why-webgpurenderer-performance-significantly-lower-than-webglrenderer/77629 "2025-02-05T17:55:06Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![tenkkov](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/tenkkov/32/58286_2.png) [@tenkkov](https://discourse.threejs.org/u/tenkkov)\
**Post date:** [February 5, 2025, 5:55pm UTC](https://discourse.threejs.org/t/why-webgpurenderer-performance-significantly-lower-than-webglrenderer/77629/1 "2025-02-05T17:55:06Z")

</div>

I have a relatively simple scene containing thousands of meshes, and I am trying to switch from WebGLRenderer to WebGPURenderer. When I use WebGPURenderer, I encounter significant performance issues, and it feels roughly twice as slow as WebGLRenderer when rendering the same number of non-instanced meshes. Here’s the basic setup I am working with:

```javascript
import MeshBasicNodeMaterial from 'three/src/materials/nodes/MeshBasicNodeMaterial.js'

const material = new MeshBasicNodeMaterial()
const helperGrid = new Mesh(new PlaneGeometry(totalGridWidth, totalGridWidth), material)

```

However, when I try to run this code with `WebGLRenderer`, I get the following error in the Chrome console: `Uncaught TypeError: Cannot read properties of undefined (reading 'replace')`

The code works fine with `WebGPURenderer`, but the performance issue with it prevents me from moving forward with my project. Is this performance difference specific to the WebGPURenderer, or is there something else I’m missing?

---

<div class="post-metadata">

**Author:** ![manthrax](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/manthrax/32/2596_2.png) [@manthrax](https://discourse.threejs.org/u/manthrax)\
**Post date:** [February 6, 2025, 4:03am UTC](https://discourse.threejs.org/t/why-webgpurenderer-performance-significantly-lower-than-webglrenderer/77629/2 "2025-02-06T04:03:49Z")

</div>

WebGPURenderer is bleeding edge and under active development, so bugs are not unusual.

That said… “replace” might be related to some shader injection? Are you using onBeforeCompile in your code by any chance?

---

<div class="post-metadata">

**Author:** ![tenkkov](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/tenkkov/32/58286_2.png) [@tenkkov](https://discourse.threejs.org/u/tenkkov)\
**Post date:** [February 6, 2025, 11:09am UTC](https://discourse.threejs.org/t/why-webgpurenderer-performance-significantly-lower-than-webglrenderer/77629/3 "2025-02-06T11:09:16Z")

</div>

No onBeforeCompile I don’t use. You can see the performance sag if you set up a base scene with 1\_000\_000 base meshes and render them with WebGL first and then with WebGPU renderer.

---

<div class="post-metadata">

**Author:** ![manthrax](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/manthrax/32/2596_2.png) [@manthrax](https://discourse.threejs.org/u/manthrax)\
**Post date:** [February 6, 2025, 11:10am UTC](https://discourse.threejs.org/t/why-webgpurenderer-performance-significantly-lower-than-webglrenderer/77629/4 "2025-02-06T11:10:56Z")

</div>

are you seeing repeating warnings/errors in the console while the webgpu is running?

Are these meshes instanced?

---

<div class="post-metadata">

**Author:** ![tenkkov](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/tenkkov/32/58286_2.png) [@tenkkov](https://discourse.threejs.org/u/tenkkov)\
**Post date:** [February 6, 2025, 11:34am UTC](https://discourse.threejs.org/t/why-webgpurenderer-performance-significantly-lower-than-webglrenderer/77629/5 "2025-02-06T11:34:47Z")

</div>

The latest Chrome console is clean. I can’t say about InstancedMesh, but I can confirm the issue with regular Mesh imported from Three.js.

---

<div class="post-metadata">

**Author:** ![PavelBoytchev](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/pavelboytchev/32/38639_2.png) [@PavelBoytchev](https://discourse.threejs.org/u/PavelBoytchev)\
**Post date:** [February 6, 2025, 5:22pm UTC](https://discourse.threejs.org/t/why-webgpurenderer-performance-significantly-lower-than-webglrenderer/77629/6 "2025-02-06T17:22:55Z")

</div>

Maybe if you put online the two versions (WebGL and WebGPU) it would be easier for others to confirm (or not) your observations.

---

<div class="post-metadata">

**Author:** ![tenkkov](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/tenkkov/32/58286_2.png) [@tenkkov](https://discourse.threejs.org/u/tenkkov)\
**Post date:** [February 6, 2025, 11:00pm UTC](https://discourse.threejs.org/t/why-webgpurenderer-performance-significantly-lower-than-webglrenderer/77629/7 "2025-02-06T23:00:12Z")

</div>

Sure. Initially, I have simple setup where 20\_000 non-instanced basic cube meshes rendered with WebGL, so personally I have smooth 60 FPS on my Mac with Apple Silicon M1 Pro. Then, when I switch to WebGPURenderer (just uncommenting the line) FPS drops exactly 4 times (15 FPS) with the same amount of meshes. So my next question would be, is this a hardware specific issue, or is it a software issue related to the implementation of the WebGPU technology?

[https://codesandbox.io/p/sandbox/webgl-webgpu-484fmh](https://codesandbox.io/p/sandbox/webgl-webgpu-484fmh)

---

<div class="post-metadata">

**Author:** ![donmccurdy](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/donmccurdy/32/33209_2.png) [@donmccurdy](https://discourse.threejs.org/u/donmccurdy)\
**Post date:** [February 18, 2025, 3:09pm UTC](https://discourse.threejs.org/t/why-webgpurenderer-performance-significantly-lower-than-webglrenderer/77629/8 "2025-02-18T15:09:19Z")

</div>

1,000,000 meshes is a lot in either renderer — I’m not too surprised that would be unworkably slow without batching. As for why it’s a “less slow” in WebGLRenderer, they’re two separate renderers, with WebGPURenderer being relatively new and under active development… not to mention that the WebGPU API itself is still evolving. It could conceivably be either, I expect someone would need to spend some time digging into this to give you a full answer.

---

<div class="post-metadata">

**Author:** ![Mugen87](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mugen87/32/5645_2.png) [@Mugen87](https://discourse.threejs.org/u/Mugen87)\
**Post date:** [February 18, 2025, 5:01pm UTC](https://discourse.threejs.org/t/why-webgpurenderer-performance-significantly-lower-than-webglrenderer/77629/9 "2025-02-18T17:01:55Z")

</div>

@tenkkov Would you mind creating an issue for this at the three.js repository? I have slightly simplified the code from your sandbox and created a fiddle with it. You can share it at GitHub when creating the issue: [three.js dev template - module - JSFiddle - Code Playground](https://jsfiddle.net/foyLns9e/)

The performance problem in `WebGPURenderer` seems to be related to the way uniforms are managed. All 20.000 cubes share the same node builder state but each cube uses a UBO for its object scope uniforms (like the world matrix). This ends up in many `setBindGroup()`/ `bindBufferBase()` as well as `writeBuffer()`/`bufferData()` calls which significantly slow down the renderer.

Besides, the renderer seems to trigger a lot of redundant state updates although only the world matrix uniform value changes from cube to cube. That is separate issue that should be investigated as well.

---

<div class="post-metadata">

**Author:** ![tenkkov](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/tenkkov/32/58286_2.png) [@tenkkov](https://discourse.threejs.org/u/tenkkov)\
**Post date:** [February 19, 2025, 9:18am UTC](https://discourse.threejs.org/t/why-webgpurenderer-performance-significantly-lower-than-webglrenderer/77629/11 "2025-02-19T09:18:10Z")

</div>

> <https://github.com/mrdoob/three.js/issues/30560>
>
> \### Description
> 
> \*\*Summary\*\*
> 
> When switching from WebGLRenderer to WebGPURendere…r, I experience a significant drop in performance. The same scene, containing thousands of non-instanced meshes, runs smoothly at 60 FPS on WebGL but drops to 15 FPS on WebGPU, a 4x decrease in performance.
> 
> \*\*Expected Behavior\*\*
> 
> WebGPURenderer should provide comparable or better performance than WebGLRenderer, given its modern API and intended improvements over WebGL.
> 
> \*\*Current Behavior\*\*
> 
> Rendering 20,000 non-instanced basic cube meshes:
> 
> WebGLRenderer: ~60 FPS on Mac (Apple Silicon M1 Pro)
> 
> WebGPURenderer: ~15 FPS (4x slower)
> 
> No errors or warnings appear in the Chrome console.
> 
> \### Reproduction steps
> 
> 1. Create a Three.js scene with 20,000 Mesh instances.
> 2. Use WebGLRenderer and observe smooth 60 FPS performance.
> 3. Switch to WebGPURenderer by uncommenting the renderer swap.
> 4. Observe FPS dropping significantly (down to 15 FPS).
> 
> \### Code
> 
> see live example below
> 
> \### Live example
> 
> https://jsfiddle.net/15zfestk/1/
> 
> \### Screenshots
> 
> \_No response\_
> 
> \### Version
> 
> r.0.173.0
> 
> \### Device
> 
> Desktop
> 
> \### Browser
> 
> Chrome
> 
> \### OS
> 
> MacOS
