Correct way to implement world scale

What is the correct way to implement world scale in VR? As in scaling things up/down to ensure they match correct size.

As far as I can tell, adding a scale transform to camera in XRRig achieves scale effect, but also causes camera movement mismatch the world movement (the movement ends up being scaled up/down, so the effect can eb quite nauseating).

Scaling XR rig, on other hand, brings camera closer to the floor.

So, what’s the right idea then? Combining XR-Rig with an additional noes that would move it up/down?

It’s kinda been two months. Surely somebody dealt with this before?

Would say Unity units in meters is a good point to start for VR.

That’s not what I asked. Let’s say your make the player shrink. The world now should look bigger.

How about putting the rig closer to the ground then? So the player has to look up at the world around him. And scaling only the player body if it has one.

That’s wrong, you need to affect IPD distance. Putting rig to the ground won’t give a sense of being tiny, it’ll give a sense of crawling on the floor.

How tiny are you talking about. Going from a person to an ant?

It doesn’t matter. You can’t scale the world, if that was the idea.

No, but perhaps scaling the whole world is the better choice in some cases, or at least parts of it? To avoid problems with lack of details, and zooming in on to low res textures.

It’s not. Scaling the whole world will also kill any sort of static baking optimization.

This is and should be a function of the camera in case of VR.

We suggest scaling the rig.
Unless you are deploying to one of the mobile platforms (Google Daydream or Oculus GearVR), you can set the Rig to use the ‘Floor Tracking Origin Mode’ and that puts the 0,0,0 point of the rig on the floor, which makes it easier to match it to the floor in your virtual Unity world/scene. After using a Floor-based rig, and placing the rig on the scene’s floor, it should consistently look correct inside of the headset. In absolute terms, the camera moves closer to the floor, but that’s because you are getting relatively shorter in comparison to the world. Does that make sense?

You have 2 main options in the end though: Scale the Rig or Scale the World.
Scaling the World let’s you keep the player rig simple. This is how Tiltbrush works. The rig is always locked at 0,0,0 and the world moves and scales and rotates around. This adds a lot of complications if you ever plan to use Unity’s Physics system, adds some unusual quirks and bugs to Unity’s AI pathfinding tools, and makes multiplayer with players of different scales a nightmare of multiple spaces depending on player context.
Scaling the Player on the other hand keeps the world acting the same for everyone. It keeps physics and pathfinding (both which assume a 1m=1Unity unit scale) working as expected, and multiplayer has a single ‘master’ space where a player’s local scale and his scale relative to a remote player is consistent. The XR Rig was designed to keep it’s positions local, and support putting that rig in different locations, rotations, and uniform scales.

3 Likes

I played with it a bit more and I believe now I got the gist of how it works.

  1. Camera Y Offset is specified in local space. If I scale XR Rig up, it will go up with it, meaning if I want to make the world look small, BUT keep the camera at the same spot, I’ll need to recalculate it while taking XR Rig scale into account.
  2. Camera Y Offset is COMPLETELY ignored if the tracking mode is set to “floor”. In this case camera position is relative to distance from the floor reported by device, and that’s in local coordinates. Meaning if XR Rig scale is 2, reported distance to floor is 1.3 (player is sitting), then it’ll be moved up to 2.6. And so on.

So, basically… if I want a seated player to control standing character, to implement “Height Offset” I’ll need to parent XR Rig to something, and move it down while keeping tracking mode set to “floor”.

7322560--888808--upload_2021-7-13_10-27-50.jpg

Did I miss anything?

Nope, you are correct.
Regarding (1), the offset is local because our internal use case was ‘Set this to an estimate of how tall the player is when you don’t have floor detection’. E.g. I want to have the player appear standing and don’t have any floor tracking, I’ll estimate a height of 5’10" or 1.77 m and then use ~1.65 as my Y-offset, taking into account the eyes are a little lower than the whole height. This means we really do want it to be in local space, because we are simulating the real player’s height, and not any specific Unity scene offset.
The above use case also meant that we used the Y-Offset as a fallback for when in DeviceTracking mode. Passing this along to our team, but this should all be in the tooltip, and potentially renamed to ‘Default Device Height’ or ‘Y Offset Fallback’.

Thinking of your use-case. Can you place the rig where you’d expect the seated player’s head to be, and then set tracking mode to ‘Device’ and the Y offset to 0? ‘Device’ mode places the origin at the first known location of the headset on startup, and so it let’s you really customize exactly where the user’s head is and where they are looking, at the cost of losing where exactly the floor is. This would also mean that since the rig’s origin is at the same location as the headset on startup, it would be correct at all scales, i.e. scaling 0,0,0 by any number is still gonna be 0,0,0, and then the scale would affect movement after the first frame relative to that curated startup head pose.
Could that work for you?

1 Like

I actually considered this, and while it could be done this way, it would also be less convenient than “Floor” mode with height offset.

I’ll try to explain. I played quite a bit of SkyrimVR with VRIK while seated, and seated player is not exactly locked in place and is capable of moving head around to a significant degree. The degree of possible movement is something in ballpark of +/- 0.3 meters left/right(X), +/- 0.3 meters forward/backward(Z), and ±…0.1 vertically (Y). It is posible to go even further than that, but that’s comfortable range of movement that does not involve rolling around in office chair.

Now, if the player starts in device mode slouched, and device centers around this position, they’ll lose some of their limited movement range, will have to straighten up and recenter, which can get annoying fast. That’s why I think floor with offset is the way to go.

The reason why I’m interested in world scale because majority of the games do not initially get the world scale right and require adjustments, and many of them do not provide a way to adjust the world scale. Basically it is very common to have a situation where something should be, say, 10 centimeters, but is seen as 9 or 8 centimeters instead. That might be because I have larger IPD.