PiTool IPD offset - how does it work

After reading some recent posts and realizing there has not been a proper coverage for the PiTool IPD offset feature, I decided to give it more thorough examination.

Before diving in, let’s point out that this adjustment is immediate, i.e. you do not need to restart SteamVR.

Now, when you set an IPD offset in the PiTool, the offset is added to the original value and two things are affected:

  1. The view geometry is adjusted to the new IPD. Let’s call the IPD you rolled manually on the headset without any IPD offset the baseline IPD.

  2. Image position on the panel is shifted accordingly to correspond to the new view geometry.

An example: My baseline IPD was set ~ 70 mm. This is how eye to head matrices for this configuration (in native mode) look like:

Left eye to head transformation matrix:
    {{ 0.984808,  0.      ,  0.173648, -0.035018},
     { 0.      ,  1.      ,  0.      ,  0.      },
     {-0.173648,  0.      ,  0.984808,  0.      }}

Right eye to head transformation matrix:
    {{ 0.984808, -0.      , -0.173648,  0.035018},
     { 0.      ,  1.      , -0.      ,  0.      },
     { 0.173648,  0.      ,  0.984808,  0.      }}

View geometry:
    left panel rotation:   -10.0 deg
    right panel rotation:   10.0 deg
    reported IPD:           70.0 mm

The IPD is determined by the last column which defines the eye coordinates in the head based system. Left eye is shifted 35 mm to the left (-X axis), right eye 35 mm to the right (+X axis) so the IPD is 70 mm.

Now changing the IPD offset to +10 changes the geometry to:

Left eye to head transformation matrix:
    {{ 0.984808,  0.      ,  0.173648, -0.03987 },
     { 0.      ,  1.      ,  0.      ,  0.      },
     {-0.173648,  0.      ,  0.984808,  0.      }}

Right eye to head transformation matrix:
    {{ 0.984808, -0.      , -0.173648,  0.03987 },
     { 0.      ,  1.      , -0.      ,  0.      },
     { 0.173648,  0.      ,  0.984808,  0.      }}

View geometry:
    left panel rotation:   -10.0 deg
    right panel rotation:   10.0 deg
    reported IPD:           79.7 mm

Analogically, setting the IPD offset to -10.

Left eye to head transformation matrix:
    {{ 0.984808,  0.      ,  0.173648, -0.030167},
     { 0.      ,  1.      ,  0.      ,  0.      },
     {-0.173648,  0.      ,  0.984808,  0.      }}

Right eye to head transformation matrix:
    {{ 0.984808, -0.      , -0.173648,  0.030167},
     { 0.      ,  1.      , -0.      ,  0.      },
     { 0.173648,  0.      ,  0.984808,  0.      }}

View geometry:
    left panel rotation:   -10.0 deg
    right panel rotation:   10.0 deg
    reported IPD:           60.3 mm

Why the offset (i.e. plus or minus 10) does not applies exactly I have no idea, but this is how it is.

Now what happens with the image.

First because of the shifted view, the rendered image changes slightly (as if you were looking at it with eyes which are either closer, or farther to each other. Below are rendered images by SteamVR Home app (grabbed from SteamVR “both eyes” mirroring).

IPD 70 mm, offset = 0

IPD 70 mm, offset = +10

IPD 70 mm, offset = -10

You would probably need to open the images separately and toggle between them to notice the small difference in the view geometry.

But this is not all. The images are also shifted on the panels accordingly to the offset. Below are the left eye captures after pre-lens warp. You may notice that the image res now corresponds to the panel res (the images above I grabbed as a screenshots, so their resolution was solely determined by the size of my monitor).

Also note that the warped captures are from the different scene than the images above. It is just because I moved my headset between the sessions, as it really does not matter for the purpose of this exercise.

Left warped image, IPD offset = 0

Left warped image, IPD offset = -10

Left warped image, IPD offset = +10

You can notice how the image is shifted on the panel based on the set IPD offset. The right eye images behave the same way (they are just shifted to the right).

You can also notice that +10 warped image looks deformed and no longer has the same shape of the HAM. I think this might be related to the fact that this particular settings puts the IPD to ~80 mm and the warping functions simply no longer work correctly.

Conclusion

When you change the IPD offset in PiTool you are basically setting a new IPD exactly as if you rolled it in manually, except that the lenses do not move. In other words, you can use it to move lenses, and then “offsetting” it back so that the view geometry and the image positions on the panels match your real IPD.

On the other hand, since the view geometry and the image position on the panel are linked, you cannot fix the case, if there is a discrepancy between the two, i.e. when the image position is incorrectly calibrated for the given IPD (and the view geometry).

13 Likes

I just don’t understand what the use case is?

If you mean the use case for an IPD offset, the only one I can think of is that you detach the lenses movement from an IPD adjustement. In other words, you can keep the pre-set IPD, while moving the lenses freely (and compensating for the move by the IPD offset).

I believe it was supposed to help people who complained that the lenses should be closer than they were, but putting them closer led to messed up view geometry, because it also set a wrong IPD for those people.

5 Likes

It could be in my imagination but when I physically set the lens to the best/sharpest image ( ipd 65.5)for my eyes individually and then used software adjustment to dial in my actual ipd ( 67.5) , everything looked better than having the offset at 0 and the lens 67.5 on the physical dial

4 Likes

It could as well be a real deal :slight_smile:. When you put the lenses closer, you are getting their optical centers closer to your eyes axes (when looking ahead). So it should improve the clarity of the image in front of you at the cost of introducing more distortion at the peripheral.

6 Likes

Yeah that’s exactly my experience. If i press the upper part of the hmd firmly against my head so that my eye lashes touch the panels, I experience a ‘solid’ (not wobbly) vr world in the center. But I see then a lot distortion at the edges. But for me it is the only way to solidify the vr world with my 5k

1 Like

Well, good for you :wink: but I was talking about putting the lenses close to each other.

Though I am not saying that your experience is not authentic, but most likely related to some other “side-effect” of the Pimax optics. My guess would be you might be sensitive to the sweet spot in forward-backward direction or may have eyes “too deep” compared to the original Pimax head model after which they calibrated the eye depth.

2 Likes

Ah I misunderstood what you said. I don’t know what the problem is with the 5k lenses but they are just not very good. But everybody (valve, xtals vrengineers, Palmer) says its very complicated to make wide fov lenses without distortion so I don’t think pimax will succeed here, it takes much more than simply slamming some high res panels in a hmd

2 Likes

Is this the correct thing to do in this case? I thought that the purpose of moving the image on the panel was to keep the rendered area centered in the lenses as they moved when using the IPD dial.

When changing the offset in Pitool the lenses are not moving so it seems odd to shift the rendered area on the panel. I would have assumed that it would just adjust the view matrices. It seems this would cause the rendered area to become off center in the lenses.

A good point, but a wrong assumption :wink: If we assume that they do not change the warp function (when shifting the image) then you made a good point. The image was rendered under assumption that the lens center is at specific position, and now the image moved and the lens did not, so the image no longer corresponds to the lens position and the final image gets distorted instead of “undistorted”.

I cannot however verify that as I do not know how to confirm the same warp has been used on two different images, especially when one seems to be malformed already. Knowing Pimax though, I would bet they do not correct the warp for the shifted image.

On the other hand, shifting the image with the offset makes sense too. This way they at least can preserve the angular verity of the virtual 3D space, since the views rendered are observed at the correct IPD. You can imagine that by changing the offset, you change the distance between the two cameras “shooting” the 3D virtual space, and at the same time you change the distance between the images from those two cameras as well. So the positions of the objects remain coherent between the 3D space and 2D images. If you do not do that the 2D images will not align anymore (to give the correct 3D perception).

So there are actually two completely different aspects, and each needs to be addressed separately in order to do it “right”.

3 Likes

Not going to attempt any math, but it wouldn’t simply be a matter of cos(10), would it?

:smiley: funny. But considering that the offset +/- 10 kind of “transforms” into +/- 9.7 and cos(10°) = 0.985, which seems enough different to consider it a rounding error, I guess not (acos(0.97) =~ 14°). But more importantly, I have no idea, where would they apply this cos(10°).

The IPD is adjusted in a plane parallel to the face (and not in the panel/view plane) so technically in the head coordinates. Which means the full offset should be added/subtracted from the corresponding “eye coordinate” which is what the last column of the eye2head transform matrix is (the eye coordinates in the eye coordinate system is [0,0,0])

Well, it was worth a try. :7

There should be an eye relief variable somewhere in there, too, I believe; I seem to recall that from when there was plain ASCII settings embedded in the piserver binary, but dunno how they would apply that. :7

Eye relief could be important for the warp function, eventually viewing frustum definition, but for what concerns an IPD the rules are pretty simple. When you adjust an IPD you adjust an IPD, and when you add 1 cm to it, it should be 1 cm longer :slight_smile:.

Ah, your transformation matrices are for the view point, of course – well, got to throw some sort of chum into the water. :stuck_out_tongue: