Forum Discussion
NEMO_54174
3 years agoExplorer
How can I get a depth map(or point cloud) just from my quest 3's depth sensor???
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
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 DevelopersCurrently, 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.
- SwancopterExplorer
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.
- RelykaaExplorer
If you happen to find a way, please let us know - others would love to use this, too! 🙂
- gecko06Honored Guest
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.
- SwancopterExplorer
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.
- MeriemKalankHonored Guest
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...
- NickauhlaExplorer
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.- npt67.idHonored Guest
Tín nổi bật
- florian.buchholz.1988Expert Protege
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.In my testing, I looked for any color-related information provided in the returned mesh, and found none.
- florian.buchholz.1988Expert Protege
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.
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.
- Ishhin24Explorer
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
Sorry - having trouble replicating my results - I'll respond after I figure out what I'm doing differently.
- FunGamePlayerExplorer
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. 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. 😉
- FunGamePlayerExplorer
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.- AethoenHonored Guest
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.
- looouiszHonored Guest
Hi! Thank you so much for sharing the info. Would you like to share/open-source the code? appreciate it ahead!
- FunGamePlayerExplorer
Hello, unfortunately I can't share/open-source the code but I can provide a screenshot of the VFX Graph that converts the Depth API data to particle positions. With that it shouldn't be difficult to create your own project with a similar structure.
For setting up the Depth API itself I suggest checking out the sample project. To get the data you have to have the EnvironmentDepthManager in your scene. To move the data to the VFX Graph you just create a property binder that takes the depth texture and reprojection matrix array from the global shader variables. Give the texture and the inverse of the first of the reprojection matrices (reprojectionMatrix[0].inverse) to the VFX Graph. And finally inside the VFX Graph use the calculated vector3 to set the particles position inside the initialize context.Create SS Point, SS to CS, CS to HCS
HCS to HWS, HWS to WS
Quick Links
- Horizon Developer Support
- Quest User Forums
- Troubleshooting Forum for problems with a game or app
- Quest Support for problems with your device
Other Meta Support
Related Content
- 5 years ago