feat(xr): WebGPU multiview frame pass, XR bridge, and clustered lights#8723
Merged
Conversation
Add FramePassMultiView and frame graph integration for per-eye WebGPU XR rendering; extend WebGPU XR bridge and device state; fix multiview detection and cluster assignment for wrapped passes; refresh xr-views example and debug labels.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds a WebGPU-focused XR stereo rendering path by introducing a FramePassMultiView wrapper that replays captured frame passes once per XR view, integrating that wrapper into the frame graph and forward renderer scheduling. It also extends the WebGPU XR bridge/device state to expose per-view sub-image data (including view descriptors for layered textures) and updates clustered-light assignment to work correctly for passes captured inside the multiview wrapper.
Changes:
- Added
FramePassMultiViewandFrameGraph.beginMultiView/endMultiViewto capture and replay passes per XR view while keeping frame-graph pass merging safe. - Updated
ForwardRendererscheduling to wrap eligible stereo XR blocks, and updated the per-view draw loop to render only the active view when a wrapper is iterating. - Extended WebGPU XR state (
xrSubImages,xrColorTextureViewDescriptor,_clearXrState) and updated the XR views example to visualize multiview output on WebGPU.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/scene/renderer/world-clusters-allocator.js | Unwraps FramePassMultiView so clustered lighting gets assigned to child passes’ render actions. |
| src/scene/renderer/frame-pass-multi-view.js | New wrapper pass that iterates XR sub-images per view and replays child passes. |
| src/scene/renderer/forward-renderer.js | Wraps eligible camera/layer blocks in multiview scopes and restricts per-view rendering to the active eye when iterating. |
| src/scene/frame-graph.js | Adds multiview capture scope plumbing and compiles wrapper children with existing optimizations. |
| src/platform/graphics/webgpu/webgpu-xr-bridge.js | Populates per-view XR sub-image info (including optional view descriptors) and centralizes XR state clearing. |
| src/platform/graphics/webgpu/webgpu-render-target.js | Creates framebuffer color views using the XR per-eye view descriptor when applicable and improves labels. |
| src/platform/graphics/webgpu/webgpu-graphics-device.js | Adds XR multiview state fields and implements _clearXrState(). |
| examples/src/examples/test/xr-views.example.mjs | Expands the XR views harness for WebGPU array-layer rendering + composite visualization. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
Implements per-eye WebGPU XR rendering via a
FramePassMultiViewwrapper integrated with the frame graph and forward renderer, extends WebGPU XR bridge/device state for sub-images and cleanup, and ensures clustered lighting assignment runs for passes inside the multiview wrapper. Updates thexr-viewstest example and related WebGPU debug labeling.Changes:
FramePassMultiViewto run child frame passes once per XR view with device/backbuffer XR state.FrameGraphwith multiview begin/end helpers and pass-merge rules that treat the wrapper as atomic.CameraComponent; guard unsupported depth/post paths.xrSubImages/xrColorTextureViewDescriptor/_clearXrStatebehavior; framebuffer color view creation and debug labels for XR vs context paths.WorldClustersAllocator: unwrapFramePassMultiViewwhen assigning clusters so inner render actions getlightClustersbefore forward passes run.xr-views.example.mjs: expanded harness for multiview / composite testing.Public API: None intended; new types and device fields are
@ignoreengine internals.Examples:
examples/src/examples/test/xr-views.example.mjsupdated.