mrdoob / three.js

JavaScript 3D Library.
https://threejs.org/
MIT License
101.98k stars 35.33k forks source link

WebVRManager needs equivalent to VRControls.userHeight #11619

Closed brianchirls closed 6 years ago

brianchirls commented 7 years ago

VRControls has a userHeight property that places the camera a given height (usually) above the origin in "standing" mode when the VRDisplay doesn't provide a standing matrix.

WebVRManager doesn't appear to have an equivalent adjustment, so headsets that do not have roomscale (i.e. anything other than Vive) place the head at or near the floor. Since WebVRManager.getCamera() sets the position of the camera inside of WebGLRenderer.render() it's difficult if not impossible to make that adjustment another way.

mrdoob commented 7 years ago

I need to have a look at the new WebVR API... However, you should be able to achieve this by parenting the camera with an object that position.y = userHeight, no?

brianchirls commented 7 years ago

I've looked into this a little further, and there's an additional challenge right now, which is that the standingMatrix is only applied when rendering stereo to the VR display. So that makes it tricky and confusing if you want to render the HMD's view to the screen.

So let's say the camera's parent is at (0, 0, 0) and the user's head is at 1.6m. You do a VR stereo render pass, and WebVRManager applies the standing matrix (i.e. moves 1.6m up) putting the view in the right place. Then you draw to the screen, but the standing matrix is no longer applied, so the view is rendered from the floor.

Sure, it's possible to write a workaround by transforming the camera for the render pass and then transforming it back. But that's extremely difficult to reason about, easy to get wrong and probably not very efficient.

arturitu commented 7 years ago

In my case I try to change the camera position around the scene (for teleport it purposes, for example) but always is rendered on 0,0,0, and you need to add the camera as a child of an object3D in the scene with your desired height to works as expected. But in this case, if you are using https://github.com/borismus/ray-input doesn't work correctly on Daydream/GearVR (and I supposed on Vive/Rift neither) because is imposible to say to the navigator.getGamepads pose that isn't on a different position than 0,0,0.

I'm trying to say with this, that if is related, maybe we need to find a more complex solution in which we could move the camera wherever we want it, not only to solve the userHeight problem.

brianchirls commented 7 years ago

I've done some more testing and research, and I think I have a handle on this issue.

WebVRManager is currently setting the camera pose at the last possible moment, presumably to minimize latency. But there are a few reasons why we might need the pose set earlier. As I mentioned above, there's the need to render another view. We also need to know where the head is for ray casting in case of gaze interactions, detecting visibility of objects, etc.

For the sake of correctness and simplicity, I propose an added option that allows rendering with ArrayCamera but disables setting the pose so it can be set with VRControls as the developer sees fit.

mrdoob commented 6 years ago

For the time being, this is how you can work around it: https://github.com/mrdoob/three.js/commit/e3cbd3052b20a9235f343446cc23b0211782d3d4#diff-eb152a516883cb17690e595058479f49

mrdoob commented 6 years ago

But now that I think about it, maybe I broke it because the controllers should also be a child of that object? I'll check it later...

mrdoob commented 6 years ago

Okay. Fixed, I think... https://github.com/mrdoob/three.js/commit/3cb51d868ee279be373815de592fc072deffc82c

MortimerGoro commented 6 years ago

@mrdoob Is that the correct solution? Why use a fixed height in vive examples when you could use standingTransform to get the best accuracy?

fernandojsg commented 6 years ago

I also believe we should the standingMatrix to fix this issue. If the device doesn't have a stageParameters we could just set the height as described, but if it has, we should use it. Otherwise we're forcing the same height for everyone, in my case for example I feel the floor is 20cms or so above my feet.

Mugen87 commented 6 years ago

With R90, standingMatrix is available again.