Add forceMonoscopic option for WebXR#33180
Conversation
📦 Bundle sizeFull ESM build, minified and gzipped.
🌳 Bundle size after tree-shakingMinimal build including a renderer, camera, empty scene, and dependencies.
|
|
@cabanier Does this change look good to you? |
|
@Mugen87 WebXR Layers has an attribute to do this more efficient at the browser level: https://immersive-web.github.io/layers/#dom-xrcompositionlayer-forcemonopresentation. |
|
@cabanier Agree and it shouldn't be a problem, but for now since the Layers API is not yet widely implemented, this proposal aims to provide a small opt-in workaround for cases where monoscopic presentation is required (such as panoramic or single-viewpoint scenes). |
|
Quest is the vast majority of the WebXR market so it's widely implemented :-)
At least for Quest, we don't like if you don't use the matrices that we give you and there might be some shaking in the right eye with your approach. I would object if it's turned on for our platform and you should likely test it on other headsets. |
|
@cabanier Agree, also for context, the current workaround was tested on a Quest 3 device as in images #33177 and is already used in a production application without noticeable issues so far "all the job done on Quest". so detecting support for forceMonoPresentation and use it, otherwise use my current implementation sounds like the right approach.I'll update the implementation. |
src/renderers/webxr/WebXRManager.js
Outdated
| // This will be ignored if the device/browser already supports native mono presentation | ||
| if ( scope.forceMonoscopic && 'forceMonoPresentation' in glProjLayer ) { | ||
|
|
||
| try { |
There was a problem hiding this comment.
you don't need to do a try/catch here. This method can't throw
src/renderers/webxr/WebXRManager.js
Outdated
| 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 ) { |
There was a problem hiding this comment.
you still do this when the attribute exists
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
How is it not working? Can you send me a file where it's broken?
There was a problem hiding this comment.
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.
|
I think I misunderstood this feature. It seems you are trying to display non-stereo content. @Mugen87 , I don't believe this is the right approach for monoscopic content. |
|
Alternatively, you can display your content in a three.js quad. It won't be as good as a native layer, but it will work everywhere. |
|
Most of the environments for the case I'm trying to solve is related to 3D geometry projection content and 3D Reconstruction needs precise position for the camera, so both eyes needs to see the full scene non-static from same position and same content (Monoscopic), quad layer wouldn't help. |
|
A full screen quad that is viewer locked should work for you. It might even be faster because you would draw the geometry only once. |
|
it's solid point and that is why matterport and realsee.ai and any similar uses this approch on their VR while did not maintain the same implementation of webGL into the XR session... here is an example https://my.matterport.com/show/?m=fCdL9GEmVag (they did use similar forceMono technique i suggest ) noticing the deference between web and vr, that cause they had to abandoned the real time rendering. my approach was keep using |
|
For Matterport, they should really be using an equirectlayer. It's possible to use those with three.js. Both approaches will produce a correct perspective for both eyes. |
|
@cabanier Thanks for the suggestions and discussion. I currently have several projects that rely on this behavior, so I'll move this PR to draft for now and further investigate the layers-based approaches. |
Related issue: #33177
Description
Adds optional
forceMonoscopicflag to WebXRManager for single-viewpoint content. When enabled, both eyes use the left eye's view position, fixing projection misalignment on the right eye for content authored from a single viewpoint.renderer.xr.forceMonoscopic = trueenables monoscopic mode