Move XR per-view data from the XR manager to the Camera (RenderView)#8907
Merged
Conversation
Closes #5011. Previously the XR manager pointed the scene Camera at itself (camera.xr = manager) so the renderer could reach the manager's per-view array, coupling the scene layer to the framework XR module. - Add a scene-level RenderView class holding a view's projection/view matrices, viewport and derived 'off' matrices plus updateTransforms(); XrView now extends it and populates it from WebXR. - Camera owns 'xrViews' (the per-view list, null when not in XR), with 'xrActive' derived from it, replacing the back-pointer; Camera.updateViewTransforms() refreshes the per-view matrices. - Renderer, forward renderer and the unified gsplat code read camera.xrViews / xrActive instead of camera.xr.*; CameraComponent.endXr goes through app.xr. - The two xr-views examples construct pc.RenderView directly instead of mocking the manager. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Public API reportThis PR changes the public API surface (+8 / −1), per the docs' rules (@ignore / @Private / undocumented are excluded). Show API diff+RenderView.fire(name: string, arg1?: any, arg2?: any, arg3?: any, arg4?: any, arg5?: any, arg6?: any, arg7?: any, arg8?: any): EventHandler
+RenderView.get viewport(): Vec4
+RenderView.hasEvent(name: string): boolean
+RenderView.off(name?: string, callback?: HandleEventCallback, scope?: any): EventHandler
+RenderView.on(name: string, callback: HandleEventCallback, scope?: any): EventHandle
+RenderView.once(name: string, callback: HandleEventCallback, scope?: any): EventHandle
+class RenderView extends EventHandler
-class XrView extends EventHandler
+class XrView extends RenderViewInformational only — this never fails the build. |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR refactors XR rendering data flow by moving per-view render data off the framework XR manager and onto the scene-layer Camera, reducing framework→scene coupling and making XR view data accessible via a scene-owned API.
Changes:
- Introduces
RenderView(scene-level per-view matrices + viewport + derived “off” matrices) and makesXrViewextend it. - Moves XR view ownership to
Cameraviacamera.xrViews(+ derivedxrActive) and addscamera.updateViewTransforms()for consumers. - Updates renderer, forward renderer, unified gsplat code, and XR examples to consume
camera.xrViews/xrActive.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/scene/renderer/renderer.js | Switches XR view acquisition to camera.xrViews and delegates per-view refresh to camera.updateViewTransforms() |
| src/scene/renderer/forward-renderer.js | Updates multiview detection / view list selection to use xrActive + xrViews |
| src/scene/render-view.js | Adds new RenderView base class for per-view render state and derived transforms |
| src/scene/gsplat-unified/gsplat-renderer.js | Updates XR-active detection to xrActive |
| src/scene/gsplat-unified/gsplat-projector.js | Uses cam.xrViews + cam.updateViewTransforms() for stereo projector matrices |
| src/scene/gsplat-unified/gsplat-manager.js | Uses sceneCam.xrViews / xrActive for viewport sizing and XR frustum handling |
| src/scene/camera.js | Adds xrViews, xrActive, and updateViewTransforms(); removes manager back-pointer behavior |
| src/index.js | Exports RenderView as part of the public module surface |
| src/framework/xr/xr-view.js | Refactors XrView to extend RenderView and populate it from WebXR frames |
| src/framework/xr/xr-manager.js | Assigns camera.camera.xrViews = views.list and clears it on failure/end |
| src/framework/components/camera/component.js | Routes endXr through app.xr and validates the active XR camera entity |
| examples/src/examples/test/xr-views.example.mjs | Updates example to construct pc.RenderView and populate per-view data via setView / setViewport |
| examples/src/examples/gaussian-splatting/xr-views.example.mjs | Updates splatting XR example to use pc.RenderView and camera.camera.xrViews |
💡 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.
Closes #5011.
Background
When an XR session was active, the XR manager pointed the scene
Cameraat itself (camera.camera.xr = manager) purely so the renderer could reach the manager's per-view array. That made the scene layer (renderer,forward-renderer, unified gsplat) reach up into the framework XR module. This moves the per-view data onto theCamera, so the XR manager just updates it.Changes
RenderViewclass (src/scene/render-view.js) — a single view's projection / view matrices, viewport, and the derived "off" matrices, plusupdateTransforms().XrViewnow extends it and populates it from the WebXR frame (setView/setViewport).RenderViewstays public becauseXrView.viewportwas already public.Cameraowns the views —camera.xrViewsis the per-view list (nullwhen not in XR), andxrActiveis derived from it, replacing the manager back-pointer.Camera.updateViewTransforms()refreshes the per-view derived matrices (called by the renderer and the gsplat passes).renderer.js,forward-renderer.js(_isMultiview), and the unified gsplat code readcamera.xrViews/xrActiveinstead ofcamera.xr.*.CameraComponent.endXrnow goes throughapp.xr.xr-viewsexamples constructpc.RenderViewdirectly instead of mocking the manager'sxrobject.Notes
xr-viewsexample to render all views correctly.-94lines (theRenderViewextraction removes duplication).