Hi, I’m trying to implement a split-screen layout with RenderPipeline and WebGPURenderer. The setup calls renderer.setViewport() and renderer.setScissor() before each pipeline.render() for different viewports (similar to the classic WebGL split-screen approach).
The problem: viewport and scissor are ignored by RenderPipeline in the WebGPU backend.
After debugging I found two root causes:
1. Shared RenderContext
RenderContexts.get() caches render contexts by attachmentState + mrtState + callDepth. When two pipelines render to the canvas (renderTarget === null), both get the same renderContext with key 'default-default-0'. The second pipeline overwrites viewportValue in the shared context, so the first pipeline’s viewport is lost.
2. renderContext.viewport = false
Even when canvasTarget._viewport is set correctly (e.g. {x:0, y:0, w:2287, h:433}), the check:
js
renderContext.viewport = renderContext.viewportValue.equals( _screen ) === false;
…may evaluate to false if the viewport happens to equal the full screen dimensions, preventing the WebGPU backend from calling setViewport on the pass encoder at all.
Note: The WebGL backend has a similar fix already merged in #32883 (for forceWebGL: true). The WebGPU backend appears to still have this issue.
Question: Is there a supported way to use RenderPipeline with multiple viewports/scissor regions? Or is this a known limitation that needs to be addressed in RenderContexts?
Setup:
- Three.js r184
- WebGPURenderer (native WebGPU, not forceWebGL)
- One canvas, multiple viewports rendered per frame via
setScissor+setViewport