-
-
Notifications
You must be signed in to change notification settings - Fork 36.4k
Add forceMonoscopic option for WebXR #33180
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -111,6 +111,17 @@ class WebXRManager extends EventDispatcher { | |
| */ | ||
| this.isPresenting = false; | ||
|
|
||
| /** | ||
| * When `true`, both eyes use the left eye's view position. Useful for content | ||
| * that must be viewed from a single viewpoint (e.g. 360° panoramas, Matterport-style). | ||
| * Uses native `forceMonoPresentation` when available, otherwise a position-override fallback. | ||
| * Maintainers: please review the implementation when the WebXR Layers API evolves. | ||
| * | ||
| * @type {boolean} | ||
| * @default false | ||
| */ | ||
| this.forceMonoscopic = false; | ||
|
|
||
| /** | ||
| * Returns a group representing the `target ray` space of the XR controller. | ||
| * Use this space for visualizing 3D objects that support the user in pointing | ||
|
|
@@ -480,6 +491,18 @@ class WebXRManager extends EventDispatcher { | |
|
|
||
| glProjLayer = glBinding.createProjectionLayer( projectionlayerInit ); | ||
|
|
||
| // Monoscopic: fallback to native XR API if available. | ||
| // This will be ignored if the device/browser already supports native mono presentation | ||
| if ( scope.forceMonoscopic && 'forceMonoPresentation' in glProjLayer ) { | ||
|
|
||
| try { | ||
|
|
||
| glProjLayer.forceMonoPresentation = true; | ||
|
|
||
| } catch ( e ) {} | ||
|
|
||
| } | ||
|
|
||
| session.updateRenderState( { layers: [ glProjLayer ] } ); | ||
|
|
||
| renderer.setPixelRatio( 1 ); | ||
|
|
@@ -982,6 +1005,15 @@ class WebXRManager extends EventDispatcher { | |
|
|
||
| camera.matrix.fromArray( view.transform.matrix ); | ||
| camera.matrix.decompose( camera.position, camera.quaternion, camera.scale ); | ||
|
|
||
| // Monoscopic fallback: override right eye position when native API not available | ||
| if ( scope.forceMonoscopic && i === 1 && cameras[ 0 ] !== undefined ) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you still do this when the attribute exists
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unfortunately, I only have a Quest 3 for testing. The feature shows as available, but it’s not fully working yet. It will work once the feature is actually supported. In the meantime, it only falls back when not available.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How is it not working? Can you send me a file where it's broken?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don’t have a reproducible example beyond the Quest 3. The attribute appears in the API but stays at Stereo because it’s not fully functional yet. I can share a small test snippet if needed.take a look at last edit 568b724. |
||
|
|
||
| camera.position.copy( cameras[ 0 ].position ); | ||
| camera.matrix.compose( camera.position, camera.quaternion, camera.scale ); | ||
|
|
||
| } | ||
|
|
||
| camera.projectionMatrix.fromArray( view.projectionMatrix ); | ||
| camera.projectionMatrixInverse.copy( camera.projectionMatrix ).invert(); | ||
| camera.viewport.set( viewport.x, viewport.y, viewport.width, viewport.height ); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you don't need to do a try/catch here. This method can't throw