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:
-
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.
-
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).