Solid Particle System with billboard not working in WebXR

Hi, the very cool SPS seems to not work correctly in WebXR when the viewer moves around. The following playground: tested on Oculus Quest shows the problem.

Also, the rotation associated with the billboard for the SPS seems to align the particles with the orientation of the camera. For VR, it would be nice to have the option to have the billboards looking directly at the camera (not using camera orientation at all, but only camera position), otherwise it looks strange to have particle rotating with you head.

The SPS billboard relies on the current camera position.
Maybe there are more than one camera in the WebXR.

1 Like

The mesh.billboardMode works fine in WebXR and seem to be using the right camera. Maybe SPS could use the same camera.

Note: mesh.billboardMode could also benefit from an extra mode of looking at camera position for WebXR (right now it uses camera orientation).

billboard mode is using the camera’s position. The demo you pasted is using WebVR instead of WebXR, which I guess is the reason it doesn’t work as expected (again, i assume).

WebVR used to take a single camera, because the parent camera didn’t have an actual transformation (only the two " eyes" had)… In XR it is different. the camera has a proper position and rotation, so billboard mode should work quite the same as a regular free camera. If it doesn’t, I will be happy to see a reproduction and work on a solution.

Hi, thanks for the answer. The demo is WebVR (based on the online demo) but the code of my Typescript application is WebXR and has the problem. In the end I had to write my own updateParticle function to correctly align my billboards. But the bug is definitely there. If that can help, here is the code that oriented the particles the way I wanted for XR, the use of a TransformNode as a proxy for doing matrix transformations made the job easier:

let TN: TransformNode = new TransformNode('ToolNode', this.vr.scene);
TN.parent = mesh; // mesh is the SPS mesh
SPS.updateParticle = (particle) => {
    TN.position = particle.position;
    TN.lookAt(this.vr.getXrCamPosition(), 0,Math.PI,Math.PI, BABYLON.Space.WORLD);
    particle.rotation = TN.rotation.clone();
    return particle;
// getXrCamPosition() returns