readRenderTargetPixels() huge latency on mobile

There is a main camera and a depth camera.
readRenderTargetPixels introduces a huge latency, and drops the frame rate considerably on mobile (android), rendering it completely unwatchable in WebXR mode where I’m interested, even with the lightest scene.

I have provided a functional demo that measures depth, and shows a ray and a point against a rotating cube, that can run both in normal and WebXR mode, and provides min and max millisecond stats on screen, in both modes for the last 10 frames, and I have also provided even QR codes for your convenience, with and without that function, on stackoverflow (no need to enter WebXR on mobile to see the huge latency).

The goal is to “cure” that huge latency, and have an efficient depth measurement from the depth camera, or via other method. I haven’t tried the raycasting method yet, but I remember it was considered heavier.
I’m sure that many people are interested to find the most efficient method for something like that.
As it is, that latency renders it useless for me on mobile, expecially on VR.
If any guru can help, it will be greatly appreciated. Thanks.

chrome-1

chrome-2-VR

The problem is that WebGLRenderer.readRenderTargetPixels() internally uses gl.readPixels() which is a synchronous operation. It tends to be slow especially on mobile devices.

If you want to implement any form of interaction, traditional raycasting is much faster.

Sidenote: It seems PBOs (Pixel Buffer Objects) could be a more efficient (asynchronous) alternative to gl.readPixels() however I have no experience with them. However, there are supported with WebGL 2.

3 Likes

traditional raycasting is much faster.

Thanks, I hope so, it’s the next thing I’m going to try. Of course to be fast it probably requires to break down the scene in smaller parts, then use raycaster only on those that are close to the ray, right?
One question: can three.js raycaster be used to locate the exact point of ray-intersection on a mesh, or do I have to implement that myself?

Sidenote: It seems PBOs (Pixel Buffer Objects) could be a more efficient (asynchronous) alternative to gl.readPixels() however I have no experience with them. However, there are supported with WebGL 2.

My goal is around 3ms of ray-intersection cost on mobile, if I’ll get this using raycasting -three.js or custom, I’ll stop there, else, I’ll have to dig to unknown territories like the one you mentioned…

Thanks for all the pointers Mugen87!

If your scene does not consist of a single large mesh, this is not necessary. Raycasting in three.js first checks bounding volumes before doing the more expensive ray/triangle interesction tests.

The result of the raycasting contains the exact intersection point on the mesh’s surface. It is the point property of the intersection object.

1 Like

Thanks Mugen87!