Skip to main content
New Participant
December 6, 2023

How can I get a depth map(or point cloud) just from my quest 3's depth sensor???

  • December 6, 2023
  • 36 replies
  • 18779 views

I know there is a depth sensor on the quest 3 and I want to use its depth data for further image research, but my MQDH only supports recording video from the binocular camera. 😞 I've checked the documentation for the Depth API, and it seems that the depth information has been encapsulated many times, and I wonder if there is a way to get the depth map or point cloud image directly, thank you very much!!🙏

36 replies

JeffNik
Honored Contributor
December 12, 2023

If you don't need a real-time point cloud, and you just want a point cloud from the scan that your Quest 3 did when it did it's room scan, you can use the OVRSceneManager component to return a GlobalMesh prefab that contains a triangle mesh of your space. You can copy the vertices array and just remove the duplicate vertices. If that sounds like what you need, and your need more info on OVRSceneManager and retrieving scene data, let me know and I can go into more detail
- or -
this link may give you what you need to get started: 
Scene Mesh | Oculus Developers

 

Participant
November 16, 2024

JeffNik Do you mean the point cloud of the surrounding environment or is it the point cloud of only the room objects defined by user while doing the space setup?

Sihat Afnan
JeffNik
Honored Contributor
November 16, 2024

Currently, there is no way to get a "live" point cloud - only the point cloud from the data that was generated at space setup time. I would LOVE to have real-time point cloud data - but I can see problems in that the headset can only "see" a small portion of your environment at any one time.

Swancopter
New Participant
February 5, 2024

Is there any way to get access to the depth stream (On quest 2/3/pro) ? I am trying to align the headset pose with the pose of a robot (in ROS) to create a digital twin overlaid in mixed reality. One way would be to match the point clouds. Alternatively if the headset is able to detect an April Tag or track a moving object that would work too.

Participant
February 16, 2024

If you happen to find a way, please let us know - others would love to use this, too! 🙂

New Participant
February 19, 2024

You can access it in the shaders provided with the recently released DepthAPI. If you look at line 28 in the EnvironmentOcclusion.cginc file the environmentDepth variable that is calculated is the raycast depth value picked up by the sensor.

Anyhow it's there, so you can write a compute shader that either directly uses the data, or exposes it to a script.

It's going to take some effort, but it's there.

Swancopter
New Participant
February 27, 2024

Just what I was looking for. A good starting point. Hopefully serializing the data and sending over tcp at 1Hz won't load the headset too much.

New Participant
May 20, 2024

Hello, by any chance... have you managed to recreate a shader or something that does fetch a depth map sample ? 
I'm trying to use the depth API to occlude specifically UIs but it doesn't really work well with images, texts and other stuffs... 

Participant
June 5, 2024

Hello,

I'm not sure it is what you're expecting to atteign, but I managed to get image and UI occlusion just by activation the Oculus embedded occlusion feature from the Unreal OcclusionSample.
You need, however, to activate scene feature support in the MetaXR plugin settings.

npt67id
New Participant
June 5, 2024

Tín nổi bật 

Npt67
florianbuchholz1988
Inspiring
November 19, 2024

Interesting way of doing it.

I am currently looking into the information of the point cloud data, simply because the placement of the shared anchors sometimes doesnt work and I'd love to know why, hence visualizing / testing the quality of the point cloud.

Do you know JeffNik if the Pointcloud data also stores 2d-color information and shares this? Not for us to access (patiently waiting for next years camera access), but for the fact, that 2d images / logos on a table could help optimizing the point cloud data that is being shared for the shared anchors.

JeffNik
Honored Contributor
November 19, 2024

In my testing, I looked for any color-related information provided in the returned mesh, and found none.

florianbuchholz1988
Inspiring
November 19, 2024

Now the question would be, is it not there when the point cloud is being created or is Meta just not sharing that information with the developers (yet)? We'll see what comes in the next year.

JeffNik
Honored Contributor
November 19, 2024

room.png

Update - I just played around with the MRUK. Following the Meta documentation, I found that this new method can be used to get the same room data. When you include the MRUK prefab and EffectMesh prefab in your scene, and do a few other setup items, it creates the same runtime object, representing the geometry it has found or you have added, including the GLOBAL_MESH object containing the scanned geometry to use for a basic point cloud. It looks like this will be the way I do it going forward.

Participant
November 20, 2024

JeffNik , one more question. The room data you get using MRUK and EffectMesh Prefab, is static data right? I mean it shouldn't change based on headset's position or direction. And technically it makes sense because you are accessing room-scan data, not the real time Mesh of the room.

And if possible, can you mention the procedures you used to get the GLOBAL_MESH using MRUK and EffectMesh?

Thanks in Advance

Sihat Afnan
JeffNik
Honored Contributor
November 24, 2024

Sorry - having trouble replicating my results - I'll respond after I figure out what I'm doing differently.

 

Participant
November 29, 2024

Hello,
im pretty new to working with OVR, the Quest 3 and the Depth API but I'm currently trying to generate a live point cloud using Unity's VFX Graph. I want to reconstruct points from the live depth information.
Up until now I know that the Depth API provides the depthMaps, something called the environmentDepthZBufferParams, which hold a depthOffset and invDepthFactor, and the reprojectionMatrices. But I don't really know what a 'reprojection' matrix is, I only know of projection matrices. 
I believe a live point cloud should be possible, since the raw camera data is used to construct the available data. But I wasn't yet able to use this data to reconstruct a live point cloud yet. 
I don't know if this information is helpful in any way but maybe someone has an idea how to use it.

JeffNik
Honored Contributor
November 30, 2024

I haven't yet. I think I started to check it out and it came down to having to write shaders, and I wasn't ready to tackle that yet. 😉

 

Participant
December 29, 2024

Ok, so I figured some things out. 

First of all, it seams that the depth API doesn't actually use the depth sensor but rather computes the provided depth from the two main cameras. I don't think that actually makes any difference but it's interesting to know.
Second, I did it! I was able to understand what the accessible data is and how to create points from that data.

If you want me to I can go into detail as to what the provided data is used for, but for now I will just share how I managed to create a live point cloud from the depth API data.
So the 3D-reconstruction itself is very easy and does not require any special things. You can create a point from the raw data and just need to transform it a little, then multiply it with the inverse of one of the provided reprojectionMatricies and do a final transformation to receive a WorldSpace point.

First of all the data in the depth texture is in a [0,1] space in the R-Channel. From that depth you can construct a 3D point using the UV coords from sampling the texture as the X and Y component getting you a Vector3(U,V,Depth). This point is in ScreenSpace [0,1] and needs to be transformed into ClipSpace [-1,1]. You can do this by multiplying it by two and subtracting one. To get the ClipSpace point into WorldSpace you use the inverse of the reprojectionMatrix. That is basicly the projectionViewMatrix so the inverse transforms points from ClipsSpace into WorldSpace. To be able to correctly transform points though, they need to be homogeneous. That can be acchieved by adding a one to the point making it a Vector4(X,Y,Z,1). Then multiply this point with the matrix. That gets you a homogeneous position as a Vector4 in WorldSpace. At last you create a Vector3 from the X,Y and Z and divide it by the W component. 
And that is it, you now have a Vector3 point in WorldSpace from a sampled pixel of the depth texture.

TLDR: you need to make a point from U,V and Depth, transform it into ClipsSpace, make it homogeneous, transform it into homogeneous WorldSpace using the inverse reprojectionMatrix and apply the perspective divide to the result.

It's important to note that for this pipeline to work the code can't be executed in a normal rendering shader but needs to be executed in like a script, compute shader or similar. For sampling the WorldSpace position inside a normal shader, you also need to transform the U,V and Depth data from the shaders perspective into the perspective the depth is encoded with.

New Participant
January 13, 2025

Was the maximum texture size that you were able to get 512 x 512? I noticed that when I used readPixels on the shader it returned a texture that was 2000 x 2000, but I was only able to get a 512 x 512 version when using a compute shader.