Forum Discussion

🚨 This forum is archived and read-only. To submit a forum post, please visit our new Developer Forum. 🚨
owenwp's avatar
owenwp
Expert Protege
13 years ago

Incorrect IPD math (maybe)

I have been feeling that the world scale has been weird since the first release despite using correct numbers. I have also seen comments concerning IPD adjustment seeming to not have much effect. After digging through the code I have finally figured out why.

The IPD math is off. The ingame cameras are being spaced (your IPD)+64mm apart, which for the average person makes the world appear exactly half its expected size. This stuff is kind of off the beaten path of CG, so I will try to be thorough if a bit long-winded. Please bear with me.

The reason is that an IPD offset is being applied on top of the lens offset. When the projection matrix is constructed it is transformed 32mm in either direction in post-perspective-transform screen space so that it lines up with the center of the each lens. For a 1:1 scale world that results in a 32mm transform in world space as well. You can make sense of this by thinking of sliding the eye position along the near plane of the camera.

But, after this is done, the camera transform position is also shifted IPD/2mm in either direction. For the above person, this would put the centers of the ingame cameras a total of 128mm apart.

Try substituting the OVRCameraController.ConfigureCamera method with the code below, which instead offsets the eye positions by the difference between IPD and inter-lens distance:


void UpdateCameras()
{
// Values that influence the stereo camera orientation up and above the tracker
if(FollowOrientation != null)
OrientationOffset = FollowOrientation.rotation;

if(UpdateCamerasDirtyFlag == false)
return;

float ipdDifference = IPD - 0.064f; // I assume the lenses are exactly 64mm center to center

float distOffset = 0.5f + (LensOffsetLeft * 0.5f);
float perspOffset = LensOffsetLeft;
float eyePositionOffset = -ipdDifference * 0.5f;
ConfigureCamera(ref CameraLeft, distOffset, perspOffset, eyePositionOffset);

distOffset = 0.5f + (LensOffsetRight * 0.5f);
perspOffset = LensOffsetRight;
eyePositionOffset = ipdDifference * 0.5f;
ConfigureCamera(ref CameraRight, distOffset, perspOffset, eyePositionOffset);

UpdateCamerasDirtyFlag = false;
}


If you load up Tuscany, set your IPD and height correctly (it defaults to you being super tall) and play standing, you should see a night and day difference from before. Everything seems exactly as big and as distant as it should be. The high vaulted ceiling looks as impressive as it should be for being over two stories high. Go back to the unmodified Tuscany and it feels like a dollhouse.

If you don't trust my explanation, try to simply set eyePositionOffset to zero. Far from getting zero stereo separation as you might intuitively expect, it should look very close to correct if you have average IPD.

I haven't looked at the C++ samples yet, and I don't think the Unreal code is accessible, but I suspect they have the same problem. The Unreal demos I tried also made the world seem tiny, though thats made worse by the intentionally out of proportion design of most unreal samples.

15 Replies

Replies have been turned off for this discussion