Skip to content

WebXRManager: Add Raw Camera Access module. #31487

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

Merged
merged 13 commits into from
Jul 30, 2025

Conversation

mikeskydev
Copy link
Contributor

@mikeskydev mikeskydev commented Jul 23, 2025

Closes #26452, Closes #26891

Description

This PR implements support for the WebXR Raw Camera Access module, and provides an example where the camera texture is placed on a rotating cube.

I have addressed the issue in #26452 by unbinding texture state if camera access is enabled, as it appears the module will automatically bind the raw camera textures at the beginning of the frame, which was affecting three.js's internal state tracking.

As this was tested on Chrome for android, this may be an implementation bug in Blink that has gone unnoticed, as their test case always rebinds textures.

shared image

Copy link

github-actions bot commented Jul 23, 2025

📦 Bundle size

Full ESM build, minified and gzipped.

Before After Diff
WebGL 338.39
78.91
338.82
79.08
+428 B
+163 B
WebGPU 566.16
156.5
566.16
156.5
+0 B
+0 B
WebGPU Nodes 564.77
156.26
564.77
156.26
+0 B
+0 B

🌳 Bundle size after tree-shaking

Minimal build including a renderer, camera, empty scene, and dependencies.

Before After Diff
WebGL 469.82
113.62
470.25
113.78
+428 B
+155 B
WebGPU 637.38
172.47
637.38
172.47
+0 B
+0 B
WebGPU Nodes 592.02
161.71
592.02
161.71
+0 B
+0 B

@mikeskydev
Copy link
Contributor Author

Any chance this makes r179? My actual use case is further downstream... :)

@Mugen87
Copy link
Collaborator

Mugen87 commented Jul 30, 2025

I've removed the opaque property from RawTexture because the renderer does not evaluate the flag anymore. Also committed some JSDoc improvements.

Do you mind temporarily updating the builds so I can test the PR with a Quest 2 over https://rawcdn.githack.com/?

@mikeskydev
Copy link
Contributor Author

Thanks! I have a built version for my own purposes on https://github.com/mikeskydev/three.js/tree/cam-access-build , but be aware camera-access isn't available on Quest yet. I've been working for mobile, and it should be supported on a default Android Chrome with no extra flags

@Mugen87
Copy link
Collaborator

Mugen87 commented Jul 30, 2025

Thanks for the heads-up. I can still test if the depth sensing demos work so we have no regression on that side.

https://rawcdn.githack.com/mikeskydev/three.js/98bc573b5d9ea8280116d100497ecadf08260139/examples/index.html

@Mugen87
Copy link
Collaborator

Mugen87 commented Jul 30, 2025

There seems to be no change in behavior 👍 .

However, it seems like depth sensing is currently broken in production. When I understand webxr_xr_dragging_custom_depth correctly, the meshes should be occluded by objects in the real world (see https://x.com/rcabanier/status/1748050448270135425). However, I don't get objects occluded at least on my Quest 2. They are always rendered in front of everything.

There are no WebGL/WebXR warnings in the browser console when using remote debugging.

/ping @cabanier I'm afraid a regression has sneaked in. Could you please have a look?

@mikeskydev
Copy link
Contributor Author

I tried the depth example on my phone (which doesn't support depth) and it seems to silently fail as it's an optional feature, so it may also be depth sensing was turned off for quest browser at some point?

@Mugen87
Copy link
Collaborator

Mugen87 commented Jul 30, 2025

Oh wait, it seems depth sensing only works with a Quest 3 since the Quest 2 does not have the required depth sensor.

@cabanier Sorry for the ping 😇 .

@cabanier
Copy link
Contributor

Oh wait, it seems depth sensing only works with a Quest 3 since the Quest 2 does not have the required depth sensor.

Depth sensing is no longer working with these changes. I'll investigate why.

@cabanier
Copy link
Contributor

Oh wait, it seems depth sensing only works with a Quest 3 since the Quest 2 does not have the required depth sensor.

Depth sensing is no longer working with these changes. I'll investigate why.

If I revert 6692d4d (Flip bool), depth sensing works again

@Mugen87
Copy link
Collaborator

Mugen87 commented Jul 30, 2025

The texture retrieved via getDepthInformation() just needs to be bound for usage, right? There is no need for an explicit texture data upload.

We've introduced RawTexture to have a dedicated code path for this use case and avoid code sections like:

const texProps = renderer.properties.get( texture );
texProps.__webglTexture = depthData.texture;

If the depth sensing texture is wrapped into a RawTexture instance, the outcome should be the same. Especially since nowhere in WebXRDepthSensing texture.needsUpdate is set to true. I wonder what me miss 🤔 .

@mikeskydev
Copy link
Contributor Author

Technically opaque textures should be bound every frame as they go invalid, In camera access it doesn't work unless I rebind in the loop.

Any chance that depth was also working by a fluke and is also affected by the unbind?

@cabanier
Copy link
Contributor

Technically opaque textures should be bound every frame as they go invalid, In camera access it doesn't work unless I rebind in the loop.

Any chance that depth was also working by a fluke and is also affected by the unbind?

Yes, you need to rebind the textures every frame. This is because we play tricks under the hood and replace the underlying system texture.

@Mugen87 Mugen87 merged commit 95febf4 into mrdoob:dev Jul 30, 2025
9 checks passed
@Mugen87 Mugen87 added this to the r179 milestone Jul 30, 2025
@Mugen87
Copy link
Collaborator

Mugen87 commented Jul 30, 2025

@mikeskydev Thanks for working on camera access and implementing the RawTexture solution. It's great to see that also the depth sensing code path benefits from the new texture type.

@mikeskydev mikeskydev deleted the feat/webxr-camera-access branch July 30, 2025 20:46
@mikeskydev
Copy link
Contributor Author

Agreed, thanks for pushing for the cleaner solution, helping get the PR over the line and for your time, it's really appreciated!

*
* @augments Texture
*/
class RawTexture extends Texture {
Copy link
Owner

@mrdoob mrdoob Jul 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe ExternalTexture could be a better name?
Are there other uses for it? If not, may be WebXRCameraTexture?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also use it for webxr depth textures, but there was some debate about naming in the linked issues and RawTexture was settled on. I could see it being useful for anything that uses raw texture handles, possibly protected content?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Provide Access to WebXR camera feed when camera-access feature is enabled. Loading VideoTexture in WebXR gives camera feed instead of actual video
4 participants