We will explore the art of recentering: how it works and why as developers we should be concerned with it.

A Seemingly Easy Problem

To recenter simply means to reset the reference pose for tracking. In the last chapter, we discussed in detail how this reference pose is generated.

But let’s take a step back and look at this feature from a user’s perspective: when exactly is a recentering action required? Can we function without it?

Typically, a user performs a recentering action whenthey need to adjust their position in the virtual world, but:

  • They can’t physically move to where they want to be—or at least not comfortably.
  • The locomotion system doesn’t provide an easy way to get them there.

Consider this scenario:

A player is immersed in a seated VR experience—say, a sim racing setup with a fixed seat, steering wheel, and shifters mounted to a rigid frame. When their camera spawns in the virtual car, they notice their head is too close to the windshield. Ideally, they’d shift back a few inches for a better view, but they’re physically restrained by the racing seat.

This is where recentering becomes essential.

To correct their position, the player adjusts their posture to a comfortable spot and then performs a recentering action (e.g., by long-pressing the system button on their controller). The VR system updates the reference pose to be this “comfortable pose,” making it the new baseline. Now, as long as the player maintains this posture, their virtual head will remain properly positioned—not too close, not too far—ensuring an optimal view.

At first glance, it seems like there’s little for application-level developers to do beyond ensuring the tracking origin is properly set in the scene (e.g., placing it on the floor directly beneath the seat, facing forward).

I wish that were the case.

Unfortunately, there are situations where we, as developers, must intervene—either by triggering the system recentering function ourselves or by implementing a soft recentering system within the application.

I’m really sorry.

The State Change

In the last chapter, we briefly discussed how the tracking origin represents the “standard” pose of the player at a given moment. What we didn’t discuss is how this “standard” pose can change dynamically during gameplay.

Consider another scenario:

Imagine you’re developing a game where the player starts in an empty room.

There’s nothing in the scene to define a standard pose—the player is free to walk around, and there’s no concept of being “off-center” or “facing the wrong direction.” Unlike the previous example, there’s no inherent “correct” position or rotation for their virtual head.

Now, let’s add an armchair to the scene and allow the player to teleport to and sit on it.

Here’s the problem:

Before the chair existed, there was no “correct” place to stand or sit. But the moment the player teleports onto the chair, that changes. Like the car seat in the previous example, the armchair now introduces:

  • A defined position.
  • A forward direction that should be respected.

Now, let’s say that, before teleporting, the player was physically one meter to the right of their last recentered position. When they snap to the chair, their virtual body will appear floating one meter to the right of the actual chair.

This can be a jarring and confusing moment for the player.

  • Before teleporting, they experienced no noticeable offset because there was no fixed reference.
  • But once they sit down, the misalignment becomes suddenly and painfully obvious.

The issue is that a “standard” pose didn’t exist—until it did.

When the game state changes in a way that introduces a fixed reference, any hidden offset between the player’s actual position and their reference point will abruptly emerge, causing their avatar to appear somewhere they didn’t expect to be.

This is where application-controlled recentering becomes necessary. If the player has to manually trigger the system recenter feature every time they transition to a fixed position—like sitting in a chair or entering a cockpit—it quickly becomes a frustrating experience. Stopping to open a menu and reset tracking breaks immersion and disrupts the flow of gameplay. Worse, new players may not even realize they need to recenter, leading to confusion and a feeling that something is wrong with the game.

The application should handle this process automatically. When the player snaps into a defined position, their virtual body should immediately align with it, eliminating the need for manual recentering.

System Level Recentering

Depending on your target platform, you may be able to directly call the system recenter feature.

You may first give Unity’s XR.XRInputSubsystem.TryRecenter() a try and see if it works as expected for your target runtime. Otherwise, try locating it in the documents of your target platform’s specific SDK.

The great thing about this approach is that it saves you the hassle of adjusting your in-application tracking setup. All you need to do is to make the call to the system recenter feature at the correct point in your application. Plus, you can expect it to work the same way a manual recentering fired by the user does, reducing potential fuck-ups.

It is however worthnoting that such a call to the system feature isn’t always available. There are platforms that don’t support it, or don’t support it through your toolset – for example, they may support it via native SDK but not when you use Unity.

For this reason, and for educational purpose, we are going to implement our own software recentering for the rest of this chatper.

Software Recentering

As application-level developers, if we don’t get to call the system recenter feature, then we don’t get to adjust the hardware’s reference point. But there’s nothing stopping us from adjusting our in-app tracking setup.

Let’s use the armchair example again. Assuming that the player is physically 1 meter to the right of the reference point and they teleport to the virtual chair; they appear at 1 meter to the right of the virtual chair instead of sitting right in it.

Now, assume that we cannot reset the hardware reference point. That is, the reported tracking value is going to have a 1-meter offset to the right and we just have to accept that. And what we can do is we cancel its effect when applying the values to our virtual tracking targets.

Let’s formalize it.

  • Assume that the tracking origin is at pose A.
  • Assume that the HMD’s local pose is pose B.
  • Now, since we want to pretend that the HMD is at a recentered position, pose B needs to be adjusted. Remember that being recentered means that the HMD is right above the tracking origin, has its “forward” direction aligned with the tracking origin’s forward (but not affecting the up/down tilt).

Leave a Reply

Your email address will not be published. Required fields are marked *