I have 3 different threejs (canvas/scene/renderer) combos in a page I’m building.
I have it managed so that only one experience renders at a time but I’d like to better understand the performance overhead of just having 3 different webGPU renderers instantiated?
Also as an aside, is it possiblewith webGPU to setContext to assign a renderer a new canvas?
Not sure exactly what you’re aiming for, but if the goal is performance, consider using a single canvas and renderer, and simply swap between multiple scenes as needed.
Here’s a minimal example:
let currentScene = 0;
const scenes = [scene1, scene2, scene3];
function swapScene(index: number) {
currentScene = scenes[index];
}
function render() {
renderer.render(currentScene, camera);
}
You can also swap cameras or renderer settings the same way.
As far as I know that’s not possible, you need to create a new canvas with a new renderer and dispose of the old one.
I know with GL it wasn’t possible. Unsure if webGPU may have better context feature set.
Mostly trying to understand if there is a strong performance penalty for multiple renderers.
Cannot conveniently swap scene/camera b/c the canvases are at different locations on the page, fill varied sizes, and are nested in their own respective components.
It is probably possible to use one renderer and swap but given aforementioned details I don’t plan to do this unless I deem the performance hit substantial and worth justifying the effort. It’d involve an insane append strategy or crazy black magic fixed positioning+ CSS warcrimes.
Sorry I don’t personally have experience with using multiple WebGPU renderers on a page either. But, for several similar projects I’ve used the viewport/scissor APIs similar to this example…
… essentially with one large canvas overlaying the entire application, and drawing into that canvas as needed. If it’s possible to adapt your application design this way, it has the great advantage of freely sharing data (geometry, textures, materials) among contexts.
In R3F the <View/> abstraction exists for exactly this; in Preact I’ve done something similar but custom, where a component manages its own scene, pushes a callback to a common render loop, and the renderer and canvas are kept in shared context.
Form my understanding you only need one scene at a time. So it’s pretty simple, use a single canvas component with position absolute at the root of the document. From there, it’s just a matter of setting the correct 2D coordinates x, y, width, and height, and swapping scenes as needed.